Added parser support for the 'defer' keyword
This commit is contained in:
parent
16f1ffb7d0
commit
dc7c6b5f6d
|
@ -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 ";";
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Reference in New Issue