diff options
author | Austin Clements <aclements@csail.mit.edu> | 2009-07-30 14:39:27 -0700 |
---|---|---|
committer | Austin Clements <aclements@csail.mit.edu> | 2009-07-30 14:39:27 -0700 |
commit | 96e1969da9cb424435bd31f2c912b15ce6e89fa1 (patch) | |
tree | 2fe900def247d1d92afe550b73763aeacf10a07f /usr/austin/eval/compiler.go | |
parent | 6a40b7b0896e5de398a9e1af52d244621a1a56e4 (diff) | |
download | golang-96e1969da9cb424435bd31f2c912b15ce6e89fa1.tar.gz |
Implement labels, goto, labeled break, and labeled continue.
Return checking is now done as a general flow check at the end
of function compilation, since break and goto complicated the
way I was doing return checking before. Goto-over-declaration
checking is also done as a final flow check.
Temporary variables used for effect extraction are now
actually temporary. Otherwise "op=", "++", and "--" appear as
declarations that cannot be jumped over.
R=rsc
APPROVED=rsc
DELTA=421 (344 added, 38 deleted, 39 changed)
OCL=32527
CL=32535
Diffstat (limited to 'usr/austin/eval/compiler.go')
-rw-r--r-- | usr/austin/eval/compiler.go | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/usr/austin/eval/compiler.go b/usr/austin/eval/compiler.go index 641e6a293..59858c800 100644 --- a/usr/austin/eval/compiler.go +++ b/usr/austin/eval/compiler.go @@ -44,7 +44,27 @@ func (a *compiler) compileFuncType(b *block, typ *ast.FuncType) *FuncDecl func (a *compiler) compileArrayLen(b *block, expr ast.Expr) (int64, bool) +type label struct { + name string; + desc string; + // The PC goto statements should jump to, or nil if this label + // cannot be goto'd (such as an anonymous for loop label). + gotoPC *uint; + // The PC break statements should jump to, or nil if a break + // statement is invalid. + breakPC *uint; + // The PC continue statements should jump to, or nil if a + // continue statement is invalid. + continuePC *uint; + // The position where this label was resolved. If it has not + // been resolved yet, an invalid position. + resolved token.Position; + // The position where this label was first jumped to. + used token.Position; +} + type codeBuf struct +type flowBuf struct type FuncType struct // A funcCompiler captures information used throughout the compilation // of a single function body. @@ -55,22 +75,21 @@ type funcCompiler struct { // kinds of return statements are legal. outVarsNamed bool; *codeBuf; + flow *flowBuf; + labels map[string] *label; err bool; } +func (a *funcCompiler) checkLabels() // A blockCompiler captures information used throughout the compilation // of a single block within a function. type blockCompiler struct { *funcCompiler; block *block; - returned bool; - // The PC break statements should jump to, or nil if a break - // statement is invalid. - breakPC *uint; - // The PC continue statements should jump to, or nil if a - // continue statement is invalid. - continuePC *uint; + // The label of this block, used for finding break and + // continue labels. + label *label; // The blockCompiler for the block enclosing this one, or nil // for a function-level block. parent *blockCompiler; |