🐐 Tests
This commit is contained in:
443
tests/11_test_assorted.py
Normal file
443
tests/11_test_assorted.py
Normal file
@@ -0,0 +1,443 @@
|
||||
from tests._helpers import (
|
||||
unittest, parameterized, Fraction, time,
|
||||
run_test, run_compiler_error_test,
|
||||
ArrayIndex, ArraySlice, Bool, BinOp, BuiltIn, DataArray, DataDict, DataRangeArray,
|
||||
Defini, Continva, Designa, DesignaDestructure, DesignaIndex, DumStatement,
|
||||
Erumpe, ExpressionStatement, Fvnctio, ID, InterpolatedString, Invoca,
|
||||
ModuleCall, Nullus, Numeral, PerStatement, Program, Redi, SiStatement,
|
||||
String, TemptaStatement, UnaryMinus, UnaryNot, Fractio, frac_to_fraction,
|
||||
fraction_to_frac, num_to_int, int_to_num, make_string,
|
||||
ValInt, ValStr, ValBool, ValList, ValDict, ValNul, ValFunc, ValFrac,
|
||||
CentvrionError, _RUNTIME_C, _cent_rng,
|
||||
Lexer, Parser, compile_program,
|
||||
os, subprocess, tempfile, StringIO, patch,
|
||||
)
|
||||
|
||||
|
||||
# --- Comments ---
|
||||
|
||||
comment_tests = [
|
||||
# trailing line comment
|
||||
('DIC("hello") // this is ignored', Program([], [ExpressionStatement(BuiltIn("DIC", [String("hello")]))]), ValStr("hello"), "hello\n"),
|
||||
# line comment on its own line before code
|
||||
('// ignored\nDIC("hi")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("hi")]))]), ValStr("hi"), "hi\n"),
|
||||
# inline block comment
|
||||
('DIC(/* ignored */ "hi")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("hi")]))]), ValStr("hi"), "hi\n"),
|
||||
# block comment spanning multiple lines
|
||||
('/* line one\nline two */\nDIC("hi")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("hi")]))]), ValStr("hi"), "hi\n"),
|
||||
# block comment mid-expression
|
||||
("II /* ignored */ + III", Program([], [ExpressionStatement(BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS"))]), ValInt(5)),
|
||||
# line comment after expression (no output)
|
||||
("II + III // ignored", Program([], [ExpressionStatement(BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS"))]), ValInt(5)),
|
||||
# division still works (/ token not confused with //)
|
||||
("X / II", Program([], [ExpressionStatement(BinOp(Numeral("X"), Numeral("II"), "SYMBOL_DIVIDE"))]), ValInt(5)),
|
||||
# multiple line comments
|
||||
('// first\n// second\nDIC("ok")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("ok")]))]), ValStr("ok"), "ok\n"),
|
||||
# comment-only line between two statements
|
||||
('DESIGNA x VT I\n// set y\nDESIGNA y VT II\nx + y',
|
||||
Program([], [Designa(ID("x"), Numeral("I")), Designa(ID("y"), Numeral("II")), ExpressionStatement(BinOp(ID("x"), ID("y"), "SYMBOL_PLUS"))]),
|
||||
ValInt(3)),
|
||||
# blank line between two statements (double newline)
|
||||
('DESIGNA x VT I\n\nDESIGNA y VT II\nx + y',
|
||||
Program([], [Designa(ID("x"), Numeral("I")), Designa(ID("y"), Numeral("II")), ExpressionStatement(BinOp(ID("x"), ID("y"), "SYMBOL_PLUS"))]),
|
||||
ValInt(3)),
|
||||
# multiple comment-only lines between statements
|
||||
('DESIGNA x VT I\n// one\n// two\nDESIGNA y VT III\nx + y',
|
||||
Program([], [Designa(ID("x"), Numeral("I")), Designa(ID("y"), Numeral("III")), ExpressionStatement(BinOp(ID("x"), ID("y"), "SYMBOL_PLUS"))]),
|
||||
ValInt(4)),
|
||||
]
|
||||
|
||||
class TestComments(unittest.TestCase):
|
||||
@parameterized.expand(comment_tests)
|
||||
def test_comments(self, source, nodes, value, output=""):
|
||||
run_test(self, source, nodes, value, output)
|
||||
|
||||
# --- Scope ---
|
||||
|
||||
scope_tests = [
|
||||
# SI: variable assigned in true branch persists in outer scope
|
||||
("SI VERITAS TVNC { DESIGNA r VT X }\nr",
|
||||
Program([], [SiStatement(Bool(True), [Designa(ID("r"), Numeral("X"))], None), ExpressionStatement(ID("r"))]),
|
||||
ValInt(10)),
|
||||
# SI: variable assigned in ALIVD branch persists in outer scope
|
||||
("SI FALSITAS TVNC { DESIGNA r VT X } ALIVD { DESIGNA r VT V }\nr",
|
||||
Program([], [SiStatement(Bool(False), [Designa(ID("r"), Numeral("X"))], [Designa(ID("r"), Numeral("V"))]), ExpressionStatement(ID("r"))]),
|
||||
ValInt(5)),
|
||||
# DVM: variable assigned in body persists after loop exits
|
||||
# x goes 1→2→3→4→5; r tracks x each iteration; loop exits when x==5
|
||||
("DESIGNA x VT I\nDVM x EST V FAC { DESIGNA x VT x + I\nDESIGNA r VT x }\nr",
|
||||
Program([], [
|
||||
Designa(ID("x"), Numeral("I")),
|
||||
DumStatement(BinOp(ID("x"), Numeral("V"), "KEYWORD_EST"), [
|
||||
Designa(ID("x"), BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS")),
|
||||
Designa(ID("r"), ID("x")),
|
||||
]),
|
||||
ExpressionStatement(ID("r")),
|
||||
]),
|
||||
ValInt(5)),
|
||||
# PER: loop variable holds last array element after loop (no ERVMPE)
|
||||
("PER i IN [I, II, III] FAC { DESIGNA nop VT I }\ni",
|
||||
Program([], [
|
||||
PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [Designa(ID("nop"), Numeral("I"))]),
|
||||
ExpressionStatement(ID("i")),
|
||||
]),
|
||||
ValInt(3)),
|
||||
# PER: reassigning loop var in body doesn't prevent remaining iterations from running
|
||||
# cnt increments once per iteration (all 3); C=100 doesn't replace next element assignment
|
||||
("DESIGNA cnt VT I\nPER i IN [I, II, III] FAC { DESIGNA i VT C\nDESIGNA cnt VT cnt + I }\ncnt",
|
||||
Program([], [
|
||||
Designa(ID("cnt"), Numeral("I")),
|
||||
PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [
|
||||
Designa(ID("i"), Numeral("C")),
|
||||
Designa(ID("cnt"), BinOp(ID("cnt"), Numeral("I"), "SYMBOL_PLUS")),
|
||||
]),
|
||||
ExpressionStatement(ID("cnt")),
|
||||
]),
|
||||
ValInt(4)),
|
||||
# PER: loop var after loop reflects the last body assignment, not the last array element
|
||||
# body sets i=C=100 on every iteration; after loop ends, i stays at 100
|
||||
("PER i IN [I, II, III] FAC { DESIGNA i VT C }\ni",
|
||||
Program([], [
|
||||
PerStatement(DataArray([Numeral("I"), Numeral("II"), Numeral("III")]), ID("i"), [Designa(ID("i"), Numeral("C"))]),
|
||||
ExpressionStatement(ID("i")),
|
||||
]),
|
||||
ValInt(100)),
|
||||
# DONICVM: counter holds last range value after loop ends
|
||||
# [I VSQVE IV] = [1,2,3,4]; last value assigned by loop is IV=4
|
||||
("DONICVM i VT I VSQVE IV FAC { DESIGNA nop VT I }\ni",
|
||||
Program([], [
|
||||
PerStatement(DataRangeArray(Numeral("I"), Numeral("IV")), ID("i"), [Designa(ID("nop"), Numeral("I"))]),
|
||||
ExpressionStatement(ID("i")),
|
||||
]),
|
||||
ValInt(4)),
|
||||
# DONICVM: reassigning counter inside body doesn't reduce the number of iterations
|
||||
# range [I VSQVE IV] evaluated once; i reset each time; cnt still increments 4 times → 5
|
||||
("DESIGNA cnt VT I\nDONICVM i VT I VSQVE IV FAC { DESIGNA cnt VT cnt + I\nDESIGNA i VT C }\ncnt",
|
||||
Program([], [
|
||||
Designa(ID("cnt"), Numeral("I")),
|
||||
PerStatement(DataRangeArray(Numeral("I"), Numeral("IV")), ID("i"), [
|
||||
Designa(ID("cnt"), BinOp(ID("cnt"), Numeral("I"), "SYMBOL_PLUS")),
|
||||
Designa(ID("i"), Numeral("C")),
|
||||
]),
|
||||
ExpressionStatement(ID("cnt")),
|
||||
]),
|
||||
ValInt(5)),
|
||||
# DONICVM: ERVMPE exits loop early; counter persists at break value
|
||||
("DONICVM i VT I VSQVE X FAC {\nSI i EST III TVNC { ERVMPE }\n}\ni",
|
||||
Program([], [
|
||||
PerStatement(DataRangeArray(Numeral("I"), Numeral("X")), ID("i"), [
|
||||
SiStatement(BinOp(ID("i"), Numeral("III"), "KEYWORD_EST"), [Erumpe()], None),
|
||||
]),
|
||||
ExpressionStatement(ID("i")),
|
||||
]),
|
||||
ValInt(3)),
|
||||
# Function: modifying parameter inside function does not affect outer variable of same name
|
||||
# outer n=1; f receives n=5 and modifies its local copy; outer n unchanged
|
||||
("DESIGNA n VT I\nDEFINI f (n) VT { DESIGNA n VT n + X\nREDI (n) }\nINVOCA f (V)\nn",
|
||||
Program([], [
|
||||
Designa(ID("n"), Numeral("I")),
|
||||
Defini(ID("f"), [ID("n")], [Designa(ID("n"), BinOp(ID("n"), Numeral("X"), "SYMBOL_PLUS")), Redi([ID("n")])]),
|
||||
ExpressionStatement(Invoca(ID("f"), [Numeral("V")])),
|
||||
ExpressionStatement(ID("n")),
|
||||
]),
|
||||
ValInt(1)),
|
||||
# Function: mutating outer variable inside function (via DESIGNA) is not visible outside
|
||||
# Invoca creates func_vtable = vtable.copy(); mutations to func_vtable don't propagate back
|
||||
("DESIGNA x VT I\nDEFINI f () VT { DESIGNA x VT C\nREDI (x) }\nINVOCA f ()\nx",
|
||||
Program([], [
|
||||
Designa(ID("x"), Numeral("I")),
|
||||
Defini(ID("f"), [], [Designa(ID("x"), Numeral("C")), Redi([ID("x")])]),
|
||||
ExpressionStatement(Invoca(ID("f"), [])),
|
||||
ExpressionStatement(ID("x")),
|
||||
]),
|
||||
ValInt(1)),
|
||||
# Function: two successive calls with same parameter name don't share state
|
||||
("DEFINI f (n) VT { REDI (n * II) }\nINVOCA f (III) + INVOCA f (IV)",
|
||||
Program([], [
|
||||
Defini(ID("f"), [ID("n")], [Redi([BinOp(ID("n"), Numeral("II"), "SYMBOL_TIMES")])]),
|
||||
ExpressionStatement(BinOp(Invoca(ID("f"), [Numeral("III")]), Invoca(ID("f"), [Numeral("IV")]), "SYMBOL_PLUS")),
|
||||
]),
|
||||
ValInt(14)),
|
||||
# Function: calling f(I) with param named n does not overwrite outer n=II
|
||||
# f is defined before n is designated; INVOCA creates a local copy, outer vtable unchanged
|
||||
("DEFINI f (n) VT { REDI (n * II) }\nDESIGNA n VT II\nINVOCA f (I)\nn",
|
||||
Program([], [
|
||||
Defini(ID("f"), [ID("n")], [Redi([BinOp(ID("n"), Numeral("II"), "SYMBOL_TIMES")])]),
|
||||
Designa(ID("n"), Numeral("II")),
|
||||
ExpressionStatement(Invoca(ID("f"), [Numeral("I")])),
|
||||
ExpressionStatement(ID("n")),
|
||||
]),
|
||||
ValInt(2)),
|
||||
]
|
||||
|
||||
class TestScope(unittest.TestCase):
|
||||
@parameterized.expand(scope_tests)
|
||||
def test_scope(self, source, nodes, value):
|
||||
run_test(self, source, nodes, value)
|
||||
|
||||
# --- First-class functions / FVNCTIO ---
|
||||
|
||||
fvnctio_tests = [
|
||||
# Lambda assigned to variable, then called
|
||||
(
|
||||
"DESIGNA f VT FVNCTIO (x) VT { REDI (x + I) }\nINVOCA f (V)",
|
||||
Program([], [
|
||||
Designa(ID("f"), Fvnctio([ID("x")], [Redi([BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS")])])),
|
||||
ExpressionStatement(Invoca(ID("f"), [Numeral("V")])),
|
||||
]),
|
||||
ValInt(6),
|
||||
),
|
||||
# IIFE: immediately invoked lambda
|
||||
(
|
||||
"INVOCA FVNCTIO (x) VT { REDI (x * II) } (III)",
|
||||
Program([], [
|
||||
ExpressionStatement(Invoca(
|
||||
Fvnctio([ID("x")], [Redi([BinOp(ID("x"), Numeral("II"), "SYMBOL_TIMES")])]),
|
||||
[Numeral("III")],
|
||||
)),
|
||||
]),
|
||||
ValInt(6),
|
||||
),
|
||||
# Zero-arg lambda
|
||||
(
|
||||
"INVOCA FVNCTIO () VT { REDI (XLII) } ()",
|
||||
Program([], [
|
||||
ExpressionStatement(Invoca(
|
||||
Fvnctio([], [Redi([Numeral("XLII")])]),
|
||||
[],
|
||||
)),
|
||||
]),
|
||||
ValInt(42),
|
||||
),
|
||||
# Function passed as argument
|
||||
(
|
||||
"DEFINI apply (f, x) VT { REDI (INVOCA f (x)) }\n"
|
||||
"DESIGNA dbl VT FVNCTIO (n) VT { REDI (n * II) }\n"
|
||||
"INVOCA apply (dbl, V)",
|
||||
Program([], [
|
||||
Defini(ID("apply"), [ID("f"), ID("x")], [
|
||||
Redi([Invoca(ID("f"), [ID("x")])])
|
||||
]),
|
||||
Designa(ID("dbl"), Fvnctio([ID("n")], [
|
||||
Redi([BinOp(ID("n"), Numeral("II"), "SYMBOL_TIMES")])
|
||||
])),
|
||||
ExpressionStatement(Invoca(ID("apply"), [ID("dbl"), Numeral("V")])),
|
||||
]),
|
||||
ValInt(10),
|
||||
),
|
||||
# Lambda uses caller-scope variable (copy-caller semantics)
|
||||
(
|
||||
"DESIGNA n VT III\n"
|
||||
"DESIGNA f VT FVNCTIO (x) VT { REDI (x + n) }\n"
|
||||
"INVOCA f (V)",
|
||||
Program([], [
|
||||
Designa(ID("n"), Numeral("III")),
|
||||
Designa(ID("f"), Fvnctio([ID("x")], [
|
||||
Redi([BinOp(ID("x"), ID("n"), "SYMBOL_PLUS")])
|
||||
])),
|
||||
ExpressionStatement(Invoca(ID("f"), [Numeral("V")])),
|
||||
]),
|
||||
ValInt(8),
|
||||
),
|
||||
# Named function passed as value
|
||||
(
|
||||
"DEFINI sqr (x) VT { REDI (x * x) }\n"
|
||||
"DESIGNA f VT sqr\n"
|
||||
"INVOCA f (IV)",
|
||||
Program([], [
|
||||
Defini(ID("sqr"), [ID("x")], [Redi([BinOp(ID("x"), ID("x"), "SYMBOL_TIMES")])]),
|
||||
Designa(ID("f"), ID("sqr")),
|
||||
ExpressionStatement(Invoca(ID("f"), [Numeral("IV")])),
|
||||
]),
|
||||
ValInt(16),
|
||||
),
|
||||
# Nested lambdas
|
||||
(
|
||||
"INVOCA FVNCTIO (x) VT { REDI (INVOCA FVNCTIO (y) VT { REDI (y + I) } (x)) } (V)",
|
||||
Program([], [
|
||||
ExpressionStatement(Invoca(
|
||||
Fvnctio([ID("x")], [
|
||||
Redi([Invoca(
|
||||
Fvnctio([ID("y")], [Redi([BinOp(ID("y"), Numeral("I"), "SYMBOL_PLUS")])]),
|
||||
[ID("x")],
|
||||
)])
|
||||
]),
|
||||
[Numeral("V")],
|
||||
)),
|
||||
]),
|
||||
ValInt(6),
|
||||
),
|
||||
# DIC on a function value
|
||||
(
|
||||
"DESIGNA f VT FVNCTIO (x) VT { REDI (x) }\nDIC(f)",
|
||||
Program([], [
|
||||
Designa(ID("f"), Fvnctio([ID("x")], [Redi([ID("x")])])),
|
||||
ExpressionStatement(BuiltIn("DIC", [ID("f")])),
|
||||
]),
|
||||
ValStr("FVNCTIO"),
|
||||
"FVNCTIO\n",
|
||||
),
|
||||
# Lambda stored in array, called via index
|
||||
(
|
||||
"DESIGNA fns VT [FVNCTIO (x) VT { REDI (x + I) }, FVNCTIO (x) VT { REDI (x * II) }]\n"
|
||||
"INVOCA fns[I] (V)",
|
||||
Program([], [
|
||||
Designa(ID("fns"), DataArray([
|
||||
Fvnctio([ID("x")], [Redi([BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS")])]),
|
||||
Fvnctio([ID("x")], [Redi([BinOp(ID("x"), Numeral("II"), "SYMBOL_TIMES")])]),
|
||||
])),
|
||||
ExpressionStatement(Invoca(
|
||||
ArrayIndex(ID("fns"), Numeral("I")),
|
||||
[Numeral("V")],
|
||||
)),
|
||||
]),
|
||||
ValInt(6),
|
||||
),
|
||||
# Lambda stored in dict, called via key
|
||||
(
|
||||
'DESIGNA d VT TABVLA {"add" VT FVNCTIO (x) VT { REDI (x + I) }}\n'
|
||||
'INVOCA d["add"] (V)',
|
||||
Program([], [
|
||||
Designa(ID("d"), DataDict([
|
||||
(String("add"), Fvnctio([ID("x")], [Redi([BinOp(ID("x"), Numeral("I"), "SYMBOL_PLUS")])])),
|
||||
])),
|
||||
ExpressionStatement(Invoca(
|
||||
ArrayIndex(ID("d"), String("add")),
|
||||
[Numeral("V")],
|
||||
)),
|
||||
]),
|
||||
ValInt(6),
|
||||
),
|
||||
# Multi-param lambda
|
||||
(
|
||||
"DESIGNA add VT FVNCTIO (a, b) VT { REDI (a + b) }\nINVOCA add (III, IV)",
|
||||
Program([], [
|
||||
Designa(ID("add"), Fvnctio([ID("a"), ID("b")], [
|
||||
Redi([BinOp(ID("a"), ID("b"), "SYMBOL_PLUS")])
|
||||
])),
|
||||
ExpressionStatement(Invoca(ID("add"), [Numeral("III"), Numeral("IV")])),
|
||||
]),
|
||||
ValInt(7),
|
||||
),
|
||||
]
|
||||
|
||||
class TestFvnctio(unittest.TestCase):
|
||||
@parameterized.expand(fvnctio_tests)
|
||||
def test_fvnctio(self, source, nodes, value, output=""):
|
||||
run_test(self, source, nodes, value, output)
|
||||
|
||||
# --- Tempta/Cape (try/catch) ---
|
||||
|
||||
tempta_tests = [
|
||||
# Try block succeeds — catch not entered
|
||||
(
|
||||
"TEMPTA {\nDESIGNA r VT I\n} CAPE e {\nDESIGNA r VT II\n}\nr",
|
||||
Program([], [
|
||||
TemptaStatement(
|
||||
[Designa(ID("r"), Numeral("I"))],
|
||||
ID("e"),
|
||||
[Designa(ID("r"), Numeral("II"))],
|
||||
),
|
||||
ExpressionStatement(ID("r")),
|
||||
]),
|
||||
ValInt(1),
|
||||
),
|
||||
# Try block errors — caught by catch
|
||||
(
|
||||
"TEMPTA {\nDESIGNA r VT I / NVLLVS\n} CAPE e {\nDESIGNA r VT II\n}\nr",
|
||||
Program([], [
|
||||
TemptaStatement(
|
||||
[Designa(ID("r"), BinOp(Numeral("I"), Nullus(), "SYMBOL_DIVIDE"))],
|
||||
ID("e"),
|
||||
[Designa(ID("r"), Numeral("II"))],
|
||||
),
|
||||
ExpressionStatement(ID("r")),
|
||||
]),
|
||||
ValInt(2),
|
||||
),
|
||||
# Error variable contains the error message
|
||||
(
|
||||
'DESIGNA e VT NVLLVS\nTEMPTA {\nDESIGNA r VT I / NVLLVS\n} CAPE e {\nNVLLVS\n}\ne',
|
||||
Program([], [
|
||||
Designa(ID("e"), Nullus()),
|
||||
TemptaStatement(
|
||||
[Designa(ID("r"), BinOp(Numeral("I"), Nullus(), "SYMBOL_DIVIDE"))],
|
||||
ID("e"),
|
||||
[ExpressionStatement(Nullus())],
|
||||
),
|
||||
ExpressionStatement(ID("e")),
|
||||
]),
|
||||
ValStr("Division by zero"),
|
||||
),
|
||||
# Nested tempta — inner catches, outer unaffected
|
||||
(
|
||||
"DESIGNA r VT NVLLVS\nTEMPTA {\nTEMPTA {\nDESIGNA r VT I / NVLLVS\n} CAPE e {\nDESIGNA r VT I\n}\n} CAPE e {\nDESIGNA r VT II\n}\nr",
|
||||
Program([], [
|
||||
Designa(ID("r"), Nullus()),
|
||||
TemptaStatement(
|
||||
[TemptaStatement(
|
||||
[Designa(ID("r"), BinOp(Numeral("I"), Nullus(), "SYMBOL_DIVIDE"))],
|
||||
ID("e"),
|
||||
[Designa(ID("r"), Numeral("I"))],
|
||||
)],
|
||||
ID("e"),
|
||||
[Designa(ID("r"), Numeral("II"))],
|
||||
),
|
||||
ExpressionStatement(ID("r")),
|
||||
]),
|
||||
ValInt(1),
|
||||
),
|
||||
# REDI inside catch block
|
||||
(
|
||||
"DEFINI f () VT {\nTEMPTA {\nDESIGNA x VT I / NVLLVS\n} CAPE e {\nREDI (III)\n}\nREDI (IV)\n}\nINVOCA f ()",
|
||||
Program([], [
|
||||
Defini(ID("f"), [], [
|
||||
TemptaStatement(
|
||||
[Designa(ID("x"), BinOp(Numeral("I"), Nullus(), "SYMBOL_DIVIDE"))],
|
||||
ID("e"),
|
||||
[Redi([Numeral("III")])],
|
||||
),
|
||||
Redi([Numeral("IV")]),
|
||||
]),
|
||||
ExpressionStatement(Invoca(ID("f"), [])),
|
||||
]),
|
||||
ValInt(3),
|
||||
),
|
||||
# ERVMPE inside catch block (inside a loop)
|
||||
(
|
||||
"DESIGNA r VT NVLLVS\nDVM r EST I FAC {\nTEMPTA {\nDESIGNA x VT I / NVLLVS\n} CAPE e {\nDESIGNA r VT I\nERVMPE\n}\n}\nr",
|
||||
Program([], [
|
||||
Designa(ID("r"), Nullus()),
|
||||
DumStatement(
|
||||
BinOp(ID("r"), Numeral("I"), "KEYWORD_EST"),
|
||||
[TemptaStatement(
|
||||
[Designa(ID("x"), BinOp(Numeral("I"), Nullus(), "SYMBOL_DIVIDE"))],
|
||||
ID("e"),
|
||||
[Designa(ID("r"), Numeral("I")), Erumpe()],
|
||||
)],
|
||||
),
|
||||
ExpressionStatement(ID("r")),
|
||||
]),
|
||||
ValInt(1),
|
||||
),
|
||||
# Statement after error in try block is not executed
|
||||
(
|
||||
"DESIGNA r VT NVLLVS\nTEMPTA {\nDESIGNA x VT I / NVLLVS\nDESIGNA r VT III\n} CAPE e {\nDESIGNA r VT II\n}\nr",
|
||||
Program([], [
|
||||
Designa(ID("r"), Nullus()),
|
||||
TemptaStatement(
|
||||
[Designa(ID("x"), BinOp(Numeral("I"), Nullus(), "SYMBOL_DIVIDE")),
|
||||
Designa(ID("r"), Numeral("III"))],
|
||||
ID("e"),
|
||||
[Designa(ID("r"), Numeral("II"))],
|
||||
),
|
||||
ExpressionStatement(ID("r")),
|
||||
]),
|
||||
ValInt(2),
|
||||
),
|
||||
]
|
||||
|
||||
class TestTempta(unittest.TestCase):
|
||||
@parameterized.expand(tempta_tests)
|
||||
def test_tempta(self, source, nodes, value, output=""):
|
||||
run_test(self, source, nodes, value, output)
|
||||
Reference in New Issue
Block a user