mirror of https://github.com/nocturn9x/nimkalc.git
Fixed various import issues and improved repr for Call AST nodes
This commit is contained in:
parent
cc09ddf3c5
commit
af83d8c0b5
|
@ -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)`.
|
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).
|
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)`
|
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
|
## Example
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.2.2"
|
version = "0.2.3"
|
||||||
author = "Mattia Giambirtone"
|
author = "Mattia Giambirtone"
|
||||||
description = "An advanced parsing library for mathematical expressions and equations"
|
description = "An advanced parsing library for mathematical expressions and equations"
|
||||||
license = "Apache 2.0"
|
license = "Apache 2.0"
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
import nimkalc/parsing/parser
|
import nimkalc/parsing/parser
|
||||||
import nimkalc/objects/ast
|
import nimkalc/objects/ast
|
||||||
import nimkalc/parsing/lexer
|
import nimkalc/parsing/lexer
|
||||||
import nimkalc/parsing/token
|
import nimkalc/objects/token
|
||||||
|
|
||||||
|
|
||||||
import strutils
|
import strutils
|
||||||
|
@ -38,7 +38,7 @@ proc `$`*(self: AstNode): string =
|
||||||
of NodeKind.Float:
|
of NodeKind.Float:
|
||||||
result = &"Float({$self.value})"
|
result = &"Float({$self.value})"
|
||||||
of NodeKind.Call:
|
of NodeKind.Call:
|
||||||
result = &"Call({self.function.name}, {self.arguments})"
|
result = &"Call({self.function.name}, {self.arguments.join(\", \")})"
|
||||||
of NodeKind.Ident:
|
of NodeKind.Ident:
|
||||||
result = &"Identifier({self.name})"
|
result = &"Identifier({self.name})"
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ proc `$`*(self: AstNode): string =
|
||||||
of NodeKind.Float:
|
of NodeKind.Float:
|
||||||
result = &"Float({$self.value})"
|
result = &"Float({$self.value})"
|
||||||
of NodeKind.Call:
|
of NodeKind.Call:
|
||||||
result = &"Call({self.function.name}, {self.arguments})"
|
result = &"Call({self.function.name}, {self.arguments.join(\", \")})"
|
||||||
of NodeKind.Ident:
|
of NodeKind.Ident:
|
||||||
result = &"Identifier({self.name})"
|
result = &"Identifier({self.name})"
|
||||||
|
|
||||||
|
@ -106,6 +106,15 @@ template ensureIntegers(left, right: AstNode) =
|
||||||
raise newException(MathError, "an integer is required")
|
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
|
# Forward declarations
|
||||||
proc visit_literal(self: NodeVisitor, node: AstNode): AstNode
|
proc visit_literal(self: NodeVisitor, node: AstNode): AstNode
|
||||||
proc visit_unary(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 =
|
proc visit_call(self: NodeVisitor, node: AstNode): AstNode =
|
||||||
## Visits function call expressions
|
## Visits function call expressions
|
||||||
var args: seq[AstNode] = @[]
|
|
||||||
for arg in node.arguments:
|
|
||||||
args.add(self.eval(arg))
|
|
||||||
if node.function.name == "sin":
|
if node.function.name == "sin":
|
||||||
let r = sin(args[0].value)
|
callFunction(sin, self.eval(node.arguments[0]).value)
|
||||||
if r is float:
|
|
||||||
result = AstNode(kind: NodeKind.Float, value: r)
|
|
||||||
else:
|
|
||||||
result = AstNode(kind: NodeKind.Integer, value: float(r))
|
|
||||||
if node.function.name == "cos":
|
if node.function.name == "cos":
|
||||||
let r = cos(args[0].value)
|
callFunction(cos, self.eval(node.arguments[0]).value)
|
||||||
if r is float:
|
|
||||||
result = AstNode(kind: NodeKind.Float, value: r)
|
|
||||||
else:
|
|
||||||
result = AstNode(kind: NodeKind.Integer, value: float(r))
|
|
||||||
if node.function.name == "tan":
|
if node.function.name == "tan":
|
||||||
let r = tan(args[0].value)
|
callFunction(tan, self.eval(node.arguments[0]).value)
|
||||||
if r is float:
|
|
||||||
result = AstNode(kind: NodeKind.Float, value: r)
|
|
||||||
else:
|
|
||||||
result = AstNode(kind: NodeKind.Integer, value: float(r))
|
|
||||||
|
|
||||||
|
|
||||||
proc visit_grouping(self: NodeVisitor, node: AstNode): AstNode =
|
proc visit_grouping(self: NodeVisitor, node: AstNode): AstNode =
|
||||||
|
|
Loading…
Reference in New Issue