diff --git a/elys.nim b/elys.nim index 087524a..4d238ea 100644 --- a/elys.nim +++ b/elys.nim @@ -11,10 +11,7 @@ var x = 10 var y = 20 print(x + y, 2 + 2 * 2 / 10 * .1) -x += 2 -x += 2 -x += 2 -x *= 2 +x *= -2 print x print 7 / 3 diff --git a/modules/ast.nim b/modules/ast.nim index d21c4be..9a84613 100644 --- a/modules/ast.nim +++ b/modules/ast.nim @@ -112,6 +112,9 @@ proc floatAst*(val: float): FloatAST = FloatAST(val: val, kind: akFloat) proc stringAst*(val: string): StringAST = StringAST(val: val, kind: akString) proc boolAst*(val: bool): BoolAST = BoolAST(val: val, kind: akBool) +proc unaryOpAst*(expr: ASTRoot, op: string): UnaryOpAST = + UnaryOpAST(expr: expr, op: op) + proc varAst*(val: string): VarAST = VarAST(name: val, kind: akVar) proc binOpAst*(l, r: ASTRoot, op: string): BinOpAST = BinOpAST(l: l, r: r, op: op, kind: akBinOp) @@ -233,6 +236,16 @@ method eval*(self: VarAST, env: Environment): ASTRoot = raise newException(RuntimeError, "Variable " & self.name & " was not assigned before") env.vars[self.name].val +method eval*(self: UnaryOpAST, env: Environment): ASTRoot = + let val = self.expr.eval(env) + if val.kind == akInt: + val.IntAST.val = -val.IntAST.val + return val + elif val.kind == akFloat: + val.FloatAST.val = -val.FloatAST.val + return val + raise newException(RuntimeError, "Can not to apply unary operator '" & self.op & "' to " & $self.expr) + method eval*(self: StmtList, env: Environment): ASTRoot = var environment = newEnv(env) for s in self.statements: diff --git a/modules/parser.nim b/modules/parser.nim index e3f78ca..16532b3 100644 --- a/modules/parser.nim +++ b/modules/parser.nim @@ -49,7 +49,8 @@ let @["+", "-", "%"] ] relationalOperators = @["==", "!=", ">=", "<=", "<", ">"] - unaryOperators = @["--", "++", "-"] + incDecOperators = @["--", "++"] + unaryOperators = @["-"] assignOperators = @["//=", "+=", "-=", "*=", "/=", "="] bExprPrecedenceLevels = @[ @["and", "&&"], @@ -65,6 +66,9 @@ proc processVar(res: Result): Option[Result] = astRes(varAst(res.val.get)) proc processGroup(res: Result): Option[Result] = res.valx.valy.some +proc unaryOperatorStmt(): Combinator + + proc aExprValue(): Combinator = ( (intNumber ^ processIntNumber) | @@ -86,7 +90,8 @@ proc aExprGroup(): Combinator = proc aExprTerm(): Combinator = ( aExprValue() | - aExprGroup() + aExprGroup() | + unaryOperatorStmt() ) proc processBinOp(res: Result): Option[Result] = @@ -166,6 +171,14 @@ proc processEof(res: Result): Option[Result] = astRes(eofStmt()) +proc processUnaryOperatorStmt(res: Result): Option[Result] = + echo res + astRes(unaryOpAst(res.valy.ast, res.valx.val.get)) +proc unaryOperatorStmt(): Combinator = + # x = -x + (anyOpInList(unaryOperators) + lazy(aExpr)) ^ processUnaryOperatorStmt + + proc stmt(): Combinator = ( printStmt() |