Added parser support for the 'defer' keyword

This commit is contained in:
Nocturn9x 2021-10-27 18:47:16 +02:00
parent 16f1ffb7d0
commit dc7c6b5f6d
5 changed files with 26 additions and 3 deletions

View File

@ -84,6 +84,7 @@ varDecl → declModifiers? ("var" | | "const") IDENTIFIER ( "=" expressio
statement → exprStmt | forStmt | ifStmt | returnStmt| whileStmt| blockStmt; // The set of all statements
exprStmt → expression ";"; // Any expression followed by a semicolon is technically a statement
returnStmt → "return" expression? ";"; // Returns from a function, illegal in top-level code
deferStmt → "defer" expression ";";
breakStmt → "break" ";";
importStmt -> ("from" IDENTIFIER)? "import" (IDENTIFIER ("as" IDENTIFIER)? ","?)+ ";";
assertStmt → "assert" expression ";";

View File

@ -87,7 +87,7 @@ const keywords = to_table({
"foreach": Foreach, "yield": Yield,
"private": Private, "public": Public,
"static": Static, "dynamic": Dynamic,
"as": As, "of": Of
"as": As, "of": Of, "defer": Defer
})

View File

@ -49,6 +49,7 @@ type
awaitStmt,
fromImportStmt,
importStmt,
deferStmt,
# An expression followed by a semicolon
exprStmt,
# Expressions
@ -212,6 +213,9 @@ type
expression*: ASTNode
body*: ASTNode
DeferStmt* = ref object of ASTNode
deferred*: ASTNode
WhileStmt* = ref object of ASTNode
condition*: ASTNode
body*: ASTNode
@ -448,6 +452,11 @@ proc newAssertStmt*(expression: ASTNode): AssertStmt =
result.expression = expression
proc newDeferStmt*(deferred: ASTNode): DeferStmt =
result = DeferStmt(kind: deferStmt)
result.deferred = deferred
proc newRaiseStmt*(exception: ASTNode): RaiseStmt =
result = RaiseStmt(kind: raiseStmt)
result.exception = exception
@ -626,5 +635,8 @@ proc `$`*(self: ASTNode): string =
of lambdaExpr:
var self = LambdaExpr(self)
result &= &"Lambda(body={self.body}, arguments=[{self.arguments.join(\", \")}], defaults=[{self.defaults.join(\", \")}], generator={self.isGenerator})"
of deferStmt:
var self = DeferStmt(self)
result &= &"Defer({self.deferred})"
else:
discard

View File

@ -38,7 +38,7 @@ type
Return, Async, Class, Import, From,
IsNot, Raise, Assert, Del, Await,
Foreach, Yield, Static, Dynamic,
Private, Public, As, Of
Private, Public, As, Of, Defer
# Basic types

View File

@ -502,6 +502,14 @@ proc breakStmt(self: Parser): ASTNode =
result = newBreakStmt()
proc deferStmt(self: Parser): ASTNode =
## Parses break statements
if self.context != Function:
self.error("'defer' cannot be used outside functions")
result = newDeferStmt(self.expression())
endOfLine("missing semicolon after defer statement")
proc continueStmt(self: Parser): ASTNode =
## Parses break statements
if self.currentLoop != Loop:
@ -891,6 +899,9 @@ proc statement(self: Parser): ASTNode =
of Await:
discard self.step()
result = self.awaitStmt()
of Defer:
discard self.step()
result = self.deferStmt()
else:
result = self.expressionStatement()
@ -963,7 +974,6 @@ proc parse*(self: Parser, tokens: seq[Token], file: string): seq[ASTNode] =
self.tokens = tokens
self.file = file
self.current = 0
self.currentLoop = None
while not self.done():
result.add(self.declaration())