🐐 SVBNVLLA implementation

This commit is contained in:
2026-04-01 12:13:00 +02:00
parent 8e7217c2c7
commit 16e785e8fa
2 changed files with 41 additions and 21 deletions

View File

@@ -54,7 +54,11 @@ def single_num_to_int(i, m):
else:
return NUMERALS[i]
def num_to_int(n, m):
def num_to_int(n, m, s=False):
if n.startswith("-"):
if not s:
raise ValueError("Cannot use negative numbers without 'SVBNVLLA' module")
return -num_to_int(n[1:], m, s)
chars = re.findall(r"[IVXLCDM]_*", n)
if ''.join(chars) != n:
raise ValueError("Invalid numeral", n)
@@ -85,19 +89,23 @@ def num_to_int(n, m):
return sum(nums)
def int_to_num(n, m):
def int_to_num(n, m, s=False):
if n < 0:
if not s:
raise ValueError("Cannot display negative numbers without 'SVBNVLLA' module")
return "-" + int_to_num(-n, m, s)
if n > 3999:
if not m:
raise ValueError(
"Cannot display numbers above 3999 without 'MAGNVM' module"
)
thousands_chars = re.findall(r"[IVXLCDM]_*", int_to_num(n//1000, m))
thousands_chars = re.findall(r"[IVXLCDM]_*", int_to_num(n//1000, m, s))
thousands = ''.join([
"M" if i == "I" else i+"_"
for i in thousands_chars
])
return thousands + int_to_num(n % 1000, m)
return thousands + int_to_num(n % 1000, m, s)
else:
nums = []
while n > 0:
@@ -109,17 +117,17 @@ def int_to_num(n, m):
return ''.join(nums)
def make_string(val, magnvm=False):
def make_string(val, magnvm=False, svbnvlla=False):
if isinstance(val, ValStr):
return val.value()
elif isinstance(val, ValInt):
return int_to_num(val.value(), magnvm)
return int_to_num(val.value(), magnvm, svbnvlla)
elif isinstance(val, ValBool):
return "VERVS" if val.value() else "FALSVS"
elif isinstance(val, ValNul):
return "NVLLVS"
elif isinstance(val, ValList):
inner = ' '.join(make_string(i, magnvm) for i in val.value())
inner = ' '.join(make_string(i, magnvm, svbnvlla) for i in val.value())
return f"[{inner}]"
else:
raise TypeError(f"Cannot display {val!r}")
@@ -225,7 +233,7 @@ class Numeral(Node):
return self.value
def _eval(self, vtable):
return vtable, ValInt(num_to_int(self.value, "MAGNVM" in vtable["#modules"]))
return vtable, ValInt(num_to_int(self.value, "MAGNVM" in vtable["#modules"], "SVBNVLLA" in vtable["#modules"]))
class Bool(Node):
@@ -439,6 +447,8 @@ class UnaryMinus(Node):
return f"(- {self.expr.print()})"
def _eval(self, vtable):
if "SVBNVLLA" not in vtable["#modules"]:
raise ValueError("Cannot use unary minus without 'SVBNVLLA' module")
vtable, val = self.expr.eval(vtable)
return vtable, ValInt(-val.value())
@@ -629,15 +639,16 @@ class BuiltIn(Node):
def _eval(self, vtable):
params = [p.eval(vtable)[1] for p in self.parameters]
magnvm = "MAGNVM" in vtable["#modules"]
svbnvlla = "SVBNVLLA" in vtable["#modules"]
match self.builtin:
case "AVDI_NVMERVS":
return vtable, ValInt(num_to_int(input(), magnvm))
return vtable, ValInt(num_to_int(input(), magnvm, svbnvlla))
case "AVDI":
return vtable, ValStr(input())
case "DICE":
print_string = ' '.join(
make_string(i, magnvm) for i in params
make_string(i, magnvm, svbnvlla) for i in params
)
print(print_string)
return vtable, ValStr(print_string)