summaryrefslogtreecommitdiff
path: root/usr/austin/eval/compiler.go
diff options
context:
space:
mode:
authorAustin Clements <aclements@csail.mit.edu>2009-07-30 14:39:27 -0700
committerAustin Clements <aclements@csail.mit.edu>2009-07-30 14:39:27 -0700
commit96e1969da9cb424435bd31f2c912b15ce6e89fa1 (patch)
tree2fe900def247d1d92afe550b73763aeacf10a07f /usr/austin/eval/compiler.go
parent6a40b7b0896e5de398a9e1af52d244621a1a56e4 (diff)
downloadgolang-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.go33
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;