🐐 Negation
This commit is contained in:
@@ -330,6 +330,18 @@ class BinOp(Node):
|
|||||||
raise Exception(self.op)
|
raise Exception(self.op)
|
||||||
|
|
||||||
|
|
||||||
|
class UnaryMinus(Node):
|
||||||
|
def __init__(self, expr):
|
||||||
|
self.expr = expr
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"UnaryMinus({self.expr!r})"
|
||||||
|
|
||||||
|
def _eval(self, vtable):
|
||||||
|
vtable, val = self.expr.eval(vtable)
|
||||||
|
return vtable, ValInt(-val.value())
|
||||||
|
|
||||||
|
|
||||||
class SiStatement(Node):
|
class SiStatement(Node):
|
||||||
def __init__(self, test, statements, else_part) -> None:
|
def __init__(self, test, statements, else_part) -> None:
|
||||||
self.test = test
|
self.test = test
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ class Parser():
|
|||||||
('left', ["KEYWORD_ET"]),
|
('left', ["KEYWORD_ET"]),
|
||||||
('left', ["KEYWORD_PLVS", "KEYWORD_MINVS", "KEYWORD_EST"]),
|
('left', ["KEYWORD_PLVS", "KEYWORD_MINVS", "KEYWORD_EST"]),
|
||||||
('left', ["SYMBOL_PLUS", "SYMBOL_MINUS"]),
|
('left', ["SYMBOL_PLUS", "SYMBOL_MINUS"]),
|
||||||
('left', ["SYMBOL_TIMES", "SYMBOL_DIVIDE"])
|
('left', ["SYMBOL_TIMES", "SYMBOL_DIVIDE"]),
|
||||||
|
('right', ["UMINUS"]),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -173,6 +174,10 @@ class Parser():
|
|||||||
def binop(tokens):
|
def binop(tokens):
|
||||||
return ast_nodes.BinOp(tokens[0], tokens[2], tokens[1].name)
|
return ast_nodes.BinOp(tokens[0], tokens[2], tokens[1].name)
|
||||||
|
|
||||||
|
@self.pg.production('expression : SYMBOL_MINUS expression', precedence='UMINUS')
|
||||||
|
def unary_minus(tokens):
|
||||||
|
return ast_nodes.UnaryMinus(tokens[1])
|
||||||
|
|
||||||
@self.pg.production('expression : KEYWORD_INVOCA id expressions')
|
@self.pg.production('expression : KEYWORD_INVOCA id expressions')
|
||||||
def invoca(tokens):
|
def invoca(tokens):
|
||||||
return ast_nodes.Invoca(tokens[1], tokens[2])
|
return ast_nodes.Invoca(tokens[1], tokens[2])
|
||||||
|
|||||||
6
tests.py
6
tests.py
@@ -8,7 +8,7 @@ from centvrion.ast_nodes import (
|
|||||||
Bool, BinOp, BuiltIn, DataArray, DataRangeArray, Defini,
|
Bool, BinOp, BuiltIn, DataArray, DataRangeArray, Defini,
|
||||||
Designa, DumStatement, Erumpe, ExpressionStatement, ID,
|
Designa, DumStatement, Erumpe, ExpressionStatement, ID,
|
||||||
Invoca, ModuleCall, Nullus, Numeral, PerStatement,
|
Invoca, ModuleCall, Nullus, Numeral, PerStatement,
|
||||||
Program, Redi, SiStatement, String,
|
Program, Redi, SiStatement, String, UnaryMinus,
|
||||||
num_to_int, int_to_num, make_string,
|
num_to_int, int_to_num, make_string,
|
||||||
)
|
)
|
||||||
from centvrion.lexer import Lexer
|
from centvrion.lexer import Lexer
|
||||||
@@ -105,6 +105,10 @@ arithmetic_tests = [
|
|||||||
("X / III", None, ValInt(3)), # integer division: 10 // 3 = 3
|
("X / III", None, ValInt(3)), # integer division: 10 // 3 = 3
|
||||||
("II + III * IV", None, ValInt(14)), # precedence: 2 + (3*4) = 14
|
("II + III * IV", None, ValInt(14)), # precedence: 2 + (3*4) = 14
|
||||||
("(II + III) * IV", None, ValInt(20)), # parens: (2+3)*4 = 20
|
("(II + III) * IV", None, ValInt(20)), # parens: (2+3)*4 = 20
|
||||||
|
("- III", None, ValInt(-3)), # unary negation
|
||||||
|
("- (II + III)", None, ValInt(-5)), # unary negation of expression
|
||||||
|
("- - II", None, ValInt(2)), # double negation
|
||||||
|
("III + - II", None, ValInt(1)), # unary in binary context
|
||||||
]
|
]
|
||||||
|
|
||||||
class TestArithmetic(unittest.TestCase):
|
class TestArithmetic(unittest.TestCase):
|
||||||
|
|||||||
Reference in New Issue
Block a user