Fixed various import issues and improved repr for Call AST nodes

This commit is contained in:
nocturn9x 2021-03-12 10:10:11 +01:00
parent cc09ddf3c5
commit af83d8c0b5
4 changed files with 17 additions and 23 deletions

View File

@ -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

View File

@ -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"

View File

@ -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})"

View File

@ -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 =