Compiler [Typechecker]: Support more complex function types.

Support type nodes other than T_FUNCTION and T_MANY in the cdr
of T_FUNCTION nodes.

Needed for #10048.
parent dc1da585
......@@ -452,6 +452,22 @@ static void encode_type(struct pike_type *t, struct encode_data *data)
t = t->cdr;
goto one_more_type;
} else if (t->type <= MAX_TYPE) {
if (t->type == T_FUNCTION) {
struct pike_type *tmp = t;
while (tmp->type == T_FUNCTION) tmp = tmp->cdr;
if (tmp->type != T_MANY) {
/* Function type needing tFuncArg. */
while (t->type == T_FUNCTION) {
addchar(t->type); /* Intentional !!!!! */
EDB(1, {
ENCODE_WERR(".type function_arg");
});
encode_type(t->car, data);
t = t->cdr;
}
goto one_more_type;
}
}
addchar(t->type ^ MIN_REF_TYPE);
EDB(1, {
ENCODE_WERR(".type %s",
......@@ -2731,6 +2747,12 @@ static void low_decode_type(struct decode_data *data)
push_scope_type(tmp); /* Actually reverse, but they're the same */
break;
case PIKE_T_FUNCTION_ARG:
low_decode_type(data); /* Argument */
low_decode_type(data); /* Continuation */
push_reverse_type(T_FUNCTION);
break;
case T_FUNCTION:
{
int narg = 0;
......
......@@ -193,6 +193,7 @@ PMOD_EXPORT char *get_name_of_type(TYPE_T t)
case PIKE_T_INT_UNTYPED: return "PIKE_T_INT_UNTYPED";
case PIKE_T_GET_SET: return "PIKE_T_GET_SET";
case PIKE_T_FREE: return "PIKE_T_FREE";
case PIKE_T_FUNCTION_ARG: return "PIKE_T_FUNCTION_ARG";
case PIKE_T_ATTRIBUTE: return "PIKE_T_ATTRIBUTE";
case PIKE_T_NSTRING: return "PIKE_T_NSTRING";
case PIKE_T_LSTRING: return "PIKE_T_LSTRING";
......@@ -2000,6 +2001,7 @@ void stupid_describe_type_string(char *a, ptrdiff_t len)
e+=sizeof(INT32)+1;
break;
case T_FUNCTION: fprintf(stderr, "function"); break;
case PIKE_T_FUNCTION_ARG: fprintf(stderr, "function_arg"); break;
case T_ARRAY: fprintf(stderr, "array"); break;
case T_MAPPING: fprintf(stderr, "mapping"); break;
case T_MULTISET: fprintf(stderr, "multiset"); break;
......@@ -2210,22 +2212,24 @@ void simple_describe_type(struct pike_type *s)
while(s->type == T_FUNCTION) {
simple_describe_type(s->car);
s = s->cdr;
while(s->type == T_ASSIGN) {
fprintf(stderr, "%"PRINTPTRDIFFT"d = ", CAR_TO_INT(s));
s = s->cdr;
}
if ((s->type == T_FUNCTION) ||
(s->car->type != T_VOID)) {
fprintf(stderr, ", ");
}
}
if (s->car->type != T_VOID) {
simple_describe_type(s->car);
fprintf(stderr, "...");
if (s->type != T_MANY) {
fprintf(stderr, ", @");
simple_describe_type(s);
fprintf(stderr, ")");
} else {
if (s->car->type != T_VOID) {
simple_describe_type(s->car);
fprintf(stderr, "...");
}
fprintf(stderr, ":");
simple_describe_type(s->cdr);
fprintf(stderr, ")");
}
fprintf(stderr, ":");
simple_describe_type(s->cdr);
fprintf(stderr, ")");
break;
case T_ARRAY: /* FIXME: cdr */
fprintf(stderr, "array(");
......@@ -2489,23 +2493,24 @@ void low_describe_type(struct string_builder *s, struct pike_type *t)
} else {
int arg = 0;
string_builder_strcat(s, "function(");
while(t->type != T_MANY)
while(t->type == T_FUNCTION)
{
if(arg++) string_builder_strcat(s, ", ");
low_describe_type(s, t->car);
t = t->cdr;
while(t->type == T_ASSIGN) {
string_builder_sprintf(s, "%c=", '0' + CAR_TO_INT(t));
t = t->cdr;
}
}
if(t->car->type != T_VOID)
{
if(arg++) string_builder_strcat(s, ", ");
low_describe_type(s, t->car);
string_builder_strcat(s, " ...");
if (t->type != T_MANY) {
string_builder_sprintf(s, ", @%T", t);
} else {
if(t->car->type != T_VOID)
{
if(arg++) string_builder_strcat(s, ", ");
low_describe_type(s, t->car);
string_builder_strcat(s, " ...");
}
t = t->cdr;
string_builder_sprintf(s, " : %T)", t);
}
string_builder_sprintf(s, " : %T)", t->cdr);
}
break;
}
......@@ -3793,10 +3798,13 @@ static struct pike_type *low_match_types2(struct pike_type *a,
case TWOT(T_MANY, T_MANY):
ret = a;
correct_args=0;
while ((a->type != T_MANY) || (b->type != T_MANY))
while ((a->type == T_FUNCTION) || (b->type == T_FUNCTION))
{
struct pike_type *a_tmp, *b_tmp;
if ((a->type != T_FUNCTION) && (a->type != T_MANY)) break;
if ((b->type != T_FUNCTION) && (b->type != T_MANY)) break;
a_tmp = a->car;
if (a->type == T_FUNCTION)
{
......@@ -3816,6 +3824,12 @@ static struct pike_type *low_match_types2(struct pike_type *a,
if(!(flags & NO_MAX_ARGS))
max_correct_args=correct_args;
}
if ((a->type != T_MANY) || (b->type != T_MANY)) {
/* Handle the generic case. */
return low_match_types(a, b, flags);
}
/* check the 'many' type */
if(b->car->type != T_VOID &&
a->car->type != T_VOID)
......@@ -4536,10 +4550,13 @@ static int low_pike_types_le2(struct pike_type *a, struct pike_type *b,
*
* FIXME: Enforcing of all required arguments?
*/
while((a->type != T_MANY) || (b->type != T_MANY))
while((a->type == T_FUNCTION) || (b->type == T_FUNCTION))
{
struct pike_type *a_tmp, *b_tmp;
if ((a->type != T_FUNCTION) && (a->type != T_MANY)) break;
if ((b->type != T_FUNCTION) && (b->type != T_MANY)) break;
a_tmp = a->car;
if (a->type == T_FUNCTION)
{
......@@ -4565,6 +4582,12 @@ static int low_pike_types_le2(struct pike_type *a, struct pike_type *b,
}
}
}
if ((a->type != T_MANY) || (b->type != T_MANY)) {
/* Handle the generic case. */
return low_pike_types_le(a, b, array_cnt, flags);
}
/* FALLTHRU */
case TWOT(T_MANY, T_MANY):
/* check the 'many' type */
......@@ -4855,6 +4878,9 @@ static int low_get_return_type(struct pike_type *a, struct pike_type *b)
while(a->type == T_FUNCTION) {
a = a->cdr;
}
if (a->type != T_MANY) {
return low_get_return_type(a, mixed_type_string);
}
/* FALLTHRU */
case T_MANY:
a = a->cdr;
......@@ -5553,6 +5579,8 @@ static int low_check_indexing(struct pike_type *type,
;
if (!type) return 0;
if (type->type != T_MANY) return 0;
/* FALLTHRU */
case T_MANY:
......@@ -5618,6 +5646,17 @@ static int low_count_arguments(struct pike_type *q)
num++;
q = q->cdr;
}
if (q->type != T_MANY) {
num2 = low_count_arguments(q);
if (num2 == MAX_INT32) return num2;
if (num2 < 0) {
num += ~num2;
return ~num;
}
return num + num2;
}
/* FALLTHRU */
case T_MANY:
q = q->car;
......@@ -6030,6 +6069,10 @@ struct pike_type *soft_cast(struct pike_type *soft_type,
type_stack_mark();
while((soft_type->type == T_FUNCTION) ||
(orig_type->type == T_FUNCTION)) {
if ((soft_type->type != T_FUNCTION) &&
(soft_type->type != T_MANY)) break;
if ((orig_type->type != T_FUNCTION) &&
(orig_type->type != T_MANY)) break;
if (!(tmp2 = soft_cast(soft_type->car, orig_type->car,
flags ^ SOFT_WEAKER))) {
goto function_cast_fail;
......@@ -8485,6 +8528,11 @@ static void low_make_pike_type(unsigned char *type_string,
low_make_pike_type(*cont, cont);
push_reverse_type(type);
break;
case PIKE_T_FUNCTION_ARG:
low_make_pike_type(type_string+1, cont);
low_make_pike_type(*cont, cont);
push_reverse_type(T_FUNCTION);
break;
case T_FUNCTION:
low_make_function_type(type_string+1, cont);
break;
......
......@@ -62,6 +62,8 @@ enum PIKE_TYPE {
PIKE_T_INT=0,
PIKE_T_FLOAT=1,
PIKE_T_FUNCTION_ARG = 4, /* Only used in type strings. */
/* NB: The reference counted types all have bit 4 set. */
PIKE_T_ARRAY=8,
PIKE_T_MAPPING=9,
......@@ -260,7 +262,11 @@ struct svalue
#define INVALIDATE_SVAL(SVAL) SET_SVAL_TYPE_DC(SVAL, 99) /* an invalid type */
/* NOTE: The t* macros below currently use the old type encoding
/* Macros for generating strings compatible with
* pike_types.cmod:make_pike_type() et al, as well
* as encode.c:decode_type().
*
* NOTE: The t* macros below currently use the old type encoding
* to be compatible with __parse_pike_type() in older
* versions of Pike.
*/
......@@ -275,6 +281,7 @@ struct svalue
#define tFuncV(ARGS,REST,RET) MagictFuncV(RET,REST,ARGS)
#define tFunc(ARGS,RET) MagictFunc(RET,ARGS)
#define tFuncArg(ARG,REST) "\014" ARG REST
#define tTuple(T1,T2) "\364" T1 T2
#define tTriple(T1,T2,T3) tTuple(T1, tTuple(T2, T3))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment