|
8 | 8 | "sort" |
9 | 9 | ) |
10 | 10 |
|
| 11 | +var jumpReturns []*int |
| 12 | + |
11 | 13 | func (c *Compiler) Compile(node ast.Node) error { |
12 | 14 | switch node := node.(type) { |
13 | 15 | case *ast.Program: |
@@ -99,7 +101,8 @@ func (c *Compiler) Compile(node ast.Node) error { |
99 | 101 | } |
100 | 102 |
|
101 | 103 | c.emit(code.OpJump, startPos) |
102 | | - c.changeOperand(jumpPos, len(c.currentInstructions())) |
| 104 | + afterPos := len(c.currentInstructions()) |
| 105 | + c.changeOperand(jumpPos, afterPos) |
103 | 106 | case *ast.ConditionalStatement: |
104 | 107 | err := c.Compile(node.Condition) |
105 | 108 | if err != nil { |
@@ -151,6 +154,15 @@ func (c *Compiler) Compile(node ast.Node) error { |
151 | 154 | } |
152 | 155 | } |
153 | 156 | c.currentScope = c.currentScope.Outer |
| 157 | + |
| 158 | + if c.currentScope.Outer == nil { |
| 159 | + skipTo := len(c.currentInstructions()) |
| 160 | + for _, jumpReturn := range jumpReturns { |
| 161 | + c.changeOperand(*jumpReturn, skipTo) |
| 162 | + } |
| 163 | + |
| 164 | + jumpReturns = []*int{} |
| 165 | + } |
154 | 166 | case *ast.VariableDeclaration: |
155 | 167 | index := c.variables |
156 | 168 |
|
@@ -273,12 +285,21 @@ func (c *Compiler) Compile(node ast.Node) error { |
273 | 285 |
|
274 | 286 | c.emit(code.OpClosure, c.addConstant(compiledFunc), len(freeSymbols)) |
275 | 287 | case *ast.Return: |
| 288 | + if c.currentScope.Outer == nil { |
| 289 | + return fmt.Errorf("cannot have return statement in root scope") |
| 290 | + } |
| 291 | + |
276 | 292 | err := c.Compile(node.Value) |
277 | 293 | if err != nil { |
278 | 294 | return err |
279 | 295 | } |
280 | 296 |
|
281 | 297 | c.emit(code.OpReturnValue) |
| 298 | + |
| 299 | + if c.scopeIndex == 0 { |
| 300 | + val := c.emit(code.OpJump, 9999) |
| 301 | + jumpReturns = append(jumpReturns, &val) |
| 302 | + } |
282 | 303 | case *ast.CallExpression: |
283 | 304 | err := c.Compile(node.Function) |
284 | 305 | if err != nil { |
|
0 commit comments