pike.git/
src/
pike_types.cmod
Branch:
Tag:
Non-build tags
All tags
No tags
2022-04-10
2022-04-10 12:04:48 by Henrik Grubbström (Grubba) <grubba@grubba.org>
8c0c8efd39aa6ddeeb67feca60226ad5ae2abe9e (
123
lines) (+
85
/-
38
)
[
Show
|
Annotate
]
Branch:
master
Compiler
[Typechecker]
: Improved BINOP_MINUS for functions.
5533:
* ==> Ø # Full overlap * * B - A == Ø && X - Y == Z # Argument overlap
-
* ==> T_FUNCTION(A, Z)
+
* ==> T_FUNCTION(A, Z)
# (Recurse)
* * B - A == B ==> T_FUNCTION(A, X) # No overlap
-
+
* # No need to recurse
*
-
* B - A == C ==> T_FUNCTION(A, X)
&
#
Partial
overlap
-
*
~
T_FUNCTION(
B
,
Y
)
+
* B - A == C
&& X - Y
==
Z # Partial overlap
+
* ==
> T_FUNCTION(A
- B
, X)
|
#
Keep
and
+
* T_FUNCTION(
A
,
Z
)
# Recurse
*
-
+
* T_FUNCTION(A - B, X) | T_FUNCTION(A, X - Y)
+
*
* T_MANY analogous with T_MANY substituted for T_FUNCTION above. */
5561:
/* Common case */ tmp = NULL; } else {
-
/* FIXME: Use implicit nullable only for legacy types. */
+
/* FIXME: Use implicit nullable only for legacy types.
+
*
FIXME: What about PT_FLAG_CMP_VOID_IS_NULL?
+
*
/
tmp = low_type_binop(PT_BINOP_MINUS, bi->car, ai->car, remap, bvoidable | PT_FLAG_CMP_NULLABLE | PT_FLAG_CMP_INSEPARABLE, avoidable | PT_FLAG_CMP_NULLABLE | PT_FLAG_CMP_INSEPARABLE, remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS); if (tmp) {
-
+
/* No or not full overlap. */
+
if ((ai->car == void_type_string) && (tmp != bi->car) && (aflags & PT_FLAG_CMP_IGNORE_EXTRA_ARGS)) { /* End of argument list for a, and it is valid to end the
5576:
free_type(tmp); tmp = NULL; } else {
-
push_finished_type(ai);
-
/* FIXME: What
if
tmp differs due to remapping? */
-
if
(tmp
!
= bi->car) {
-
/*
Some
overlap. */
-
push
_
finished
_
type
(
bi
);
-
push
_type(
T_NOT
);
-
push
_
type
(
T_AND
);
+
if (tmp =
=
bi->car) {
+
/*
Common
case, no
overlap. */
+
pop
_
stack
_
mark
();
+
free
_type(
tmp
);
+
add
_
ref
(
ai
);
+
return ai;
} free_type(tmp);
-
return
pop_
unfinished
_type();
+
+
tmp
= low_type_binop(PT_BINOP_MINUS, ai->car, bi->car, remap,
+
avoidable | PT_FLAG_CMP_NULLABLE | PT_FLAG_CMP_INSEPARABLE,
+
bvoidable | PT_FLAG_CMP_NULLABLE | PT_FLAG_CMP_INSEPARABLE,
+
remap_flags);
+
+
if (tmp == ai->car) {
+
/* No overlap.
+
*
+
* The first overlap test likely failed due
+
* to remapping.
+
*/
+
pop_
stack
_
mark();
+
free_
type(
tmp
);
+
add_ref(ai);
+
return ai;
}
-
+
+
push_finished_type(ai->cdr);
+
push_finished_type(tmp);
+
push_type(ai->type);
+
free_type(tmp);
+
tmp = NULL;
} }
-
+
}
/* Advance to the next argument. */ if (ai->type == T_FUNCTION) {
5601:
if (aret) { Pike_fatal("Unsupported type operation.\n"); }
-
break;
+
} if ((bi->type != T_FUNCTION) && (bi->type != T_MANY)) { if (bret) { Pike_fatal("Unsupported type operation.\n"); }
-
break;
+
} if (avoidable && bvoidable) {
5625:
push_finished_type(a->car); push_type(T_MANY); free_type(tmp);
-
return
pop
_
unfinished_
type();
+
}
else
{
+
push
_type(
PIKE_T_UNKNOWN
);
}
-
pop_stack_mark();
-
return NULL;
-
}
-
+
}
else
{
/* Recurse. */ tmp = low_type_binop(PT_BINOP_MINUS, ai, bi, remap, aflags, bflags, remap_flags); if (tmp) { push_finished_type(tmp);
-
push_finished_type(
ai
->car);
+
push_finished_type(
a
->car);
push_type(PIKE_T_FUNCTION); free_type(tmp);
-
return
pop
_
unfinished_
type();
+
}
else {
+
push
_type(
PIKE_T_UNKNOWN
);
}
-
pop_stack_mark();
-
return NULL;
+
}
-
+
while (peek_stack_mark() > 1) {
+
push_type(T_OR);
+
}
+
return pop_unfinished_type();
+
default: /* Fall back to complex_function below. */ break; } complex_function:
-
+
/* Either of ai and/or bi is a complex type. */
-
nargs = peek_stack_mark();
+
if (op != PT_BINOP_AND) {
-
nargs
=
0
;
-
ai
=
a;
-
bi
=
b
;
+
compiler_discard_type();
+
type_stack_mark()
;
+
+
push_remap_markers(b,
remap,
+
remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS);
+
push_remap_markers(
a
, remap, remap_flags)
;
+
+
push_binop(op);
+
+
return pop_unfinished_type()
;
}
-
/*
Either
of
a
and/or
b
is
a
complex
type
.
*/
+
nargs = peek_stack_mark();
+
if ((ai && (ai->type == PIKE_T_TRANSITIVE)) ||
+
(bi && (bi->type == PIKE_T_TRANSITIVE))) {
+
/*
Expand
ai
and/or
bi.
*/
+
tmp =
+
low_
type
_binop(op,
ai, bi, remap, aflags, bflags, remap_flags);
+
push_finished_type(tmp);
+
free_type(tmp);
+
} else {
push_remap_markers(bi, remap, remap_flags ^ PT_FLAG_REMAP_SWAP_MARKERS); push_remap_markers(ai, remap, remap_flags); push_binop(op);
-
+
}
while (nargs--) { push_reverse_type(T_FUNCTION);