pike.git / src / las.c

version» Context lines:

pike.git/src/las.c:1:   /*\   ||| This file a part of Pike, and is copyright by Fredrik Hubinette   ||| Pike is distributed as GPL (General Public License)   ||| See the files COPYING and DISCLAIMER for more information.   \*/   /**/   #include "global.h" - RCSID("$Id: las.c,v 1.118 1999/11/20 03:41:15 grubba Exp $"); + RCSID("$Id: las.c,v 1.119 1999/11/20 19:09:47 grubba Exp $");      #include "language.h"   #include "interpret.h"   #include "las.h"   #include "array.h"   #include "object.h"   #include "stralloc.h"   #include "dynamic_buffer.h"   #include "lex.h"   #include "pike_types.h"
pike.git/src/las.c:471:      #define mkemptynode() dmalloc_touch(node *, debug_mkemptynode())      node *debug_mknode(short token, node *a, node *b)   {    node *res;      #if defined(PIKE_DEBUG) && !defined(SHARED_NODES)    if(b && a==b)    fatal("mknode: a and be are the same!\n"); +  if (token == F_CAST) +  fatal("Attempt to create a cast-node with mknode()!\n");   #endif       check_tree(a,0);    check_tree(b,0);       res = mkemptynode();    _CAR(res) = dmalloc_touch(node *, a);    _CDR(res) = dmalloc_touch(node *, b);    res->node_info = 0;    res->tree_info = 0;
pike.git/src/las.c:605:    case F_DEC:    case F_POST_INC:    case F_POST_DEC:    res->node_info |= OPT_ASSIGNMENT;    if (a) {    res->tree_info |= a->tree_info;    }    break;       default: -  /* We try to optimize most things, but argument lists are hard... */ -  if(token != F_ARG_LIST && (a || b)) -  res->node_info |= OPT_TRY_OPTIMIZE; -  +     if(a) res->tree_info |= a->tree_info;    if(b) res->tree_info |= b->tree_info;    }    -  +  /* We try to optimize most things, but argument lists are hard... */ +  if(token != F_ARG_LIST && (a || b)) +  res->node_info |= OPT_TRY_OPTIMIZE; +     res->tree_info |= res->node_info;      #ifdef PIKE_DEBUG    if(d_flag > 3)    verify_shared_strings_tables();   #endif       if(!num_parse_error && compiler_pass==2)    {    check_tree(res,0);
pike.git/src/las.c:861:       return freeze_node(res);   }      node *debug_mkcastnode(struct pike_string *type,node *n)   {    node *res;       if(!n) return 0;    +  if (!type) { +  fatal("Casting to no type!\n"); +  } +     if (type == void_type_string) return mknode(F_POP_VALUE, n, 0);       if(type==n->type) return n;       res = mkemptynode();    res->token = F_CAST;    copy_shared_string(res->type,type);       if(match_types(object_type_string, type) ||    match_types(object_type_string, type))
pike.git/src/las.c:1957:    }else{    push_type(T_MIXED);    }    }   }         void fix_type_field(node *n)   {    struct pike_string *type_a,*type_b; +  struct pike_string *old_type;    -  if(n->type) return; /* assume it is correct */ +  if (n->type && !(n->node_info & OPT_TYPE_NOT_FIXED)) +  return; /* assume it is correct */    -  +  old_type = n->type; +  n->type = 0; +  n->node_info &= ~OPT_TYPE_NOT_FIXED; +     switch(n->token)    { -  +  case F_CAST: +  /* Type-field is correct by definition. */ +  copy_shared_string(n->type, old_type); +  break; +     case F_LAND:    case F_LOR:    if (!CAR(n) || CAR(n)->type == void_type_string ||    !CDR(n) || CDR(n)->type == void_type_string) {    yyerror("Conditional contains void expression.");    copy_shared_string(n->type, mixed_type_string);    break;    }    if(!match_types(CAR(n)->type,mixed_type_string))    yyerror("Bad conditional expression.");
pike.git/src/las.c:1990:    /* FIXME: Shouldn't it be an or? */    copy_shared_string(n->type,mixed_type_string);    }    break;       case F_ASSIGN:    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    my_yyerror("Assigning a void expression.");    copy_shared_string(n->type, void_type_string);    break; -  } else if(CAR(n) && CDR(n) && +  } else if(CAR(n) && CDR(n)) { +  fix_type_field(CAR(n)); +  fix_type_field(CDR(n));    /* a["b"]=c and a->b=c can be valid when a is an array */ -  CDR(n)->token != F_INDEX && CDR(n)->token != F_ARROW && +  if (CDR(n)->token != F_INDEX && CDR(n)->token != F_ARROW &&    !match_types(CDR(n)->type,CAR(n)->type)) {    my_yyerror("Bad type in assignment.");    } -  +  }    copy_shared_string(n->type, CAR(n)->type);    break;       case F_INDEX:    case F_ARROW:    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    my_yyerror("Indexing a void expression.");    /* The optimizer converts this to an expression returning 0. */    copy_shared_string(n->type, mixed_type_string);    } else {
pike.git/src/las.c:2018:    if(!check_indexing(type_a, type_b, n))    if(!catch_level)    my_yyerror("Indexing on illegal type.");    n->type=index_type(type_a,n);    }    break;       case F_APPLY:    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    my_yyerror("Calling a void expression."); -  /* The optimizer converts this to an expression returning 0. */ -  if (!n->type) { -  copy_shared_string(n->type, mixed_type_string); -  } +     } else {    struct pike_string *s;    struct pike_string *f; -  +  char *name;    INT32 max_args,args; -  +     push_type(T_MIXED); /* match any return type, even void */    push_type(T_VOID); /* not varargs */    push_type(T_MANY);    function_type_max=0;    low_build_function_type(CDR(n));    push_type(T_FUNCTION);    s=pop_type();    f=CAR(n)->type?CAR(n)->type:mixed_type_string;    n->type=check_call(s,f);    args=count_arguments(s);    max_args=count_arguments(f);    if(max_args<0) max_args=0x7fffffff;    -  if(!n->type) -  { -  char *name; +     switch(CAR(n)->token)    {   #if 0 /* FIXME */ -  case F_TRAMPOLINE; +  case F_TRAMPOLINE:   #endif    case F_IDENTIFIER:    name=ID_FROM_INT(new_program, CAR(n)->u.id.number)->name->str;    break;       case F_CONSTANT:    switch(CAR(n)->u.sval.type)    {    case T_FUNCTION:    if(CAR(n)->u.sval.subtype == FUNCTION_BUILTIN)
pike.git/src/las.c:2093:    {    my_yyerror("Too many arguments to %s.",name);    }    else if(max_correct_args == args)    {    my_yyerror("Too few arguments to %s.",name);    }else{    my_yyerror("Bad argument %d to %s.",    max_correct_args+1, name);    } -  copy_shared_string(n->type, mixed_type_string); -  } +     free_string(s); -  break; +     } -  +  copy_shared_string(n->type, mixed_type_string); +  break;       case '?':    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    yyerror("Conditional expression is void.");    } else if(!match_types(CAR(n)->type,mixed_type_string))    yyerror("Bad conditional expression.");       if(!CDR(n) || !CADR(n) || !CDDR(n))    {    copy_shared_string(n->type,void_type_string); -  return; +  break;    }       if(CADR(n)->type == CDDR(n)->type)    {    copy_shared_string(n->type,CADR(n)->type); -  return; +  break;    }    -  +  /* FIXME: Should be type_a|type_b */    copy_shared_string(n->type,mixed_type_string);    break;       case F_RETURN:    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    yyerror("Returning a void expression.");    } else if(compiler_frame &&    compiler_frame->current_return_type &&    !match_types(compiler_frame->current_return_type,CAR(n)->type) &&    !(
pike.git/src/las.c:2146:    /* Fall through */       case F_INC_LOOP:    case F_DEC_LOOP:    case F_DEC_NEQ_LOOP:    case F_INC_NEQ_LOOP:    case F_CASE:    case F_CONTINUE:    case F_BREAK:    case F_DEFAULT: +  case F_POP_VALUE:    copy_shared_string(n->type,void_type_string);    break;       case F_DO:    if (!CDR(n) || (CDR(n)->type == void_type_string)) {    yyerror("do - while(): Conditional expression is void.");    } else if(!match_types(CDR(n)->type,mixed_type_string))    yyerror("Bad conditional expression do - while().");    copy_shared_string(n->type,void_type_string);    break;
pike.git/src/las.c:2177:    yyerror("switch(): Conditional expression is void.");    } else if(!match_types(CAR(n)->type,mixed_type_string))    yyerror("Bad switch expression.");    copy_shared_string(n->type,void_type_string);    break;       case F_CONSTANT:    n->type = get_type_of_svalue(& n->u.sval);    break;    -  case F_COMMA_EXPR: +     case F_ARG_LIST: -  +  if (n->parent) { +  /* Propagate the changed type all the way up to the apply node. */ +  n->parent->node_info |= OPT_TYPE_NOT_FIXED; +  } +  /* FALL_THROUGH */ +  case F_COMMA_EXPR:    if(!CAR(n) || CAR(n)->type==void_type_string)    {    if(CDR(n))    copy_shared_string(n->type,CDR(n)->type);    else    copy_shared_string(n->type,void_type_string); -  return; +  break;    }       if(!CDR(n) || CDR(n)->type==void_type_string)    {    if(CAR(n))    copy_shared_string(n->type,CAR(n)->type);    else    copy_shared_string(n->type,void_type_string); -  return; +  break;    }       default:    copy_shared_string(n->type,mixed_type_string);    } -  +  +  if (n->type != old_type) { +  if (n->parent) { +  n->parent->node_info |= OPT_TYPE_NOT_FIXED;    } -  +  } +  if (old_type) { +  free_string(old_type); +  } + }      static void zapp_try_optimize(node *n)   {    if(!n) return;    n->node_info &=~ OPT_TRY_OPTIMIZE;    n->tree_info &=~ OPT_TRY_OPTIMIZE;    if(car_is_node(n)) zapp_try_optimize(CAR(n));    if(cdr_is_node(n)) zapp_try_optimize(CDR(n));   }   
pike.git/src/las.c:3016: Inside #if defined(SHARED_NODES)
  #ifdef SHARED_NODES    n->hash = hash_node(n);    n->node_info |= OPT_DEFROSTED;    add_node(n);   #endif /* SHARED_NODES */    if(CDR(n)) CDR(n)->parent = n;    zapp_try_optimize(CDR(n)); /* avoid infinite loops */    continue;    }    } +  if (!n->type || (n->node_info & OPT_TYPE_NOT_FIXED)) {    fix_type_field(n); -  +  }    debug_malloc_touch(n->type);      #ifdef PIKE_DEBUG    if(l_flag > 3 && n)    {    fprintf(stderr,"Optimizing (tree info=%04x):",n->tree_info);    print_tree(n);    }   #endif   
pike.git/src/las.c:3062: Inside #if defined(SHARED_NODES)
     #ifdef SHARED_NODES    sub_node(n->parent);   #endif /* SHARED_NODES */       if(CAR(n->parent) == n)    _CAR(n->parent) = tmp1;    else    _CDR(n->parent) = tmp1;    +  if (!tmp1 || (tmp1->type != n->type)) { +  n->parent->node_info |= OPT_TYPE_NOT_FIXED; +  } +    #ifdef SHARED_NODES    n->parent->hash = hash_node(n->parent);    add_node(n->parent);    n->parent->node_info |= OPT_DEFROSTED;   #endif /* SHARED_NODES */       if(tmp1)    tmp1->parent = n->parent;    else    tmp1 = n->parent;