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.128 1999/11/23 03:07:35 grubba Exp $"); + RCSID("$Id: las.c,v 1.129 1999/11/23 22:04:17 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:39:   static void optimize(node *n);   static node *localopt(node *n);      node *init_node = 0;   int num_parse_error;   int cumulative_parse_error=0;   extern char *get_type_name(int);      #define MAX_GLOBAL 2048    + /* #define yywarning my_yyerror */ +    int car_is_node(node *n)   {    switch(n->token)    {    case F_EXTERNAL:    case F_IDENTIFIER:    case F_TRAMPOLINE:    case F_CONSTANT:    case F_LOCAL:    return 0;
pike.git/src/las.c:65:   int cdr_is_node(node *n)   {    switch(n->token)    {    case F_EXTERNAL:    case F_IDENTIFIER:    case F_TRAMPOLINE:    case F_CONSTANT:    case F_LOCAL:    case F_CAST: +  case F_SOFT_CAST:    return 0;       default:    return !!_CDR(n);    }   }      #ifdef PIKE_DEBUG   void check_tree(node *n, int depth)   {
pike.git/src/las.c:135:    b=count_args(CDR(n));    if(b==-1) return -1;    return a+b;       case F_CAST:    if(n->type == void_type_string)    return 0;    else    return count_args(CAR(n));    +  case F_SOFT_CAST: +  return count_args(CAR(n)); +     case F_CASE:    case F_FOR:    case F_DO:    case F_INC_LOOP:    case F_DEC_LOOP:    case F_DEC_NEQ_LOOP:    case F_INC_NEQ_LOOP:    case F_BREAK:    case F_RETURN:    case F_CONTINUE:
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) +  if ((token == F_CAST) || (token == F_SOFT_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;
pike.git/src/las.c:907:    node *res;       if(!n) return 0;      #ifdef PIKE_DEBUG    if (!type) {    fatal("Soft cast to no type!\n");    }   #endif /* PIKE_DEBUG */    +  if (type == void_type_string) return mknode(F_POP_VALUE, n, 0); +     if(type==n->type) return n;       if (n->type) { -  if (!match_types(type, n->type)) { +  if (!pike_types_le(type, n->type)) {    struct pike_string *t1 = describe_type(type);    struct pike_string *t2 = describe_type(n->type);    yywarning("Soft cast to %s isn't a restriction of %s.",    t1->str, t2->str);    free_string(t2);    free_string(t1);    }    }    res = mkemptynode();    res->token = F_SOFT_CAST;
pike.git/src/las.c:1216:    {    case F_LOCAL:    return a->u.integer.a == b->u.integer.a &&    a->u.integer.b == b->u.integer.b;       case F_IDENTIFIER:    case F_TRAMPOLINE: /* FIXME, the context has to be the same! */    return a->u.id.number == b->u.id.number;       case F_CAST: +  case F_SOFT_CAST:    return a->type == b->type && node_is_eq(CAR(a), CAR(b));       case F_CONSTANT:    return is_equal(&(a->u.sval), &(b->u.sval));       default:    if( a->type != b->type ) return 0;    if(car_is_node(a) && !node_is_eq(CAR(a), CAR(b))) return 0;    if(cdr_is_node(a) && !node_is_eq(CDR(a), CDR(b))) return 0;    return 1;
pike.git/src/las.c:1344: Inside #if defined(DEAD_CODE)
      default:   #ifdef SHARED_NODES    n->refs++;    return n;   #else /* !SHARED_NODES */    case F_CAST:    b=mkcastnode(n->type,copy_node(CAR(n)));    break;    +  case F_SOFT_CAST: +  b=mksoftcastnode(n->type,copy_node(CAR(n))); +  break; +     case F_CONSTANT:    b=mksvaluenode(&(n->u.sval));    break;       default:    switch((car_is_node(n) << 1) | cdr_is_node(n))    {    default: fatal("fooo?\n");       case 3:
pike.git/src/las.c:1448:    if(!n) return 0;    if(!n->type) return 1;    return type_may_overload(n->type->str, lfun);   }      node **last_cmd(node **a)   {    node **n;    if(!a || !*a) return (node **)NULL;    if(((*a)->token == F_CAST) || +  ((*a)->token == F_SOFT_CAST) ||    ((*a)->token == F_POP_VALUE)) return last_cmd(&_CAR(*a));    if(((*a)->token != F_ARG_LIST) &&    ((*a)->token != F_COMMA_EXPR)) return a;    if(CDR(*a))    {    if(CDR(*a)->token != F_CAST && -  +  CDR(*a)->token != F_SOFT_CAST &&    CDR(*a)->token != F_POP_VALUE &&    CAR(*a)->token != F_ARG_LIST && /* FIXME: typo? */    CAR(*a)->token != F_COMMA_EXPR) /* FIXME: typo? */    return &_CDR(*a);    if((n=last_cmd(&_CDR(*a))))    return n;    }    if(CAR(*a))    {    if(CAR(*a)->token != F_CAST && -  +  CAR(*a)->token != F_SOFT_CAST &&    CAR(*a)->token != F_POP_VALUE &&    CAR(*a)->token != F_ARG_LIST &&    CAR(*a)->token != F_COMMA_EXPR)    return &_CAR(*a);    if((n=last_cmd(&_CAR(*a))))    return n;    }    return 0;   }   
pike.git/src/las.c:1592:    init_buf();    low_describe_type(foo->type->str);    s=simple_free_buf();    fprintf(stderr, "(%s){",s);    free(s);    low_print_tree(_CAR(foo),0);    fprintf(stderr, "}");    break;    }    +  case F_SOFT_CAST: +  { +  char *s; +  init_buf(); +  low_describe_type(foo->type->str); +  s=simple_free_buf(); +  fprintf(stderr, "[%s]{",s); +  free(s); +  low_print_tree(_CAR(foo),0); +  fprintf(stderr, "}"); +  break; +  } +     case F_COMMA_EXPR:    low_print_tree(_CAR(foo),0);    if(_CAR(foo) && _CDR(foo))    {    if(_CAR(foo)->type == void_type_string &&    _CDR(foo)->type == void_type_string)    fprintf(stderr, ";\n");    else    fprintf(stderr, ",\n");    }
pike.git/src/las.c:1955:   #else   #define depend_p depend_p3   #endif      static int cntargs(node *n)   {    if(!n) return 0;    switch(n->token)    {    case F_CAST: +  case F_SOFT_CAST:    case F_APPLY:    return n->type != void_type_string;       case F_POP_VALUE:    case F_FOREACH:    case F_INC_NEQ_LOOP:    case F_DEC_NEQ_LOOP:    case F_INC_LOOP:    case F_DEC_LOOP: return 0;   
pike.git/src/las.c:2032:    return; /* assume it is correct */       old_type = n->type;    n->type = 0;    n->node_info &= ~OPT_TYPE_NOT_FIXED;       switch(n->token)    {    case F_SOFT_CAST:    if (CAR(n) && CAR(n)->type) { -  if (!match_types(old_type, CAR(n)->type)) { +  if (!pike_types_le(old_type, CAR(n)->type)) {    struct pike_string *t1 = describe_type(old_type);    struct pike_string *t2 = describe_type(CAR(n)->type);    yywarning("Soft cast to %s isn't a restriction of %s.",    t1->str, t2->str);    free_string(t2);    free_string(t1);    }    }    /* FALL_THROUGH */    case F_CAST:
pike.git/src/las.c:2075:    n->type = or_pike_types(CAR(n)->type, CDR(n)->type);    }    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)) { +  /* Ensure that the type-fields are up to date. */    fix_type_field(CAR(n));    fix_type_field(CDR(n)); -  +  if (!pike_types_le(CAR(n)->type, CDR(n)->type)) {    /* a["b"]=c and a->b=c can be valid when a is an array */    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."); -  +  } else if (lex.pragmas & ID_STRICT_TYPES) { +  struct pike_string *t1 = describe_type(CAR(n)->type); +  struct pike_string *t2 = describe_type(CDR(n)->type); +  print_tree(n); +  yywarning("An expression type %s cannot be assigned to " +  "a variable of type %s.", +  t1->str, t2->str); +  free_string(t2); +  free_string(t1); +  yywarning("Incompatible types in assignment.");    }    } -  +  }    n->type = and_pike_types(CAR(n)->type, CDR(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); +  copy_shared_string(n->type, zero_type_string);    } else {    type_a=CAR(n)->type;    type_b=CDR(n)->type;    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;   
pike.git/src/las.c:2250:   #endif /* SHARED_NODES */    _CAR(n) = mkintnode(0);    copy_shared_string(n->type, CAR(n)->type);   #ifdef SHARED_NODES    n->hash = hash_node(n);    n->node_info |= OPT_DEFROSTED;    add_node(n);   #endif /* SHARED_NODES */    break;    } -  } else if(compiler_frame && -  compiler_frame->current_return_type && -  !match_types(compiler_frame->current_return_type,CAR(n)->type) && +  } else if(compiler_frame && compiler_frame->current_return_type) { +  if (!pike_types_le(CAR(n)->type, compiler_frame->current_return_type) &&    !(    compiler_frame->current_return_type==void_type_string &&    CAR(n)->token == F_CONSTANT &&    IS_ZERO(& CAR(n)->u.sval)    ) -  ) +  ) { +  if (!match_types(compiler_frame->current_return_type,CAR(n)->type))    {    yyerror("Wrong return type.");    } -  +  else if (lex.pragmas & ID_STRICT_TYPES) +  { +  yywarning("Return type mismatch."); +  } +  } +  }       /* 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:
pike.git/src/las.c:2310:       case F_CONSTANT:    n->type = get_type_of_svalue(& n->u.sval);    break;       case F_SSCANF:    MAKE_CONSTANT_SHARED_STRING(n->type, tIntPos);    break;       case F_UNDEFINED: -  MAKE_CONSTANT_SHARED_STRING(n->type, tInt0); +  MAKE_CONSTANT_SHARED_STRING(n->type, tZero);    break;       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)
pike.git/src/las.c:2748: Inside #if defined(SHARED_NODES) && !defined(IN_TPIKE)
   case F_ARRAY_LVALUE:    return mknode(F_ARRAY_LVALUE, low_localopt(CAR(n), usage, switch_u, cont_u,    break_u, catch_u), 0);             case F_CAST:    return mkcastnode(n->type, low_localopt(CAR(n), usage, switch_u, cont_u,    break_u, catch_u));    +  case F_SOFT_CAST: +  return mksoftcastnode(n->type, low_localopt(CAR(n), usage, switch_u, +  cont_u, break_u, catch_u)); +     case F_CONTINUE:    MEMCPY(usage, cont_u, MAX_LOCAL);    ADD_NODE_REF(n);    return n;       case F_BREAK:    MEMCPY(usage, break_u, MAX_LOCAL);    ADD_NODE_REF(n);    return n;   
pike.git/src/las.c:3387:       return ret;   }      static node *eval(node *n)   {    int args;    extern struct svalue *sp;    if(!is_const(n) || n->token==':')    return n; +     args=eval_low(n);       switch(args)    {    case -1:    return n;    break;       case 0:    if(catch_level) return n;    free_node(n);    n=0;    break;       case 1:    if(catch_level && IS_ZERO(sp-1))    {    pop_stack();    return n;    } -  +  if (n->token != F_SOFT_CAST) {    free_node(n);    n=mksvaluenode(sp-1); -  +  } else { +  node *nn = n; +  n = mksoftcastnode(n->type, mksvaluenode(sp-1)); +  free_node(nn); +  }    pop_stack();    break;       default: -  +  if (n->token != F_SOFT_CAST) {    free_node(n);    n=NULL;    while(args--)    {    n=mknode(F_ARG_LIST,mksvaluenode(sp-1),n);    pop_stack();    } -  +  } else { +  node *nn = n; +  n = NULL; +  while(args--) +  { +  n=mknode(F_ARG_LIST,mksvaluenode(sp-1),n); +  pop_stack();    } -  +  n = mksoftcastnode(nn->type, n); +  free_node(nn); +  } +  }    return dmalloc_touch(node *, n);   }      INT32 last_function_opt_info;      static int stupid_args(node *n, int expected,int vargs)   {    if(!n) return expected;    switch(n->token)    {