This commit is contained in:
NikolajDanger
2022-06-08 13:08:19 +02:00
parent 2dfbb33213
commit 912c46ab7c
5 changed files with 121 additions and 19 deletions

View File

@@ -19,7 +19,7 @@ DEFINI fib x UT {
} ALUID SI x EST I TUNC {
REDI I
} ALUID {
REDI (INVOCA fib (x-II) + INVOCA fib (x-I))
REDI ((INVOCA fib (x-II)) + (INVOCA fib (x-I)))
}
}
```
@@ -30,13 +30,13 @@ DEFINI fib x UT {
VOCA FORS
DESIGNA correct UT FORTIS_NUMERUS I C
DESIGNA guess UT NULLUS
DESIGNA gvess UT NULLUS
DUM FALSITAS FACE {
DESIGNA guess UT AUDI_NUMERUS
SI guess MINUS correct TUNC {
DESIGNA gvess UT AUDI_NUMERUS
SI gvess MINUS correct TUNC {
DICE "Too low!"
} ALUID SI guess PLUS correct TUNC {
} ALUID SI gvess PLUS correct TUNC {
DICE "Too high!"
} ALUID {
ERUMPE
@@ -170,8 +170,8 @@ SI x ET y TUNC {
### DONICUM loops
```
DESIGNA x UT NULLUM
DONICUM y UT NULLUM USQUE X FACE {
DESIGNA x UT NULLUS
DONICUM y UT NULLUS USQUE X FACE {
DESIGNA x UT x + y
}
DICE x
@@ -181,7 +181,7 @@ DICE x
### DUM loops
```
DESIGNA x UT NULLUM
DESIGNA x UT NULLUS
DUM x PLUS X FACE {
DESIGNA x UT x+I
}

View File

@@ -23,6 +23,7 @@ def rep_join(l):
return format_string
# TODO: Magnum
def num_to_int(n):
return roman.fromRoman(n)
@@ -31,6 +32,8 @@ def make_string(n):
return n
elif isinstance(n, int):
return roman.toRoman(n)
elif isinstance(n, list):
return f"[{' '.join([make_string(i) for i in n])}]"
else:
raise Exception(n)
@@ -45,6 +48,31 @@ class ExpressionStatement(BaseBox):
self.expression.eval(vtable.copy(), ftable.copy(), modules)
return vtable, ftable
class DataArray(BaseBox):
def __init__(self, content) -> None:
self.content = content
def __repr__(self) -> str:
content_string = rep_join(self.content)
return f"Array([{content_string}])"
def eval(self, vtable, ftable, modules):
content = [i.eval(vtable, ftable, modules) for i in self.content]
return content
class DataRangeArray(BaseBox):
def __init__(self, from_value, to_value) -> None:
self.from_value = from_value
self.to_value = to_value
def __repr__(self) -> str:
content_string = rep_join([self.from_value, self.to_value])
return f"RangeArray([{content_string}])"
def eval(self, vtable, ftable, modules):
content = list(range(self.from_value.eval(), self.to_value.eval()))
return content
class String(BaseBox):
def __init__(self, value) -> None:
self.value = value
@@ -122,7 +150,7 @@ class Defini(BaseBox):
)
return f"Defini({def_string})"
def eval(self, vtable, ftable, modules):
def eval(self, vtable, ftable, _):
ftable[self.name.name] = (
self.parameters, self.statements
)
@@ -180,6 +208,11 @@ class BinOp(BaseBox):
return left + right
case "SYMBOL_MINUS":
return left - right
case "SYMBOL_TIMES":
return left * right
case "SYMBOL_DIVIDE":
# TODO: Fractio
return left // right
case "KEYWORD_MINUS":
return left < right
case "KEYWORD_PLUS":
@@ -242,6 +275,37 @@ class DumStatement(BaseBox):
return vtable, ftable
class PerStatement(BaseBox):
def __init__(self, data_list, variable_name, statements) -> None:
self.data_list = data_list
self.variable_name = variable_name
self.statements = statements
def __repr__(self) -> str:
test = repr(self.data_list)
variable_name = repr(self.variable_name)
statements = f"statements([{rep_join(self.statements)}])"
dum_string = rep_join([test, variable_name, statements])
return f"Per({dum_string})"
def eval(self, vtable, ftable, modules):
data_array = self.data_list.eval(vtable, ftable, modules)
variable_name = self.variable_name.name
for i in data_array:
vtable[variable_name] = i
for statement in self.statements:
vtable, ftable = statement.eval(
vtable, ftable, modules
)
if vtable["ERUMPE"]:
break
if vtable["ERUMPE"]:
vtable["ERUMPE"] = False
break
return vtable, ftable
class Invoca(BaseBox):
def __init__(self, name, parameters) -> None:
self.name = name
@@ -294,6 +358,7 @@ class BuiltIn(BaseBox):
vtable["ERUMPE"] = True
return None
case "FORTIS_NUMERUS":
# TODO: Fors
return random.randint(parameters[0], parameters[1])
case _:
raise Exception(self.builtin)

View File

@@ -13,6 +13,7 @@ keyword_tokens = [("KEYWORD_"+i, i) for i in [
"FACE",
"FALSITAS",
"INVOCA",
"IN",
"MINUS",
"NULLUS",
"PER",

24
main.py
View File

@@ -2,18 +2,23 @@ from lexer import Lexer
from parser import Parser
text_input = """
DEFINI fib x UT {
SI x EST NULLUS TUNC {
REDI NULLUS
} ALUID SI x EST I TUNC {
REDI I
VOCA FORS
DESIGNA correct UT FORTIS_NUMERUS I C
DESIGNA gvess UT NULLUS
DUM FALSITAS FACE {
DESIGNA gvess UT AUDI_NUMERUS
SI gvess MINUS correct TUNC {
DICE "Too low!"
} ALUID SI gvess PLUS correct TUNC {
DICE "Too high!"
} ALUID {
REDI ((INVOCA fib (x-II)) + (INVOCA fib (x-I)))
ERUMPE
}
}
DICE "Input n:"
DICE (INVOCA fib AUDI_NUMERUS)
DICE "You guessed correctly!"
"""
lexer = Lexer().get_lexer()
@@ -22,6 +27,9 @@ pg.parse()
parser = pg.get_parser()
tokens = lexer.lex(text_input)
#for token in tokens:
# print(token)
x = parser.parse(tokens)
#print(x)
x.eval()

View File

@@ -1,3 +1,4 @@
from multiprocessing.dummy import Array
from rply import ParserGenerator
from lexer import all_tokens
@@ -7,7 +8,13 @@ ALL_TOKENS = list(set([i[0] for i in all_tokens]))
class Parser():
def __init__(self):
self.pg = ParserGenerator(ALL_TOKENS)
self.pg = ParserGenerator(
ALL_TOKENS,
precedence=[
('left', ["SYMBOL_PLUS", "SYMBOL_MINUS"]),
('left', ["SYMBOL_TIMES", "SYMBOL_DIVIDE"])
]
)
def parse(self):
@self.pg.production('program : opt_newline module_calls statements')
@@ -94,6 +101,8 @@ class Parser():
@self.pg.production('expression : expression SYMBOL_MINUS expression')
@self.pg.production('expression : expression SYMBOL_PLUS expression')
@self.pg.production('expression : expression SYMBOL_TIMES expression')
@self.pg.production('expression : expression SYMBOL_DIVIDE expression')
@self.pg.production('expression : expression KEYWORD_EST expression')
@self.pg.production('expression : expression KEYWORD_MINUS expression')
@self.pg.production('expression : expression KEYWORD_PLUS expression')
@@ -116,8 +125,10 @@ class Parser():
def si_statement(tokens):
return tokens[0]
@self.pg.production('statement : per_statement')
@self.pg.production('statement : dum_statement')
def dum_statement(tokens):
@self.pg.production('statement : donicum_statement')
def loops(tokens):
return tokens[0]
@self.pg.production('statement : KEYWORD_ERUMPE')
@@ -132,6 +143,15 @@ class Parser():
def dum(tokens):
return ast_nodes.DumStatement(tokens[1], tokens[5])
@self.pg.production('per_statement : KEYWORD_PER id KEYWORD_IN expression KEYWORD_FACE SYMBOL_LCURL opt_newline statements opt_newline SYMBOL_RCURL')
def per(tokens):
return ast_nodes.PerStatement(tokens[3], tokens[1], tokens[7])
@self.pg.production('donicum_statement : KEYWORD_DONICUM id KEYWORD_UT expression KEYWORD_USQUE expression KEYWORD_FACE SYMBOL_LCURL opt_newline statements opt_newline SYMBOL_RCURL')
def donicum(tokens):
range_array = ast_nodes.DataRangeArray(tokens[3], tokens[5])
return ast_nodes.PerStatement(range_array, tokens[1], tokens[9])
@self.pg.production('aluid_statement : ')
def aluid_empty(_):
return None
@@ -148,6 +168,14 @@ class Parser():
def parens(tokens):
return tokens[1]
@self.pg.production('expression : SYMBOL_LBRACKET expressions SYMBOL_RBRACKET')
def array(tokens):
return ast_nodes.DataArray(tokens[1])
@self.pg.production('expression : SYMBOL_LBRACKET expression KEYWORD_USQUE expression SYMBOL_RBRACKET')
def range_array(tokens):
return ast_nodes.DataRangeArray(tokens[1], tokens[3])
@self.pg.error
def error_handle(token):
raise ValueError(token)