mirror of https://github.com/nocturn9x/nimkalc.git
Beautified code and moved visitor methods to camelCase naming convention
This commit is contained in:
parent
e92e40b6ea
commit
81e95feea4
|
@ -73,7 +73,6 @@ proc `$`*(self: AstNode): string =
|
|||
result = &"Identifier({self.name})"
|
||||
|
||||
|
||||
|
||||
proc initNodeVisitor*(): NodeVisitor =
|
||||
## Initializes a node visitor
|
||||
new(result)
|
||||
|
@ -97,7 +96,8 @@ template ensureNonZero(node: AstNode) =
|
|||
of NodeKind.Float, NodeKind.Integer:
|
||||
raise newException(MathError, "value can't be zero")
|
||||
else:
|
||||
raise newException(CatchableError, &"invalid node kind '{node.kind}' for ensureNonZero")
|
||||
raise newException(CatchableError,
|
||||
&"invalid node kind '{node.kind}' for ensureNonZero")
|
||||
|
||||
|
||||
template ensurePositive(node: AstNode) =
|
||||
|
@ -107,7 +107,8 @@ template ensurePositive(node: AstNode) =
|
|||
of NodeKind.Float, NodeKind.Integer:
|
||||
raise newException(MathError, "value must be positive")
|
||||
else:
|
||||
raise newException(CatchableError, &"invalid node kind '{node.kind}' for ensureNonZero")
|
||||
raise newException(CatchableError,
|
||||
&"invalid node kind '{node.kind}' for ensureNonZero")
|
||||
|
||||
|
||||
template ensureIntegers(left, right: AstNode) =
|
||||
|
@ -126,11 +127,11 @@ template callFunction(fun: untyped, args: varargs[untyped]) =
|
|||
|
||||
|
||||
# Forward declarations
|
||||
proc visit_literal(self: NodeVisitor, node: AstNode): AstNode
|
||||
proc visit_unary(self: NodeVisitor, node: AstNode): AstNode
|
||||
proc visit_binary(self: NodeVisitor, node: AstNode): AstNode
|
||||
proc visit_grouping(self: NodeVisitor, node: AstNode): AstNode
|
||||
proc visit_call(self: NodeVisitor, node: AstNode): AstNode
|
||||
proc visitLiteral(self: NodeVisitor, node: AstNode): AstNode
|
||||
proc visitUnary(self: NodeVisitor, node: AstNode): AstNode
|
||||
proc visitBinary(self: NodeVisitor, node: AstNode): AstNode
|
||||
proc visitGrouping(self: NodeVisitor, node: AstNode): AstNode
|
||||
proc visitCall(self: NodeVisitor, node: AstNode): AstNode
|
||||
|
||||
|
||||
proc accept(self: AstNode, visitor: NodeVisitor): AstNode =
|
||||
|
@ -138,15 +139,15 @@ proc accept(self: AstNode, visitor: NodeVisitor): AstNode =
|
|||
## for our AST visitor
|
||||
case self.kind:
|
||||
of NodeKind.Integer, NodeKind.Float, NodeKind.Ident:
|
||||
result = visitor.visit_literal(self)
|
||||
result = visitor.visitLiteral(self)
|
||||
of NodeKind.Binary:
|
||||
result = visitor.visit_binary(self)
|
||||
result = visitor.visitBinary(self)
|
||||
of NodeKind.Unary:
|
||||
result = visitor.visit_unary(self)
|
||||
result = visitor.visitUnary(self)
|
||||
of NodeKind.Grouping:
|
||||
result = visitor.visit_grouping(self)
|
||||
result = visitor.visitGrouping(self)
|
||||
of NodeKind.Call:
|
||||
result = visitor.visit_call(self)
|
||||
result = visitor.visitCall(self)
|
||||
|
||||
|
||||
proc eval*(self: NodeVisitor, node: AstNode): AstNode =
|
||||
|
@ -154,12 +155,12 @@ proc eval*(self: NodeVisitor, node: AstNode): AstNode =
|
|||
result = node.accept(self)
|
||||
|
||||
|
||||
proc visit_literal(self: NodeVisitor, node: AstNode): AstNode =
|
||||
proc visitLiteral(self: NodeVisitor, node: AstNode): AstNode =
|
||||
## Visits a literal AST node (such as integers)
|
||||
result = node # Not that we can do anything else after all, lol
|
||||
|
||||
|
||||
proc visit_call(self: NodeVisitor, node: AstNode): AstNode =
|
||||
proc visitCall(self: NodeVisitor, node: AstNode): AstNode =
|
||||
## Visits function call expressions
|
||||
case node.function.name:
|
||||
of "sin":
|
||||
|
@ -175,7 +176,8 @@ proc visit_call(self: NodeVisitor, node: AstNode): AstNode =
|
|||
of "log":
|
||||
let arg = self.eval(node.arguments[0])
|
||||
ensureNonZero(arg)
|
||||
callFunction(log, self.eval(node.arguments[0]).value, self.eval(node.arguments[1]).value)
|
||||
callFunction(log, self.eval(node.arguments[0]).value, self.eval(
|
||||
node.arguments[1]).value)
|
||||
of "ln":
|
||||
let arg = self.eval(node.arguments[0])
|
||||
ensureNonZero(arg)
|
||||
|
@ -209,10 +211,11 @@ proc visit_call(self: NodeVisitor, node: AstNode): AstNode =
|
|||
of "arccosh":
|
||||
callFunction(arccosh, self.eval(node.arguments[0]).value)
|
||||
of "hypot":
|
||||
callFunction(hypot, self.eval(node.arguments[0]).value, self.eval(node.arguments[1]).value)
|
||||
callFunction(hypot, self.eval(node.arguments[0]).value, self.eval(
|
||||
node.arguments[1]).value)
|
||||
|
||||
|
||||
proc visit_grouping(self: NodeVisitor, node: AstNode): AstNode =
|
||||
proc visitGrouping(self: NodeVisitor, node: AstNode): AstNode =
|
||||
## Visits grouping (i.e. parenthesized) expressions. Parentheses
|
||||
## have no other meaning than to allow a lower-precedence expression
|
||||
## where a higher-precedence one is expected so that 2 * (3 + 1) is
|
||||
|
@ -220,7 +223,7 @@ proc visit_grouping(self: NodeVisitor, node: AstNode): AstNode =
|
|||
return self.eval(node.expr)
|
||||
|
||||
|
||||
proc visit_binary(self: NodeVisitor, node: AstNode): AstNode =
|
||||
proc visitBinary(self: NodeVisitor, node: AstNode): AstNode =
|
||||
## Visits a binary AST node and evaluates it
|
||||
let right = self.eval(node.right)
|
||||
let left = self.eval(node.left)
|
||||
|
@ -236,7 +239,8 @@ proc visit_binary(self: NodeVisitor, node: AstNode): AstNode =
|
|||
# Modulo is a bit special since we must have integers
|
||||
ensureIntegers(left, right)
|
||||
ensureNonZero(right)
|
||||
result = AstNode(kind: NodeKind.Integer, value: float(int(left.value) mod int(right.value)))
|
||||
result = AstNode(kind: NodeKind.Integer, value: float(int(
|
||||
left.value) mod int(right.value)))
|
||||
of TokenType.Exp:
|
||||
result = handleBinary(left, right, pow)
|
||||
of TokenType.Mul:
|
||||
|
@ -245,7 +249,7 @@ proc visit_binary(self: NodeVisitor, node: AstNode): AstNode =
|
|||
discard # Unreachable
|
||||
|
||||
|
||||
proc visit_unary(self: NodeVisitor, node: AstNode): AstNode =
|
||||
proc visitUnary(self: NodeVisitor, node: AstNode): AstNode =
|
||||
## Visits unary expressions and evaluates them
|
||||
let expr = self.eval(node.operand)
|
||||
case node.unOp.kind:
|
||||
|
|
|
@ -35,7 +35,8 @@ type
|
|||
const arities = to_table({"sin": 1, "cos": 1, "tan": 1, "cosh": 1,
|
||||
"tanh": 1, "sinh": 1, "arccos": 1, "arcsin": 1,
|
||||
"arctan": 1, "log": 2, "log10": 1, "ln": 1, "log2": 1,
|
||||
"hypot": 2, "sqrt": 1, "cbrt": 2, "arctanh": 1, "arcsinh": 1,
|
||||
"hypot": 2, "sqrt": 1, "cbrt": 2, "arctanh": 1,
|
||||
"arcsinh": 1,
|
||||
"arccosh": 1
|
||||
})
|
||||
|
||||
|
@ -160,7 +161,8 @@ proc call(self: Parser): AstNode =
|
|||
arguments.add(self.binary())
|
||||
while self.match(TokenType.Comma):
|
||||
arguments.add(self.binary())
|
||||
result = AstNode(kind: NodeKind.Call, arguments: arguments, function: expression)
|
||||
result = AstNode(kind: NodeKind.Call, arguments: arguments,
|
||||
function: expression)
|
||||
if expression.kind != NodeKind.Ident:
|
||||
self.error(&"can't call object of type {expression.kind}")
|
||||
if len(arguments) != arities[expression.name]:
|
||||
|
@ -175,7 +177,8 @@ proc unary(self: Parser): AstNode =
|
|||
## Parses unary expressions such as -1
|
||||
case self.step().kind:
|
||||
of TokenType.Minus, TokenType.Plus:
|
||||
result = AstNode(kind: NodeKind.Unary, unOp: self.previous(), operand: self.unary())
|
||||
result = AstNode(kind: NodeKind.Unary, unOp: self.previous(),
|
||||
operand: self.unary())
|
||||
else:
|
||||
result = self.call()
|
||||
|
||||
|
@ -186,7 +189,8 @@ proc pow(self: Parser): AstNode =
|
|||
var operator: Token
|
||||
while self.match(TokenType.Exp):
|
||||
operator = self.previous()
|
||||
result = AstNode(kind: NodeKind.Binary, left: result, right: self.unary(), binOp: operator)
|
||||
result = AstNode(kind: NodeKind.Binary, left: result, right: self.unary(),
|
||||
binOp: operator)
|
||||
|
||||
|
||||
proc mul(self: Parser): AstNode =
|
||||
|
@ -196,7 +200,8 @@ proc mul(self: Parser): AstNode =
|
|||
var operator: Token
|
||||
while self.match(TokenType.Div, TokenType.Modulo, TokenType.Mul):
|
||||
operator = self.previous()
|
||||
result = AstNode(kind: NodeKind.Binary, left: result, right: self.pow(), binOp: operator)
|
||||
result = AstNode(kind: NodeKind.Binary, left: result, right: self.pow(),
|
||||
binOp: operator)
|
||||
|
||||
|
||||
proc addition(self: Parser): AstNode =
|
||||
|
@ -205,7 +210,8 @@ proc addition(self: Parser): AstNode =
|
|||
var operator: Token
|
||||
while self.match(TokenType.Plus, TokenType.Minus):
|
||||
operator = self.previous()
|
||||
result = AstNode(kind: NodeKind.Binary, left: result, right: self.mul(), binOp: operator)
|
||||
result = AstNode(kind: NodeKind.Binary, left: result, right: self.mul(),
|
||||
binOp: operator)
|
||||
|
||||
|
||||
proc binary(self: Parser): AstNode =
|
||||
|
|
Loading…
Reference in New Issue