@@ -144,10 +144,39 @@ func CompileAst(Ast ast.Ast, filename string, flags int, dont_inherit bool) *py.
144144 return code
145145}
146146
147+ // Loop
148+ type loop struct {
149+ Start * Label
150+ End * Label
151+ IsForLoop bool
152+ }
153+
154+ // Loopstack
155+ type loopstack []loop
156+
157+ // Push a loop
158+ func (ls * loopstack ) Push (l loop ) {
159+ * ls = append (* ls , l )
160+ }
161+
162+ // Pop a loop
163+ func (ls * loopstack ) Pop () {
164+ * ls = (* ls )[:len (* ls )- 1 ]
165+ }
166+
167+ // Return current loop or nil for none
168+ func (ls loopstack ) Top () * loop {
169+ if len (ls ) == 0 {
170+ return nil
171+ }
172+ return & ls [len (ls )- 1 ]
173+ }
174+
147175// State for the compiler
148176type compiler struct {
149177 Code * py.Code // code being built up
150178 OpCodes Instructions
179+ loops loopstack
151180}
152181
153182// Compiles a python constant
@@ -318,6 +347,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
318347 endpopblock := new (Label )
319348 c .Jump (vm .SETUP_LOOP , endpopblock )
320349 while := c .NewLabel ()
350+ c .loops .Push (loop {Start : while , End : endpopblock })
321351 c .Expr (node .Test )
322352 c .Jump (vm .POP_JUMP_IF_FALSE , endwhile )
323353 for _ , stmt := range node .Body {
@@ -326,6 +356,7 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
326356 c .Jump (vm .JUMP_ABSOLUTE , while )
327357 c .Label (endwhile )
328358 c .Op (vm .POP_BLOCK )
359+ c .loops .Pop ()
329360 for _ , stmt := range node .Orelse {
330361 c .Stmt (stmt )
331362 }
@@ -407,9 +438,22 @@ func (c *compiler) Stmt(stmt ast.Stmt) {
407438 case * ast.Pass :
408439 // Do nothing
409440 case * ast.Break :
410- panic ("FIXME compile: Break not implemented" )
441+ l := c .loops .Top ()
442+ if l == nil {
443+ panic (py .ExceptionNewf (py .SyntaxError , "'break' outside loop" ))
444+ }
445+ c .Op (vm .BREAK_LOOP )
411446 case * ast.Continue :
412- panic ("FIXME compile: Continue not implemented" )
447+ l := c .loops .Top ()
448+ if l == nil {
449+ panic (py .ExceptionNewf (py .SyntaxError , "'continue' not properly in loop" ))
450+ }
451+ if l .IsForLoop {
452+ panic (py .ExceptionNewf (py .SyntaxError , "FIXME continue in for loop not implemented" , stmt ))
453+ c .OpArg (vm .CONTINUE_LOOP , 0 )
454+ } else {
455+ c .Jump (vm .JUMP_ABSOLUTE , l .Start )
456+ }
413457 default :
414458 panic (py .ExceptionNewf (py .SyntaxError , "Unknown StmtBase: %v" , stmt ))
415459 }
0 commit comments