@@ 25,14 25,20 @@ def interpret_num_word(word):
return float(word)
assert word not in "0123456789"
+def const_num(x): return TpIntersection(TpRange(x, x),)
+
def interpret_word(word):
"""Interprets constant values."""
x = interpret_num_word(word)
if x is not None:
- return TpIntersection(TpRange(x, x),)
+ return const_num(x)
elif word[0] == '"': # Constant string.
return ConstStr(word[1:])
+def concat_gen(*gen):
+ for el in gen:
+ yield from el
+
class StackCalc:
"""Calculates types, heart of the implementation, basically."""
@@ 79,6 85,8 @@ class StackCalc:
# Actually calculate the type, return new stack and result.
stack, *tc_code = tp_fun(self, vs, inp)
assert isinstance(stack, list), (val)
+ stack = [(const_num(v) if isinstance(v, (float, int)) else v)
+ for v in stack]
assert_acceptable_vals(tc_code, ".tp_calc output.")
assert_acceptable_vals(stack, inp, rest, code, var)
@@ 98,15 106,12 @@ class StackCalc:
def tp_calc(self, code, vs, stack):
"""Calculates types and also collects the calls again, with their types, some origins."""
- code, inserted = iter(code), []
+ code = iter(code)
while True:
- if len(inserted) > 0: # Next word from inserts.
- word, inserted = inserted[0], inserted[1:]
- else: # Next word from given code.
- word = next(code, None)
- if word is None:
- yield stack
- return
+ word = next(code, None) # Next word, if ran out lastly stack.
+ if word is None:
+ yield stack
+ return
val = interpret_word(word)
if val is not None: # It is a constant value.
@@ 129,7 134,7 @@ class StackCalc:
if raw_fun := getattr(got.val, 'raw_tp_calc', None):
assert getattr(got.val, 'tp_calc', None) is None, "BUG: cannot have both `raw_tp_calc` and `tp_calc`."
plus, stack, *tc_code = raw_fun(self, code, vs, stack)
- inserted = plus + inserted # Can add-in some code.
+ code = concat_gen(plus, code) # Can prepend some code.
else:
stack, *tc_code = self.deal_with_var(got, code, vs, stack)
yield from tc_code