🐐 NVLLVUS fix
This commit is contained in:
@@ -133,8 +133,11 @@ def int_to_num(n, m, s=False) -> str:
|
|||||||
for i in thousands_chars
|
for i in thousands_chars
|
||||||
])
|
])
|
||||||
|
|
||||||
return thousands + int_to_num(n % 1000, m, s)
|
remainder = n % 1000
|
||||||
|
return thousands + (int_to_num(remainder, m, s) if remainder else "")
|
||||||
else:
|
else:
|
||||||
|
if n == 0:
|
||||||
|
return "NVLLVS"
|
||||||
nums = []
|
nums = []
|
||||||
while n > 0:
|
while n > 0:
|
||||||
for num, i in list(NUMERALS.items())[::-1]:
|
for num, i in list(NUMERALS.items())[::-1]:
|
||||||
@@ -779,8 +782,14 @@ class BinOp(Node):
|
|||||||
raise CentvrionError("Cannot compare strings or arrays with PLVS")
|
raise CentvrionError("Cannot compare strings or arrays with PLVS")
|
||||||
return vtable, ValBool((lv or 0) > (rv or 0))
|
return vtable, ValBool((lv or 0) > (rv or 0))
|
||||||
case "KEYWORD_EST":
|
case "KEYWORD_EST":
|
||||||
|
if ((isinstance(left, ValInt) and lv == 0 and isinstance(right, ValNul)) or
|
||||||
|
(isinstance(left, ValNul) and isinstance(right, ValInt) and rv == 0)):
|
||||||
|
return vtable, ValBool(True)
|
||||||
return vtable, ValBool(lv == rv)
|
return vtable, ValBool(lv == rv)
|
||||||
case "KEYWORD_DISPAR":
|
case "KEYWORD_DISPAR":
|
||||||
|
if ((isinstance(left, ValInt) and lv == 0 and isinstance(right, ValNul)) or
|
||||||
|
(isinstance(left, ValNul) and isinstance(right, ValInt) and rv == 0)):
|
||||||
|
return vtable, ValBool(False)
|
||||||
return vtable, ValBool(lv != rv)
|
return vtable, ValBool(lv != rv)
|
||||||
case "KEYWORD_ET":
|
case "KEYWORD_ET":
|
||||||
return vtable, ValBool(bool(left) and bool(right))
|
return vtable, ValBool(bool(left) and bool(right))
|
||||||
|
|||||||
@@ -177,8 +177,12 @@ static void transform_thousands(const char *src, char *dst, size_t dstsz) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cent_int_to_roman(long n, char *buf, size_t bufsz) {
|
void cent_int_to_roman(long n, char *buf, size_t bufsz) {
|
||||||
if (n <= 0 || (n > 3999 && !cent_magnvm))
|
if (n == 0) {
|
||||||
cent_runtime_error("number out of range for Roman numerals (1-3999)");
|
if (bufsz > 6) { memcpy(buf, "NVLLVS", 6); buf[6] = '\0'; }
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (n < 0 || (n > 3999 && !cent_magnvm))
|
||||||
|
cent_runtime_error("number out of range for Roman numerals");
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
if (n > 3999) {
|
if (n > 3999) {
|
||||||
char base[64];
|
char base[64];
|
||||||
@@ -480,6 +484,9 @@ CentValue cent_mod_frac(CentValue a, CentValue b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CentValue cent_eq(CentValue a, CentValue b) {
|
CentValue cent_eq(CentValue a, CentValue b) {
|
||||||
|
if ((a.type == CENT_INT && a.ival == 0 && b.type == CENT_NULL) ||
|
||||||
|
(a.type == CENT_NULL && b.type == CENT_INT && b.ival == 0))
|
||||||
|
return cent_bool(1);
|
||||||
if ((a.type == CENT_INT || a.type == CENT_FRAC) &&
|
if ((a.type == CENT_INT || a.type == CENT_FRAC) &&
|
||||||
(b.type == CENT_INT || b.type == CENT_FRAC)) {
|
(b.type == CENT_INT || b.type == CENT_FRAC)) {
|
||||||
long an, ad, bn, bd;
|
long an, ad, bn, bd;
|
||||||
|
|||||||
17
tests.py
17
tests.py
@@ -881,7 +881,7 @@ class TestNumerals(unittest.TestCase):
|
|||||||
|
|
||||||
# int_to_num: valid cases
|
# int_to_num: valid cases
|
||||||
def test_int_to_num(self):
|
def test_int_to_num(self):
|
||||||
for n, s in [(1,"I"),(4,"IV"),(9,"IX"),(40,"XL"),(42,"XLII"),(3999,"MMMCMXCIX")]:
|
for n, s in [(0,"NVLLVS"),(1,"I"),(4,"IV"),(9,"IX"),(40,"XL"),(42,"XLII"),(3999,"MMMCMXCIX")]:
|
||||||
self.assertEqual(int_to_num(n, False), s)
|
self.assertEqual(int_to_num(n, False), s)
|
||||||
|
|
||||||
def test_int_to_num_above_3999_raises(self):
|
def test_int_to_num_above_3999_raises(self):
|
||||||
@@ -907,6 +907,9 @@ class TestMakeString(unittest.TestCase):
|
|||||||
def test_int(self):
|
def test_int(self):
|
||||||
self.assertEqual(make_string(ValInt(3)), "III")
|
self.assertEqual(make_string(ValInt(3)), "III")
|
||||||
|
|
||||||
|
def test_int_zero(self):
|
||||||
|
self.assertEqual(make_string(ValInt(0)), "NVLLVS")
|
||||||
|
|
||||||
def test_bool_true(self):
|
def test_bool_true(self):
|
||||||
self.assertEqual(make_string(ValBool(True)), "VERITAS")
|
self.assertEqual(make_string(ValBool(True)), "VERITAS")
|
||||||
|
|
||||||
@@ -939,6 +942,8 @@ dic_type_tests = [
|
|||||||
('DIC("")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("")]))]), ValStr(""), "\n"),
|
('DIC("")', Program([], [ExpressionStatement(BuiltIn("DIC", [String("")]))]), ValStr(""), "\n"),
|
||||||
# arithmetic result printed as numeral
|
# arithmetic result printed as numeral
|
||||||
("DIC(II + III)", Program([], [ExpressionStatement(BuiltIn("DIC", [BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS")]))]), ValStr("V"), "V\n"),
|
("DIC(II + III)", Program([], [ExpressionStatement(BuiltIn("DIC", [BinOp(Numeral("II"), Numeral("III"), "SYMBOL_PLUS")]))]), ValStr("V"), "V\n"),
|
||||||
|
# integer 0 prints as NVLLVS
|
||||||
|
("DIC(I - I)", Program([], [ExpressionStatement(BuiltIn("DIC", [BinOp(Numeral("I"), Numeral("I"), "SYMBOL_MINUS")]))]), ValStr("NVLLVS"), "NVLLVS\n"),
|
||||||
# multiple args of mixed types
|
# multiple args of mixed types
|
||||||
('DIC("x", VERITAS)', Program([], [ExpressionStatement(BuiltIn("DIC", [String("x"), Bool(True)]))]), ValStr("x VERITAS"), "x VERITAS\n"),
|
('DIC("x", VERITAS)', Program([], [ExpressionStatement(BuiltIn("DIC", [String("x"), Bool(True)]))]), ValStr("x VERITAS"), "x VERITAS\n"),
|
||||||
]
|
]
|
||||||
@@ -1062,6 +1067,8 @@ interpolation_tests = [
|
|||||||
Program([], [
|
Program([], [
|
||||||
ExpressionStatement(InterpolatedString([String("value: "), Nullus()]))
|
ExpressionStatement(InterpolatedString([String("value: "), Nullus()]))
|
||||||
]), ValStr("value: NVLLVS")),
|
]), ValStr("value: NVLLVS")),
|
||||||
|
# integer 0 interpolates as NVLLVS
|
||||||
|
('"value: {I - I}"', Program([], [ExpressionStatement(InterpolatedString([String("value: "), BinOp(Numeral("I"), Numeral("I"), "SYMBOL_MINUS")]))]), ValStr("value: NVLLVS")),
|
||||||
# expression-only string (no literal parts around it)
|
# expression-only string (no literal parts around it)
|
||||||
('DESIGNA x VT "hi"\n"{x}"',
|
('DESIGNA x VT "hi"\n"{x}"',
|
||||||
Program([], [
|
Program([], [
|
||||||
@@ -1194,6 +1201,14 @@ comparison_tests = [
|
|||||||
("NVLLVS DISPAR NVLLVS", Program([], [ExpressionStatement(BinOp(Nullus(), Nullus(), "KEYWORD_DISPAR"))]), ValBool(False)),
|
("NVLLVS DISPAR NVLLVS", Program([], [ExpressionStatement(BinOp(Nullus(), Nullus(), "KEYWORD_DISPAR"))]), ValBool(False)),
|
||||||
# cross-type: an int and a string are never equal
|
# cross-type: an int and a string are never equal
|
||||||
('I DISPAR "I"', Program([], [ExpressionStatement(BinOp(Numeral("I"), String("I"), "KEYWORD_DISPAR"))]), ValBool(True)),
|
('I DISPAR "I"', Program([], [ExpressionStatement(BinOp(Numeral("I"), String("I"), "KEYWORD_DISPAR"))]), ValBool(True)),
|
||||||
|
# integer 0 equals NVLLVS
|
||||||
|
("(I - I) EST NVLLVS", Program([], [ExpressionStatement(BinOp(BinOp(Numeral("I"), Numeral("I"), "SYMBOL_MINUS"), Nullus(), "KEYWORD_EST"))]), ValBool(True)),
|
||||||
|
("NVLLVS EST (I - I)", Program([], [ExpressionStatement(BinOp(Nullus(), BinOp(Numeral("I"), Numeral("I"), "SYMBOL_MINUS"), "KEYWORD_EST"))]), ValBool(True)),
|
||||||
|
("(I - I) DISPAR NVLLVS", Program([], [ExpressionStatement(BinOp(BinOp(Numeral("I"), Numeral("I"), "SYMBOL_MINUS"), Nullus(), "KEYWORD_DISPAR"))]), ValBool(False)),
|
||||||
|
("NVLLVS DISPAR (I - I)", Program([], [ExpressionStatement(BinOp(Nullus(), BinOp(Numeral("I"), Numeral("I"), "SYMBOL_MINUS"), "KEYWORD_DISPAR"))]), ValBool(False)),
|
||||||
|
# non-zero integer does not equal NVLLVS
|
||||||
|
("I EST NVLLVS", Program([], [ExpressionStatement(BinOp(Numeral("I"), Nullus(), "KEYWORD_EST"))]), ValBool(False)),
|
||||||
|
("NVLLVS DISPAR I", Program([], [ExpressionStatement(BinOp(Nullus(), Numeral("I"), "KEYWORD_DISPAR"))]), ValBool(True)),
|
||||||
]
|
]
|
||||||
|
|
||||||
class TestComparisons(unittest.TestCase):
|
class TestComparisons(unittest.TestCase):
|
||||||
|
|||||||
Reference in New Issue
Block a user