-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
go: Implement break statement #30
Conversation
firebase-deployment: https://evy-lang--30-p7ccr9tp.web.app (9f848d0) |
Fix bare returns in evaluator as they accidentally got ignored and didn't stop execution.
cfc77fe
to
381f744
Compare
Fix while.AlwaysReturn() logic to always return false as a loop could not be executing its body even once which would then not result in a return even if the body itself always returns. This was an initial oversight, now fixed.
438204a
to
402065e
Compare
46081d4
to
8d3859a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
some comments for now
pkg/parser/parser.go
Outdated
p.advance() // advance past IF token | ||
scope = newInnerScope(scope) | ||
condition := p.parseCondition(scope) | ||
scope = scope.innerScope(ifStmt) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure this is right. The block should be the conditional block, not the if block. the if has multiple blocks and they do not share the scope. they each have their own.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a new scope is created, each time, just always containing the same outer block == ifStmt.
It is confusing I can see this, but otherwise it doesn't line up with the else statement.
I cannot have the block create its own scope, because in the case of the While .block
has to be the While statement (I suppose I could, but again unnecessary extra scoping).
I've updated this now so that the conditional block creates a new block (which means there is an unnecessary extra scope for the while, but I guess that's ok).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still feel a bit wrong about this because of the asymmetry between the else branch and the if | if-else branches.
9326db8
to
dda68b9
Compare
Add containing block Node to scope. This is a preparatory step for break statement parsing to ensure that the break statement is within a loop.
107cbcf
to
2c0aed6
Compare
Refactor alwaysReturns to alwaysTerminates as a non-functional change and pure rename. This is another preparatory step for implementing break statements as breaks interrupt the flow like returns but _are not_ returns. It will be used as follows: while true if true return else break end print "unreachable" end We can now use AlwaysTerminates instead of AlwaysReturns to also check that a function with return specified type always returns, because loop statements _never_ always terminated, as the loop body could be executed 0 times.
fa5593d
to
46140c4
Compare
Implement break statement in parser and evaluator ensuring it is only used inside a loop. Use scope to keep track of enclosing AST node and ensure that break's scope is within a loop, a *While AST node. Implement unreachable code with block.AlwaysTerminates method on block. AlwaysTerminates means there is either a `return` or `break` statement within all paths of the loop body. All code following is unreachable. E.g.: while true if true return else break end print "unreachable" end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Quite the marathon, but this now LGTM! 🎉
🟢
Implement break statement in parser and evaluator ensuring it is only
used inside a loop. Use scope to keep track of enclosing AST node and
ensure that break's scope is within a loop (while) node's scope.
Implement unreachable code with block.AlwaysTerminates method on block.
Fix bare returns in evaluator as they accidentally got ignored and
didn't stop execution. This became apparent when thinking about breaks
in evaluator.
Also, fix AlwaysReturns method on While blocks. Loops may at times never
have their body executed so can never always return.