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.233 2001/02/09 10:29:54 hubbe Exp $"); + RCSID("$Id: las.c,v 1.234 2001/02/19 23:50:00 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:283:    return 0;    return 1;       default:    if(n->type == void_type_string) return 0;    return 1;    }   }      /* FIXME: Ought to use parent pointer to avoid recursion. */ - struct pike_string *find_return_type(node *n) + struct pike_type *find_return_type(node *n)   { -  struct pike_string *a,*b; +  struct pike_type *a, *b;       check_tree(n,0);       fatal_check_c_stack(16384);       if(!n) return 0;       if (n->token == F_RETURN) {    if (CAR(n)) {    if (CAR(n)->type) { -  copy_shared_string(a, CAR(n)->type); +  copy_type(a, CAR(n)->type);    } else {   #ifdef PIKE_DEBUG    if (l_flag > 2) {    fprintf(stderr, "Return with untyped argument.\n");    print_tree(n);    }   #endif /* PIKE_DEBUG */ -  copy_shared_string(a, mixed_type_string); +  copy_type(a, mixed_type_string);    }    } else { -  copy_shared_string(a, zero_type_string); +  copy_type(a, zero_type_string);    }    return a;    }       if(!(n->tree_info & OPT_RETURN)) return 0;       if(car_is_node(n))    a=find_return_type(CAR(n));    else    a=0;       if(cdr_is_node(n))    b=find_return_type(CDR(n));    else    b=0;       if(a)    {    if(b) {    if (a != b) { -  struct pike_string *res = or_pike_types(a, b, 1); -  free_string(a); -  free_string(b); +  struct pike_type *res = or_pike_types(a, b, 1); +  free_type(a); +  free_type(b);    return res;    } -  free_string(b); +  free_type(b);    }    return a;    }    return b;   }      int check_tailrecursion(void)   {    int e;    if(debug_options & NO_TAILRECURSION) return 0;
pike.git/src/las.c:1298: Inside #if defined(PIKE_DEBUG)
   simple_describe_type(res->type);    printf("\n");       fatal("Type of external node is not matching it's identifier.\n");    }   #endif       return res;   }    - node *debug_mkcastnode(struct pike_string *type,node *n) + node *debug_mkcastnode(struct pike_type *type, node *n)   {    node *res;       if(!n) return 0;      #ifdef PIKE_DEBUG    if (!type) {    fatal("Casting 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;       res = mkemptynode();    res->token = F_CAST; -  copy_shared_string(res->type,type); +  copy_type(res->type, type);       if(match_types(object_type_string, type) ||    match_types(program_type_string, type))    res->node_info |= OPT_SIDE_EFFECT;       res->tree_info |= n->tree_info;       _CAR(res) = n;    _CDR(res) = mktypenode(type);       n->parent = res;       return freeze_node(res);   }    - node *debug_mksoftcastnode(struct pike_string *type,node *n) + node *debug_mksoftcastnode(struct pike_type *type, node *n)   {    node *res;       if(!n) return 0;      #ifdef PIKE_DEBUG    if (!type) {    fatal("Soft cast to no type!\n");    }   #endif /* PIKE_DEBUG */
pike.git/src/las.c:1375:    }    /* FIXME: check_soft_cast() is weaker than pike_types_le()    * The resulting type should probably be the and between the old    * and the new type.    */    }    }       res = mkemptynode();    res->token = F_SOFT_CAST; -  copy_shared_string(res->type, type); +  copy_type(res->type, type);       res->tree_info |= n->tree_info;       _CAR(res) = n;    _CDR(res) = mktypenode(type);       n->parent = res;       return freeze_node(res);   }
pike.git/src/las.c:1711:    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;    }   }    - node *debug_mktypenode(struct pike_string *t) + node *debug_mktypenode(struct pike_type *t)   {    node *res = mkemptynode();    res->token = F_CONSTANT; -  copy_shared_string(res->u.sval.u.string, t); +  copy_type(res->u.sval.u.type, t);    res->u.sval.type = T_TYPE; -  copy_shared_string(res->type, type_type_string); +  copy_type(res->type, type_type_string);    return freeze_node(res);   }      node *debug_mkconstantsvaluenode(struct svalue *s)   {    node *res = mkemptynode();    res->token = F_CONSTANT;    assign_svalue_no_free(& res->u.sval, s);    if(s->type == T_OBJECT ||    (s->type==T_FUNCTION && s->subtype!=FUNCTION_BUILTIN))
pike.git/src/las.c:2914:    if(n->type)    {    if(n->type == void_type_string) return;    push_finished_type(n->type);    }else{    push_type(T_MIXED);    }    }   }    - void yytype_error(char *msg, struct pike_string *expected_t, -  struct pike_string *got_t, unsigned int flags) + void yytype_error(char *msg, struct pike_type *expected_t, +  struct pike_type *got_t, unsigned int flags)   {    if (msg)    {    if (flags & YYTE_IS_WARNING)    yywarning("%s", msg);    else    my_yyerror("%s", msg);    }       yyexplain_nonmatching_types(expected_t, got_t, flags);   }      void fix_type_field(node *n)   { -  struct pike_string *type_a,*type_b; -  struct pike_string *old_type; +  struct pike_type *type_a,*type_b; +  struct pike_type *old_type;       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)    {
pike.git/src/las.c:2960:    free_string(t1);    }    /* FIXME: check_soft_cast() is weaker than pike_types_le()    * The resulting type should probably be the and between the old    * and the new type.    */    }    /* FALL_THROUGH */    case F_CAST:    /* Type-field is correct by definition. */ -  copy_shared_string(n->type, old_type); +  copy_type(n->type, old_type);    break;       case F_LAND:    case F_LOR:    if (!CAR(n) || CAR(n)->type == void_type_string) {    yyerror("Conditional uses void expression."); -  copy_shared_string(n->type, mixed_type_string); +  copy_type(n->type, mixed_type_string);    break;    }    if(!match_types(CAR(n)->type,mixed_type_string))    yyerror("Bad conditional expression.");       if (!CDR(n) || CDR(n)->type == void_type_string) -  copy_shared_string(n->type,void_type_string); +  copy_type(n->type,void_type_string);    else if(n->token == F_LAND || CAR(n)->type == CDR(n)->type)    { -  copy_shared_string(n->type,CDR(n)->type); +  copy_type(n->type,CDR(n)->type);    }else{    n->type = or_pike_types(CAR(n)->type, CDR(n)->type, 0);    }    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); +  copy_type(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)) {    yytype_error("Bad type in assignment.",
pike.git/src/las.c:3023:    }    }    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, zero_type_string); +  copy_type(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(!Pike_compiler->catch_level)    my_yyerror("Indexing on illegal type.");    n->type=index_type(type_a, type_b,n);    }    break;       case F_APPLY:    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    my_yyerror("Calling a void expression.");    } else { -  struct pike_string *s; -  struct pike_string *f; +  struct pike_type *s; +  struct pike_type *f;    char *name;    INT32 max_args,args;       push_type(T_MIXED); /* match any return type */    push_type(T_VOID); /* even void */    push_type(T_OR);       push_type(T_VOID); /* not varargs */    push_type(T_MANY);    function_type_max=0;
pike.git/src/las.c:3064:    n->type = check_call(s, f,    (lex.pragmas & ID_STRICT_TYPES) &&    !(n->node_info & OPT_WEAK_TYPE));    args = count_arguments(s);    max_args = count_arguments(f);    if(max_args<0) max_args = 0x7fffffff;          if (n->type) {    /* Type/argument-check OK. */ -  free_string(s); +  free_type(s);    break;    }       switch(CAR(n)->token)    {   #if 0 /* FIXME */    case F_TRAMPOLINE:   #endif    case F_IDENTIFIER:    name=ID_FROM_INT(Pike_compiler->new_program, CAR(n)->u.id.number)->name->str;
pike.git/src/las.c:3159:    break;       default:    name="unknown function";    }       if(max_args < args)    {    if(TEST_COMPAT(0,6))    { -  free_string(s); -  copy_shared_string(n->type, mixed_type_string); +  free_type(s); +  copy_type(n->type, mixed_type_string);    break;    }    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);    }       yytype_error(NULL, f, s, 0);       /* print_tree(n); */    -  free_string(s); +  free_type(s);    } -  copy_shared_string(n->type, mixed_type_string); +  copy_type(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) ||    CADR(n)->type == void_type_string ||    CDDR(n)->type == void_type_string)    { -  copy_shared_string(n->type,void_type_string); +  copy_type(n->type, void_type_string);    break;    }       if(CADR(n)->type == CDDR(n)->type)    { -  copy_shared_string(n->type,CADR(n)->type); +  copy_type(n->type, CADR(n)->type);    break;    }       n->type = or_pike_types(CADR(n)->type, CDDR(n)->type, 0);    break;       case F_AND_EQ:    case F_OR_EQ:    case F_XOR_EQ:    case F_LSH_EQ:
pike.git/src/las.c:3226:    * type = typeof(OP(var, expr)) AND typeof(var);    */    case F_RANGE:    case F_INC:    case F_DEC:    case F_POST_INC:    case F_POST_DEC:    if (CAR(n)) {    /* The expression gets the type from the variable. */    /* FIXME: Ought to strip non-applicable subtypes from the type. */ -  copy_shared_string(n->type, CAR(n)->type); +  copy_type(n->type, CAR(n)->type);    } else { -  copy_shared_string(n->type, mixed_type_string); +  copy_type(n->type, mixed_type_string);    }    break;       case F_RETURN:    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    yywarning("Returning a void expression.");    if (!CAR(n)) {   #ifdef SHARED_NODES    sub_node(n);   #endif /* SHARED_NODES */    _CAR(n) = mkintnode(0); -  copy_shared_string(n->type, CAR(n)->type); +  copy_type(n->type, CAR(n)->type);   #ifdef SHARED_NODES    if (!(n->tree_info & OPT_NOT_SHARED)) {    n->hash = hash_node(n);    }    n->node_info |= OPT_DEFROSTED;    add_node(n);   #endif /* SHARED_NODES */    break;    } -  } else if(Pike_compiler->compiler_frame && Pike_compiler->compiler_frame->current_return_type) { -  if (!pike_types_le(CAR(n)->type, Pike_compiler->compiler_frame->current_return_type) && +  } else if(Pike_compiler->compiler_frame && +  Pike_compiler->compiler_frame->current_return_type) { +  if (!pike_types_le(CAR(n)->type, +  Pike_compiler->compiler_frame->current_return_type) &&    !(    Pike_compiler->compiler_frame->current_return_type==void_type_string &&    CAR(n)->token == F_CONSTANT &&    IS_ZERO(& CAR(n)->u.sval)    )    ) { -  if (!match_types(Pike_compiler->compiler_frame->current_return_type,CAR(n)->type)) +  if (!match_types(Pike_compiler->compiler_frame->current_return_type, +  CAR(n)->type))    {    yyerror("Wrong return type.");    yyexplain_nonmatching_types(Pike_compiler->compiler_frame->current_return_type,    CAR(n)->type,0);    }    else if (lex.pragmas & ID_STRICT_TYPES)    {    yytype_error("Return type mismatch.",    Pike_compiler->compiler_frame->current_return_type,    CAR(n)->type,    YYTE_IS_WARNING);    }    }    } -  copy_shared_string(n->type,void_type_string); +  copy_type(n->type, void_type_string);    break;       case F_CASE:    if (CDR(n) && CAR(n) && !TEST_COMPAT(0,6)) {    /* case 1 .. 2: */    if (!match_types(CAR(n)->type, CDR(n)->type)) {    if (!match_types(CAR(n)->type, int_type_string) ||    !match_types(CDR(n)->type, int_type_string)) {    yytype_error("Type mismatch in case range.",    CAR(n)->type, CDR(n)->type, 0);
pike.git/src/las.c:3313:    }    /* FALL_THROUGH */    case F_INC_LOOP:    case F_DEC_LOOP:    case F_DEC_NEQ_LOOP:    case F_INC_NEQ_LOOP:    case F_CONTINUE:    case F_BREAK:    case F_DEFAULT:    case F_POP_VALUE: -  copy_shared_string(n->type,void_type_string); +  copy_type(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); +  copy_type(n->type, void_type_string);    break;       case F_FOR:    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    yyerror("for(): Conditional expression is void.");    } else if(!match_types(CAR(n)->type,mixed_type_string))    yyerror("Bad conditional expression for()."); -  copy_shared_string(n->type,void_type_string); +  copy_type(n->type, void_type_string);    break;       case F_SWITCH:    if (!CAR(n) || (CAR(n)->type == void_type_string)) {    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); +  copy_type(n->type, void_type_string);    break;       case F_CONSTANT:    n->type = get_type_of_svalue(& n->u.sval);    break;       case F_FOREACH:    if (!CAR(n) || (CAR(n)->token != F_VAL_LVAL)) {    yyerror("foreach(): No expression to loop over.");    } else {    if (!CAAR(n) || pike_types_le(CAAR(n)->type, void_type_string)) {    yyerror("foreach(): Looping over a void expression.");    } else { -  struct pike_string *array_zero; +  struct pike_type *array_zero;    MAKE_CONSTANT_SHARED_STRING(array_zero, tArr(tZero));       if (!pike_types_le(array_zero, CAAR(n)->type)) {    yyerror("Bad argument 1 to foreach().");    } else {    if ((lex.pragmas & ID_STRICT_TYPES) &&    !pike_types_le(CAAR(n)->type, array_type_string)) {    struct pike_string *t = describe_type(CAAR(n)->type);    yywarning("Argument 1 to foreach() is not always an array.");    yywarning("Got: %s", t->str);    free_string(t);    }       if (!CDAR(n) || pike_types_le(CDAR(n)->type, void_type_string)) {    yyerror("Bad argument 2 to foreach().");    } else { -  struct pike_string *value_type = array_value_type(CAAR(n)->type); +  struct pike_type *value_type = array_value_type(CAAR(n)->type);       if (!pike_types_le(value_type, CDAR(n)->type)) {    if (!match_types(value_type, CDAR(n)->type)) {    yytype_error("Variable type mismatch in foreach().",    value_type, CDAR(n)->type, 0);    } else if (lex.pragmas & ID_STRICT_TYPES) {    yytype_error("Variable type mismatch in foreach().",    value_type, CDAR(n)->type, YYTE_IS_WARNING);    }    } -  free_string(value_type); +  free_type(value_type);    }    } -  free_string(array_zero); +  free_type(array_zero);    }    } -  copy_shared_string(n->type, void_type_string); +  copy_type(n->type, void_type_string);    break;       case F_SSCANF:    if (!CAR(n) || (CAR(n)->token != F_ARG_LIST) ||    !CAAR(n) || !CDAR(n)) {    yyerror("Too few arguments to sscanf().");    } else {    if (!pike_types_le(CAAR(n)->type, string_type_string)) {    if (!match_types(CAAR(n)->type, string_type_string)) {    yytype_error("Bad argument 1 to sscanf().",
pike.git/src/las.c:3429:    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); +  copy_type(n->type, CDR(n)->type);    else -  copy_shared_string(n->type,void_type_string); +  copy_type(n->type, void_type_string);    break;    }       if(!CDR(n) || CDR(n)->type==void_type_string)    {    if(CAR(n)) -  copy_shared_string(n->type,CAR(n)->type); +  copy_type(n->type, CAR(n)->type);    else -  copy_shared_string(n->type,void_type_string); +  copy_type(n->type, void_type_string);    break;    }    if (n->token == F_ARG_LIST) {    n->type = or_pike_types(CAR(n)->type, CDR(n)->type, 0);    } else { -  copy_shared_string(n->type, CDR(n)->type); +  copy_type(n->type, CDR(n)->type);    }    break;       case F_MAGIC_INDEX:    /* FIXME: Could have a stricter type for ::`->(). */    MAKE_CONSTANT_SHARED_STRING(n->type, tFunc(tMix,tMix));    break;    case F_MAGIC_SET_INDEX:    /* FIXME: Could have a stricter type for ::`->=(). */    MAKE_CONSTANT_SHARED_STRING(n->type, tFunc(tMix tSetvar(0,tMix), tVar(0)));    break;       case F_CATCH:    /* FALL_THROUGH */    default: -  copy_shared_string(n->type,mixed_type_string); +  copy_type(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); +  free_type(old_type);    }   #ifdef PIKE_DEBUG    check_type_string(n->type);   #endif /* PIKE_DEBUG */   }      static void zapp_try_optimize(node *n)   {    node *parent;    node *orig_n = n;
pike.git/src/las.c:3806: Inside #if defined(SHARED_NODES) && !defined(IN_TPIKE)
      if (!n)    return NULL;       switch(n->token) {    case F_ASSIGN:    if ((CDR(n)->token == F_LOCAL) && (!CDR(n)->u.integer.b)) {    /* Assignment of local variable */    if (!(usage[CDR(n)->u.integer.a] & 1)) {    /* Value isn't used. */ -  struct pike_string *ref_type; +  struct pike_type *ref_type;    MAKE_CONSTANT_SHARED_STRING(ref_type, tOr(tComplex, tString));    if (!match_types(CDR(n)->type, ref_type)) {    /* The variable doesn't hold a refcounted value. */ -  free_string(ref_type); +  free_type(ref_type);    return low_localopt(CAR(n), usage, switch_u, cont_u,    break_u, catch_u);    } -  free_string(ref_type); +  free_type(ref_type);    }    usage[CDR(n)->u.integer.a] = 0;    cdr = CDR(n);    ADD_NODE_REF(cdr);    } else if (CDR(n)->token == F_ARRAY_LVALUE) {    cdr = low_localopt(CDR(n), usage, switch_u, cont_u, break_u, catch_u);    } else {    cdr = CDR(n);    ADD_NODE_REF(cdr);    }
pike.git/src/las.c:4693:    n->token == F_POP_VALUE)    return is_null_branch(CAR(n));    if(n->token==F_ARG_LIST)    return is_null_branch(CAR(n)) && is_null_branch(CDR(n));    return 0;   }      static struct svalue *is_stupid_func(node *n,    int args,    int vargs, -  struct pike_string *type) +  struct pike_type *type)   {    node *a,*b;    int tmp;    while(1)    {    if(!n) return 0;       if(n->token == F_ARG_LIST)    {    if(is_null_branch(CAR(n)))
pike.git/src/las.c:4741:    return 0;       if(minimum_arguments(type) < minimum_arguments(n->type))    return 0;       return &n->u.sval;   }      int dooptcode(struct pike_string *name,    node *n, -  struct pike_string *type, +  struct pike_type *type,    int modifiers)   {    union idptr tmp;    int args, vargs, ret;    struct svalue *foo;       check_tree(check_node_hash(n),0);      #ifdef PIKE_DEBUG    if(a_flag > 1)