Last active
May 29, 2019 21:28
-
-
Save mrnugget/33cd3189cc09fca16ad3b022eb0e6f4f to your computer and use it in GitHub Desktop.
Little bug in "Writing A Compiler In Go" 1.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func TestCallingRecursiveFunctionsInFunctions(t *testing.T) { | |
tests := []vmTestCase{ | |
{ | |
// This works | |
input: ` | |
let inner = fn(x) { | |
if (x == 0) { | |
return 0; | |
} else { | |
inner(x - 1); | |
} | |
}; | |
inner(1); | |
`, | |
expected: 0, | |
}, | |
{ | |
// This also works | |
input: ` | |
let inner = fn(x) { | |
if (x == 0) { | |
return 0; | |
} else { | |
inner(x - 1); | |
} | |
}; | |
let wrapper = fn() { | |
inner(1); | |
}; | |
wrapper(); | |
`, | |
expected: 0, | |
}, | |
{ | |
// This does _NOT_ work | |
input: ` | |
let wrapper = fn() { | |
let inner = fn(x) { | |
if (x == 0) { | |
return 0; | |
} else { | |
inner(x - 1); | |
} | |
}; | |
inner(1); | |
}; | |
wrapper(); | |
`, | |
expected: 0, | |
}, | |
} | |
runVmTests(t, tests) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is a compiler/constant-pool dump from the third test case: | |
CONSTANT 0 0xc00009a158 (*object.Integer): | |
Value: 0 | |
CONSTANT 1 0xc00009a168 (*object.Integer): | |
Value: 0 | |
CONSTANT 2 0xc00009a190 (*object.Integer): | |
Value: 1 | |
CONSTANT 3 0xc000078e40 (*object.CompiledFunction): | |
Instructions: | |
0000 OpGetLocal 0 | |
0002 OpConstant 0 | |
0005 OpEqual | |
0006 OpJumpNotTruthy 16 | |
0009 OpConstant 1 | |
0012 OpReturnValue | |
0013 OpJump 26 | |
0016 OpGetFree 0 | |
0018 OpGetLocal 0 | |
0020 OpConstant 2 | |
0023 OpSub | |
0024 OpCall 1 | |
0026 OpReturnValue | |
CONSTANT 4 0xc00009a1b8 (*object.Integer): | |
Value: 1 | |
CONSTANT 5 0xc000078e70 (*object.CompiledFunction): | |
Instructions: | |
0000 OpGetLocal 0 | |
0002 OpClosure 3 1 | |
0006 OpSetLocal 0 | |
0008 OpGetLocal 0 | |
0010 OpConstant 4 | |
0013 OpCall 1 | |
0015 OpReturnValue | |
main: | |
0000 OpClosure 5 0 | |
0004 OpSetGlobal 0 | |
0007 OpGetGlobal 0 | |
0010 OpCall 0 | |
0012 OpPop |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is VM trace of the third test case. | |
FRAME INS OP ARG ARG SP STACK | |
[01] 0000 OpClosure 5 0 sp= 1 stack=[ Closure[0xc00000a900] ] | |
[01] 0004 OpSetGlobal 0 sp=0 stack=[] | |
[01] 0007 OpGetGlobal 0 sp= 1 stack=[ Closure[0xc00000a900] ] | |
[01] 0010 OpCall 0 sp= 2 stack=[ Closure[0xc00000a900] | <nil> ] | |
[02] 0000 OpGetLocal 0 sp= 3 stack=[ Closure[0xc00000a900] | <nil> | <nil> ] | |
[02] 0002 OpClosure 3 1 sp= 3 stack=[ Closure[0xc00000a900] | <nil> | Closure[0xc00000a980] ] | |
[02] 0006 OpSetLocal 0 sp= 2 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] ] | |
[02] 0008 OpGetLocal 0 sp= 3 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] | Closure[0xc00000a980] ] | |
[02] 0010 OpConstant 4 sp= 4 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] | Closure[0xc00000a980] | 1 ] | |
[02] 0013 OpCall 1 sp= 4 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] | Closure[0xc00000a980] | 1 ] | |
[03] 0000 OpGetLocal 0 sp= 5 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] | Closure[0xc00000a980] | 1 | 1 ] | |
[03] 0002 OpConstant 0 sp= 6 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] | Closure[0xc00000a980] | 1 | 1 | 0 ] | |
[03] 0005 OpEqual sp= 5 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] | Closure[0xc00000a980] | 1 | false ] | |
[03] 0006 OpJumpNotTruthy 16 sp= 4 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] | Closure[0xc00000a980] | 1 ] | |
[03] 0016 OpGetFree 0 sp= 5 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] | Closure[0xc00000a980] | 1 | <nil> ] | |
[03] 0018 OpGetLocal 0 sp= 6 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] | Closure[0xc00000a980] | 1 | <nil> | 1 ] | |
[03] 0020 OpConstant 2 sp= 7 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] | Closure[0xc00000a980] | 1 | <nil> | 1 | 1 ] | |
[03] 0023 OpSub sp= 6 stack=[ Closure[0xc00000a900] | Closure[0xc00000a980] | Closure[0xc00000a980] | 1 | <nil> | 0 ] | |
[03] 0024 OpCall 1--- FAIL: TestCallingRecursiveFunctionsInFunctions (0.00s) | |
vm_test.go:644: vm error: calling non-closure and non-builtin | |
FAIL | |
FAIL github.com/mrnugget/monkey/vm 0.005s |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment