From af83d8c0b5c842b2ce2f2f57b1808740f89d1087 Mon Sep 17 00:00:00 2001 From: nocturn9x Date: Fri, 12 Mar 2021 10:10:11 +0100 Subject: [PATCH] Fixed various import issues and improved repr for Call AST nodes --- README.md | 2 +- nimkalc.nimble | 2 +- src/nimkalc.nim | 4 ++-- src/nimkalc/objects/ast.nim | 32 +++++++++++++------------------- 4 files changed, 17 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 349a314..d21b66e 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ All of NimKalc's objects implement the `$` operator and are therefore printable. floats are represented with `Float(x.x)`. Unary operators print as `Unary(operator, right)`, while binary operators print as `Binary(left, operator, right)`. Parenthesized expressions print as `Grouping(expr)`, where `expr` is the expression enclosed in parentheses (as an AST node, obviously). Token objects will print as `Token(kind, lexeme)`: an example for the number 2 would be `Token(Integer, '2')`. Function calls print like `Call(name, args)` -where `name` is the function name and `args` is a `seq[AstNode]` representing the function's arguments +where `name` is the function name and `args` is a list of arguments ## Example diff --git a/nimkalc.nimble b/nimkalc.nimble index d8c21ad..8187313 100644 --- a/nimkalc.nimble +++ b/nimkalc.nimble @@ -1,6 +1,6 @@ # Package -version = "0.2.2" +version = "0.2.3" author = "Mattia Giambirtone" description = "An advanced parsing library for mathematical expressions and equations" license = "Apache 2.0" diff --git a/src/nimkalc.nim b/src/nimkalc.nim index bb48533..03f6889 100644 --- a/src/nimkalc.nim +++ b/src/nimkalc.nim @@ -17,7 +17,7 @@ import nimkalc/parsing/parser import nimkalc/objects/ast import nimkalc/parsing/lexer -import nimkalc/parsing/token +import nimkalc/objects/token import strutils @@ -38,7 +38,7 @@ proc `$`*(self: AstNode): string = of NodeKind.Float: result = &"Float({$self.value})" of NodeKind.Call: - result = &"Call({self.function.name}, {self.arguments})" + result = &"Call({self.function.name}, {self.arguments.join(\", \")})" of NodeKind.Ident: result = &"Identifier({self.name})" diff --git a/src/nimkalc/objects/ast.nim b/src/nimkalc/objects/ast.nim index a533168..cd685de 100644 --- a/src/nimkalc/objects/ast.nim +++ b/src/nimkalc/objects/ast.nim @@ -68,7 +68,7 @@ proc `$`*(self: AstNode): string = of NodeKind.Float: result = &"Float({$self.value})" of NodeKind.Call: - result = &"Call({self.function.name}, {self.arguments})" + result = &"Call({self.function.name}, {self.arguments.join(\", \")})" of NodeKind.Ident: result = &"Identifier({self.name})" @@ -106,6 +106,15 @@ template ensureIntegers(left, right: AstNode) = raise newException(MathError, "an integer is required") +template callFunction(fun: untyped, args: varargs[untyped]) = + ## Handy template to call functions + let r = fun(args) + if r is float: + result = AstNode(kind: NodeKind.Float, value: r) + else: + result = AstNode(kind: NodeKind.Integer, value: float(r)) + + # Forward declarations proc visit_literal(self: NodeVisitor, node: AstNode): AstNode proc visit_unary(self: NodeVisitor, node: AstNode): AstNode @@ -142,27 +151,12 @@ proc visit_literal(self: NodeVisitor, node: AstNode): AstNode = proc visit_call(self: NodeVisitor, node: AstNode): AstNode = ## Visits function call expressions - var args: seq[AstNode] = @[] - for arg in node.arguments: - args.add(self.eval(arg)) if node.function.name == "sin": - let r = sin(args[0].value) - if r is float: - result = AstNode(kind: NodeKind.Float, value: r) - else: - result = AstNode(kind: NodeKind.Integer, value: float(r)) + callFunction(sin, self.eval(node.arguments[0]).value) if node.function.name == "cos": - let r = cos(args[0].value) - if r is float: - result = AstNode(kind: NodeKind.Float, value: r) - else: - result = AstNode(kind: NodeKind.Integer, value: float(r)) + callFunction(cos, self.eval(node.arguments[0]).value) if node.function.name == "tan": - let r = tan(args[0].value) - if r is float: - result = AstNode(kind: NodeKind.Float, value: r) - else: - result = AstNode(kind: NodeKind.Integer, value: float(r)) + callFunction(tan, self.eval(node.arguments[0]).value) proc visit_grouping(self: NodeVisitor, node: AstNode): AstNode =