From 0e4eb8255477ac3c565b623afda3650728f11ab0 Mon Sep 17 00:00:00 2001 From: Mattia Giambirtone Date: Thu, 28 Apr 2022 11:50:10 +0200 Subject: [PATCH] Fixed AST inheritance issues and got back to a working state --- src/frontend/meta/ast.nim | 18 ++++++++---------- src/frontend/parser.nim | 10 +++++----- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/frontend/meta/ast.nim b/src/frontend/meta/ast.nim index a487548..5c964d6 100644 --- a/src/frontend/meta/ast.nim +++ b/src/frontend/meta/ast.nim @@ -97,18 +97,16 @@ type # This is not shown when the node is printed, but makes it a heck of a lot easier to report # errors accurately even deep in the compilation pipeline token*: Token - # This weird inheritance chain is just a map of - # our grammar's precedence rules (expressions first, - # then statements and declarations last) - Expression* = ref object of ASTNode - ## An expression - Statement* = ref object of Expression - ## A statement - Declaration* = ref object of Statement + # This weird inheritance chain is needed for the parser to + # work properly + Declaration* = ref object of ASTNode ## A declaration closedOver*: bool pragmas*: seq[Token] - + Statement* = ref object of Declaration + ## A statement + Expression* = ref object of Statement + ## An expression LiteralExpr* = ref object of Expression # Using a string for literals makes it much easier to handle numeric types, as # there is no overflow nor underflow or float precision issues during parsing. @@ -375,7 +373,7 @@ proc newGroupingExpr*(expression: Expression, token: Token): GroupingExpr = result.token = token -proc newLambdaExpr*(arguments: seq[tuple[name: IdentExpr, valueType: IdentExpr]], defaults: seq[Expression], body: Declaration, +proc newLambdaExpr*(arguments: seq[tuple[name: IdentExpr, valueType: IdentExpr]], defaults: seq[Expression], body: Statement, isGenerator: bool, isAsync: bool, token: Token): LambdaExpr = result = LambdaExpr(kind: lambdaExpr) result.body = body diff --git a/src/frontend/parser.nim b/src/frontend/parser.nim index 85e4ecd..2fe1e07 100644 --- a/src/frontend/parser.nim +++ b/src/frontend/parser.nim @@ -320,13 +320,13 @@ proc primary(self: Parser): Expression = result = newInfExpr(self.step()) of Function: discard self.step() - result = self.funDecl(isLambda=true) + result = Expression(self.funDecl(isLambda=true)) of Coroutine: discard self.step() - result = self.funDecl(isAsync=true, isLambda=true) + result = Expression(self.funDecl(isAsync=true, isLambda=true)) of Generator: discard self.step() - result = self.funDecl(isGenerator=true, isLambda=true) + result = Expression(self.funDecl(isGenerator=true, isLambda=true)) else: self.error("invalid syntax") @@ -773,7 +773,7 @@ proc forStmt(self: Parser): Statement = if increment != nil: # The increment runs after each iteration, so we # inject it into the block as the last statement - body = newBlockStmt(@[Declaration(body), Declaration(Expression(newExprStmt(increment, increment.token)))], tok) + body = newBlockStmt(@[Declaration(body), newExprStmt(increment, increment.token)], tok) if condition == nil: ## An empty condition is functionally ## equivalent to "true" @@ -894,7 +894,7 @@ proc funDecl(self: Parser, isAsync: bool = false, isGenerator: bool = false, isL self.currentFunction = enclosingFunction return result elif isLambda: - self.currentFunction = Declaration(Expression(newLambdaExpr(arguments, defaults, Declaration(Statement(newBlockStmt(@[], Token()))), isGenerator=isGenerator, isAsync=isAsync, token=tok))) + self.currentFunction = newLambdaExpr(arguments, defaults, newBlockStmt(@[], Token()), isGenerator=isGenerator, isAsync=isAsync, token=tok) elif not isOperator: self.error("funDecl: invalid state") if self.match(Colon):