pike.git/
src/
pike_types.cmod
Branch:
Tag:
Non-build tags
All tags
No tags
2020-12-30
2020-12-30 17:36:56 by Henrik Grubbström (Grubba) <grubba@grubba.org>
0b361f9a2b8f5982e4afcfcd81506dd01f468557 (
98
lines) (+
91
/-
7
)
[
Show
|
Annotate
]
Branch:
master
Compiler
[Typechecker]
: Even more fixes for PT_BINOP_MINUS and functions.
4654:
} break; case PT_BINOP_MINUS:
+
/* Subtraction (A - B)
+
*
+
* The result is the subset of function A where at least one
+
* of the arguments or the return type differs from function B.
+
*
+
* T_FUNCTION(A, X) - T_FUNCTION(B, Y) ==
+
* T_OR(T_FUNCTION(A - B, X), T_FUNCTION(A, X - Y))
+
*
+
* T_FUNCTION(A, X) - T_MANY(T_VOID, Y) ==
+
* T_OR(T_FUNCTION(A - T_VOID, X),
+
* T_MANY(T_VOID, X* - Y))
+
*
+
* T_FUNCTION(A, X) - T_MANY(B, Y) ==
+
* T_OR(T_FUNCTION(A - B, X), T_FUNCTION(A, X - MANY(B, Y)))
+
*
+
* T_MANY(T_VOID, X) - T_FUNCTION(B, Y) ==
+
* T_MANY(T_VOID, X) (if B not voidable)
+
* T_MANY(T_VOID, X - Y*) (if B voidable) ==
+
* T_MANY(T_VOID, X) - Y
+
*
+
* T_MANY(A, X) - T_FUNCTION(B, Y) ==
+
* T_OR(T_FUNCTION(A - B, T_MANY(A, X)),
+
* T_FUNCTION(A, T_MANY(A, X) - Y))
+
*
+
* Caveat for the above: Handle the special case where
+
* A - B == T_VOID.
+
*
+
* T_MANY(A, X) - T_MANY(A, Y) == T_MANY(T_VOID, X - Y)
+
*
+
* T_MANY(T_VOID, X) - T_MANY(B, Y) == T_MANY(T_VOID, X - Y)
+
*
+
* T_MANY(A, X) - T_MANY(T_VOID, Y) ==
+
* T_OR(T_FUNCTION(A, T_MANY(A, X)),
+
* T_MANY(T_VOID, X - Y))
+
*
+
* T_MANY(A, X) - T_MANY(~A, Y) == T_MANY(A, X - Y)
+
*
+
* T_MANY(A, X) - T_MANY(B, Y) ==
+
* T_OR(T_MANY(A, X - Y),
+
* T_AND(T_MANY(A, X),
+
* T_NOT(T_MANY(T_NOT(A - B), T_MIXED))))
+
*/
if (avoidable && bvoidable) {
-
+
/* FIXME: What if tmp only differs due to remapping? */
if (tmp != a->car) {
-
if (!tmp)
goto
function
_
fail
;
+
pop_stack_mark();
+
if (!tmp)
{
+
push
_
remap_markers(a->cdr, NULL, remap, remap_flags)
;
+
push_type(T_VOID);
+
push_type(T_MANY);
+
return pop_unfinished_type();
+
}
+
/* FIXME: What about tmp->type == T_VOID? */
+
push_type(T_MIXED);
+
push_finished_type(tmp);
+
push_type(T_NOT);
+
push_type(T_MANY);
+
push_type(T_NOT);
+
push_remap_markers(a, NULL, remap, remap_flags);
+
push_type(T_AND);
free_type(tmp);
-
goto
complex
_
function
;
+
+
tmp
= low
_
type_binop(op, a->cdr, b->cdr, remap,
+
PT_FLAG_CMP_VOIDABLE,
+
0, remap_flags)
;
+
if (tmp) {
+
push_finished_type(tmp);
+
push_remap_markers(a->car, NULL, remap, remap_flags);
+
push_type(T_MANY);
+
push_type(T_OR);
+
free_type(tmp);
}
-
+
return pop_unfinished_type();
+
}
/* Time to check the return types. */
4667:
if (!bret) bret = bi->cdr; /* NB: Ignore the return type if matching against void. */
-
tmp = low_type_binop(op, aret, bret,
NULL
,
+
tmp = low_type_binop(op, aret, bret,
remap
,
PT_FLAG_CMP_VOIDABLE, 0, remap_flags);
4687:
return pop_unfinished_type(); } if (tmp) {
+
if (tmp->type != T_VOID) {
push_remap_markers(ai, NULL, remap, remap_flags); push_finished_type(tmp); push_type(T_FUNCTION);
-
+
} else if (a->type == T_FUNCTION) {
+
push_remap_markers(ai, NULL, remap, remap_flags);
+
if ((ai->type != T_MANY) || (ai->car != T_VOID)) {
+
/* Convert voidable arguments into zero|void
+
* if they must be present for later arguments.
+
*/
+
push_type(T_ZERO);
+
push_type(T_VOID);
+
push_type(T_OR);
+
push_type(T_FUNCTION);
+
}
+
} else {
+
/* a->type == T_MANY */
+
}
free_type(tmp); }
-
tmp = low_type_binop(op, ai, bi,
NULL
, aflags, bflags, remap_flags);
+
tmp = low_type_binop(op, ai, bi,
remap
, aflags, bflags, remap_flags);
if (tmp) { push_finished_type(tmp); push_remap_markers(a->car, NULL, remap, remap_flags);