🐐 Modulo
This commit is contained in:
63
tests.py
63
tests.py
@@ -136,6 +136,9 @@ arithmetic_tests = [
|
||||
("III * IV", Program([], [ExpressionStatement(BinOp(Numeral("III"), Numeral("IV"), "SYMBOL_TIMES"))]), ValInt(12)),
|
||||
("X / II", Program([], [ExpressionStatement(BinOp(Numeral("X"), Numeral("II"), "SYMBOL_DIVIDE"))]), ValInt(5)),
|
||||
("X / III", Program([], [ExpressionStatement(BinOp(Numeral("X"), Numeral("III"), "SYMBOL_DIVIDE"))]), ValInt(3)), # integer division: 10 // 3 = 3
|
||||
("X RELIQVVM III", Program([], [ExpressionStatement(BinOp(Numeral("X"), Numeral("III"), "KEYWORD_RELIQVVM"))]), ValInt(1)), # 10 % 3 = 1
|
||||
("IX RELIQVVM III", Program([], [ExpressionStatement(BinOp(Numeral("IX"), Numeral("III"), "KEYWORD_RELIQVVM"))]), ValInt(0)), # exact divisor
|
||||
("VII RELIQVVM X", Program([], [ExpressionStatement(BinOp(Numeral("VII"), Numeral("X"), "KEYWORD_RELIQVVM"))]), ValInt(7)), # dividend < divisor
|
||||
("II + III * IV", Program([], [ExpressionStatement(BinOp(Numeral("II"), BinOp(Numeral("III"), Numeral("IV"), "SYMBOL_TIMES"), "SYMBOL_PLUS"))]), ValInt(14)), # precedence: 2 + (3*4) = 14
|
||||
("(II + III) * IV", Program([], [ExpressionStatement(BinOp(BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS"), Numeral("IV"), "SYMBOL_TIMES"))]), ValInt(20)), # parens: (2+3)*4 = 20
|
||||
("CVM SVBNVLLA\n- III", Program([ModuleCall("SVBNVLLA")], [ExpressionStatement(UnaryMinus(Numeral("III")))]), ValInt(-3)), # unary negation
|
||||
@@ -153,7 +156,7 @@ class TestArithmetic(unittest.TestCase):
|
||||
# --- Precedence and associativity ---
|
||||
#
|
||||
# Precedence (lowest → highest):
|
||||
# AVT < ET < (EST, PLVS, MINVS) < (+ -) < (* /) < UMINUS < INDEX
|
||||
# AVT < ET < (EST, DISPAR, PLVS, MINVS) < (+ -) < (* / RELIQVVM) < UMINUS < INDEX
|
||||
|
||||
precedence_tests = [
|
||||
# * binds tighter than -: 10 - (2*3) = 4, not (10-2)*3 = 24
|
||||
@@ -176,6 +179,14 @@ precedence_tests = [
|
||||
("I EST II ET II EST II",
|
||||
Program([], [ExpressionStatement(BinOp(BinOp(Numeral("I"), Numeral("II"), "KEYWORD_EST"), BinOp(Numeral("II"), Numeral("II"), "KEYWORD_EST"), "KEYWORD_ET"))]),
|
||||
ValBool(False)),
|
||||
# + binds tighter than DISPAR: (2+3)!=5 = False, not 2+(3!=5) = type error
|
||||
("II + III DISPAR V",
|
||||
Program([], [ExpressionStatement(BinOp(BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS"), Numeral("V"), "KEYWORD_DISPAR"))]),
|
||||
ValBool(False)),
|
||||
# DISPAR binds tighter than ET: (1!=2) AND (2!=2) = True AND False = False
|
||||
("I DISPAR II ET II DISPAR II",
|
||||
Program([], [ExpressionStatement(BinOp(BinOp(Numeral("I"), Numeral("II"), "KEYWORD_DISPAR"), BinOp(Numeral("II"), Numeral("II"), "KEYWORD_DISPAR"), "KEYWORD_ET"))]),
|
||||
ValBool(False)),
|
||||
# ET binds tighter than AVT: True OR (False AND False) = True
|
||||
("VERITAS AVT FALSITAS ET FALSITAS",
|
||||
Program([], [ExpressionStatement(BinOp(Bool(True), BinOp(Bool(False), Bool(False), "KEYWORD_ET"), "KEYWORD_AVT"))]),
|
||||
@@ -208,6 +219,19 @@ precedence_tests = [
|
||||
("XII / II / III",
|
||||
Program([], [ExpressionStatement(BinOp(BinOp(Numeral("XII"), Numeral("II"), "SYMBOL_DIVIDE"), Numeral("III"), "SYMBOL_DIVIDE"))]),
|
||||
ValInt(2)),
|
||||
# RELIQVVM same precedence as *, /; left-associative: (17 % 5) % 2 = 0
|
||||
("XVII RELIQVVM V RELIQVVM II",
|
||||
Program([], [ExpressionStatement(
|
||||
BinOp(BinOp(Numeral("XVII"), Numeral("V"), "KEYWORD_RELIQVVM"),
|
||||
Numeral("II"), "KEYWORD_RELIQVVM"))]),
|
||||
ValInt(0)),
|
||||
# RELIQVVM binds tighter than +: 2 + (7 % 3) = 3, not (2+7) % 3 = 0
|
||||
("II + VII RELIQVVM III",
|
||||
Program([], [ExpressionStatement(
|
||||
BinOp(Numeral("II"),
|
||||
BinOp(Numeral("VII"), Numeral("III"), "KEYWORD_RELIQVVM"),
|
||||
"SYMBOL_PLUS"))]),
|
||||
ValInt(3)),
|
||||
# left-associativity of AVT: (False OR True) OR False = True
|
||||
("FALSITAS AVT VERITAS AVT FALSITAS",
|
||||
Program([], [ExpressionStatement(BinOp(BinOp(Bool(False), Bool(True), "KEYWORD_AVT"), Bool(False), "KEYWORD_AVT"))]),
|
||||
@@ -719,6 +743,15 @@ comparison_tests = [
|
||||
# NVLLVS coerces to 0 in comparisons
|
||||
("V PLVS NVLLVS", Program([], [ExpressionStatement(BinOp(Numeral("V"), Nullus(), "KEYWORD_PLVS"))]), ValBool(True)),
|
||||
("NVLLVS MINVS V", Program([], [ExpressionStatement(BinOp(Nullus(), Numeral("V"), "KEYWORD_MINVS"))]), ValBool(True)),
|
||||
# DISPAR (not-equal): mirrors EST semantics, negated
|
||||
("I DISPAR II", Program([], [ExpressionStatement(BinOp(Numeral("I"), Numeral("II"), "KEYWORD_DISPAR"))]), ValBool(True)),
|
||||
("I DISPAR I", Program([], [ExpressionStatement(BinOp(Numeral("I"), Numeral("I"), "KEYWORD_DISPAR"))]), ValBool(False)),
|
||||
('"hello" DISPAR "hello"', Program([], [ExpressionStatement(BinOp(String("hello"), String("hello"), "KEYWORD_DISPAR"))]), ValBool(False)),
|
||||
('"hello" DISPAR "world"', Program([], [ExpressionStatement(BinOp(String("hello"), String("world"), "KEYWORD_DISPAR"))]), ValBool(True)),
|
||||
("VERITAS DISPAR FALSITAS", Program([], [ExpressionStatement(BinOp(Bool(True), Bool(False), "KEYWORD_DISPAR"))]), ValBool(True)),
|
||||
("NVLLVS DISPAR NVLLVS", Program([], [ExpressionStatement(BinOp(Nullus(), Nullus(), "KEYWORD_DISPAR"))]), ValBool(False)),
|
||||
# cross-type: an int and a string are never equal
|
||||
('I DISPAR "I"', Program([], [ExpressionStatement(BinOp(Numeral("I"), String("I"), "KEYWORD_DISPAR"))]), ValBool(True)),
|
||||
]
|
||||
|
||||
class TestComparisons(unittest.TestCase):
|
||||
@@ -1431,6 +1464,34 @@ fractio_tests = [
|
||||
]),
|
||||
ValFrac(Fraction(5))
|
||||
),
|
||||
# Modulo on fractions: 7/2 RELIQVVM 3/2 = 1/2 (7/2 / 3/2 = 7/3, floor=2, 7/2 - 3 = 1/2)
|
||||
("CVM FRACTIO\nIIIS RELIQVVM IS",
|
||||
Program([ModuleCall("FRACTIO")], [
|
||||
ExpressionStatement(BinOp(Fractio("IIIS"), Fractio("IS"), "KEYWORD_RELIQVVM"))
|
||||
]),
|
||||
ValFrac(Fraction(1, 2))
|
||||
),
|
||||
# Modulo with mixed operand types: 5/2 RELIQVVM 1 = 1/2
|
||||
("CVM FRACTIO\nIIS RELIQVVM I",
|
||||
Program([ModuleCall("FRACTIO")], [
|
||||
ExpressionStatement(BinOp(Fractio("IIS"), Numeral("I"), "KEYWORD_RELIQVVM"))
|
||||
]),
|
||||
ValFrac(Fraction(1, 2))
|
||||
),
|
||||
# Int operands under FRACTIO still return a fraction: 10 RELIQVVM 3 = 1 (as Fraction)
|
||||
("CVM FRACTIO\nX RELIQVVM III",
|
||||
Program([ModuleCall("FRACTIO")], [
|
||||
ExpressionStatement(BinOp(Numeral("X"), Numeral("III"), "KEYWORD_RELIQVVM"))
|
||||
]),
|
||||
ValFrac(Fraction(1))
|
||||
),
|
||||
# Exact multiple under FRACTIO: 3 RELIQVVM 3/2 = 0
|
||||
("CVM FRACTIO\nIII RELIQVVM IS",
|
||||
Program([ModuleCall("FRACTIO")], [
|
||||
ExpressionStatement(BinOp(Numeral("III"), Fractio("IS"), "KEYWORD_RELIQVVM"))
|
||||
]),
|
||||
ValFrac(Fraction(0))
|
||||
),
|
||||
# String concatenation with fraction
|
||||
("CVM FRACTIO\nDICE(IIIS & \"!\")",
|
||||
Program([ModuleCall("FRACTIO")], [
|
||||
|
||||
Reference in New Issue
Block a user