pike.git / src / pike_types.cmod

version» Context lines:

pike.git/src/pike_types.cmod:11938:    simple_describe_type(arg_type);    fprintf(stderr, " against function type ");    simple_describe_type(fun_type);    fprintf(stderr, ".\n");    remap_flags |= PT_FLAG_REMAP_TRACE;    }   #endif /* PIKE_DEBUG */       /* No need to perform advanced checking in the trivial case... */    if (arg_type != (tmp2 = fun_type->car)) { +  if (flags & CALL_ARG_LVALUE) { +  /* For lvalues (ie sscanf) the direction is reversed. */ +  struct pike_type *tmp3 = tmp2; +  tmp2 = arg_type; +  arg_type = tmp3; +  +  remap_flags ^= PT_FLAG_REMAP_SWAP_MARKERS; +  }    if (!tmp2) {    if (flags & CALL_STRICT) goto no_match;    } else if (tmp2 == void_type_string) {    /* No more arguments accepted. */    goto no_match;    } else {    struct pike_type *bin_t =    low_type_binop(PT_BINOP_MINUS,    arg_type, tmp2, &remap,    PT_FLAG_CMP_VOID_IS_ZERO,
pike.git/src/pike_types.cmod:11986:    if (tmp) free_type(tmp);       EXIT_REMAP_STATE(remap);       break;    }       free_type(bin_t);    }    } +  +  if (flags & CALL_ARG_LVALUE) { +  /* Undo the lvalue swap from above. */ +  struct pike_type *tmp3 = tmp2; +  tmp2 = arg_type; +  arg_type = tmp3; +  +  remap_flags ^= PT_FLAG_REMAP_SWAP_MARKERS;    } -  +  }       /* Match. */    if (fun_type->type == PIKE_T_FUNCTION) {    struct pike_type *t = NULL;    /* Advance to the next argument. */    fun_cont = fun_type->cdr;    } else {    fun_cont = fun_type;    }   
pike.git/src/pike_types.cmod:12123:    * int|string    * where a value only can have one of the    * types at a time.    * In strict mode the former should be split here,    * and the latter kept.    * In non-strict mode both should be split here.    * Suggestion:    * Introduce a new operator (UNION?) for the former case.    */    +  if (!(flags & CALL_ARG_LVALUE)) {    loop:    /* First split the argument type into basic types. */    switch(arg_type?arg_type->type:PIKE_T_UNKNOWN) {    case T_ASSIGN:    case PIKE_T_NAME:    arg_type = arg_type->cdr;    goto loop;       /* FIXME: PIKE_T_ATTRIBUTE's ought to propagate out to the basic types.    */
pike.git/src/pike_types.cmod:12200:    return pop_unfinished_type();       case T_VOID:    if ((flags & (CALL_WEAK_VOID|CALL_STRICT)) == CALL_STRICT) {    return NULL;    }    /* Promote void arguments to zero. */    arg_type = zero_type_string;    break;    } +  }       if (!(tmp = lower_new_check_call(fun_type, arg_type,    flags & ~CALL_WEAK_VOID, cs, sval   #ifdef PIKE_TYPE_DEBUG    , 0   #endif    ))) {    struct pike_type *tmp2;    if (!(flags & CALL_STRICT) || !arg_type || (arg_type->type != T_INT) ||    (CAR_TO_INT(arg_type) >= 0) || (CDR_TO_INT(arg_type) <= 0)) {
pike.git/src/pike_types.cmod:12985:   #ifdef PIKE_DEBUG    if (l_flag>2) fputc ('\n', stderr);   #endif    if ((res = low_new_check_call(fun_type, args->type, flags, cs, sval))) {    /* OK. */   #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, " OK.\n");    }   #endif /* PIKE_DEBUG */ -  if ((c->lex.pragmas & ID_STRICT_TYPES) && -  /* FIXME: Strict types not supported for lvalues yet. */ -  !(flags & CALL_ARG_LVALUE)){ +  if (c->lex.pragmas & ID_STRICT_TYPES) {    if (!(tmp = low_new_check_call(fun_type, args->type,    flags|CALL_STRICT, cs, sval))) {    tmp = get_first_arg_type(fun_type, flags);    yytype_report(REPORT_WARNING, NULL, 0, tmp,    NULL, 0, args->type,    0, "Type mismatch in argument %d to %S.",    cs->argno, fun_name);    if (tmp) free_type(tmp);    } else {    free_type(tmp);    }    }    free_type(fun_type); -  +     return res;    }    }       if ((tmp = get_first_arg_type(fun_type, flags|CALL_NOT_LAST_ARG))) {    struct pike_type *tmp2;      #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, " Bad argument.\n");
pike.git/src/pike_types.cmod:13030:    /* Succeeded. */    free_type(fun_type);    free_type(tmp);   #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, " Created continuation type: ");    simple_describe_type(tmp2);    fprintf(stderr, " OK.\n");    }   #endif /* PIKE_DEBUG */ +     return tmp2;    }   #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, "\n Failed to create continuation type.\n");    }   #endif /* PIKE_DEBUG */    free_type(tmp);    } else {   #ifdef PIKE_DEBUG    if (l_flag>2) {    fprintf(stderr, " Too many arguments.\n");    }   #endif /* PIKE_DEBUG */    yytype_report(REPORT_ERROR, NULL, 0, NULL,    NULL, 0, args->type,    0, "Too many arguments to %S (expected %d arguments).",    fun_name, cs->argno - 1);    }    free_type(fun_type); -  +     return NULL;   }      /* NOTE: fun_type loses a reference. */   struct pike_type *new_check_call(struct pike_string *fun_name,    struct pike_type *fun_type,    node *args, struct call_state *cs,    INT32 flags)   { -  +  node *orig_args = args;    node *orig_arg_parent = NULL; -  INT32 orig_flags = flags; +     int num_cdr = 0; -  int num_lvalue = 0; +        if (!args || !fun_type) {    debug_malloc_touch(fun_type);    return fun_type;    }       orig_arg_parent = args->parent;    args->parent = NULL; /* End marker. */    -  +  if (flags & CALL_NOT_LAST_ARG) { +  /* Recursive call, where there's a CDR above. */ +  num_cdr = 1; +  } +     debug_malloc_touch(fun_type);       clear_markers();    while (args && fun_type) {    if ((args->token == F_ARG_LIST) || (args->token == F_LVALUE_LIST)) {    if (CDR(args)) {    num_cdr++;    flags |= CALL_NOT_LAST_ARG;    }    if (args->token == F_LVALUE_LIST) { -  num_lvalue++; +     flags |= CALL_ARG_LVALUE;    }    if (CAR(args)) {    CAR(args)->parent = args;    args = CAR(args);    continue;    } else if (CDR(args)) {    CDR(args)->parent = args;    args = CDR(args);    if (!--num_cdr) { -  flags = orig_flags | (num_lvalue?CALL_ARG_LVALUE:0); +  flags &= ~CALL_NOT_LAST_ARG;    }    continue;    }    } else {    fun_type = new_check_call_arg(fun_name, fun_type, args, cs, flags);    debug_malloc_touch(fun_type); -  -  if (!fun_type) return NULL; +     }    -  do { +  while (args && fun_type) {    node *prev = args; -  if (args->token == F_LVALUE_LIST) { -  if (!--num_lvalue) { -  flags = orig_flags | (num_cdr?CALL_NOT_LAST_ARG:0); -  } -  } +     args = args->parent;    if (!args) { -  prev->parent = orig_arg_parent; +     break;    }    if ((CAR(args) == prev) && CDR(args)) {    if (!--num_cdr) { -  flags = orig_flags | (num_lvalue?CALL_ARG_LVALUE:0); +  flags &= ~CALL_NOT_LAST_ARG;    }    if (CDR(args) != prev) {    CDR(args)->parent = args;    args = CDR(args);    break;    }    /* CAR(args) == CDR(args), so we need to recurse    * since we can't differentiate otherwise.    *    * This should be a quite rare case, and the tree is    * most likely very shallow, so this should be safe.    */    fun_type = new_check_call(fun_name, fun_type, prev, cs, flags);    debug_malloc_touch(fun_type); -  -  if (!fun_type) return NULL; +     } -  } while(args); +     } -  +  }    -  +  orig_args->parent = orig_arg_parent; +     return fun_type;   }      struct pike_type *zzap_function_return(struct pike_type *a,    struct pike_type *fun_ret)   {    struct pike_type *ret = NULL;    switch(a->type & PIKE_T_MASK)    {    case T_SCOPE:
pike.git/src/pike_types.cmod:14405:    tObj)));    typeable_type_string = CONSTTYPE(tOr4(tPrg(tObj), tObj,    tFuncV(tNone, tOr(tVoid, tMix),    tObj),    tType(tMix)));    enumerable_type_string = CONSTTYPE(tOr3(tString,tInt,tFloat));    any_type_string = CONSTTYPE(tOr(tVoid,tMix));    weak_type_string = CONSTTYPE(tOr4(tArray,tMultiset,tMapping,    tFuncV(tNone,tZero,tOr(tMix,tVoid))));    sscanf_type_string = CONSTTYPE(tFuncV(tStr tAttr("sscanf_format", tStr), -  tAttr("sscanf_args", tMix), tIntPos)); +  tAttr("sscanf_args", tUnknown), tIntPos));    utf8_type_string = CONSTTYPE(tUtf8Str);       /* add_ref(weak_type_string); *//* LEAK */       literal_string_string = make_shared_string("string");    literal_int_string = make_shared_string("int");    literal_float_string = make_shared_string("float");    literal_function_string = make_shared_string("function");    literal_object_string = make_shared_string("object");    literal_program_string = make_shared_string("program");