Skip to content

Commit

Permalink
Switch, Break, Continue, Fallthrough, Error Context
Browse files Browse the repository at this point in the history
  • Loading branch information
Vilsol committed Dec 28, 2020
1 parent 7a525a3 commit 09bd426
Show file tree
Hide file tree
Showing 11 changed files with 601 additions and 247 deletions.
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,16 @@ A Web IDE is available [here](https://vilsol.github.io/go-mlog-web/?1)
* `return` from functions
* `for` loops
* `if`/`else if`/`else` statements
* `switch` statement
* `break`/`continue`/`fallthrough` statements
* Binary and Unary math
* Function level variable scopes
* Contextual errors

## Roadmap

* Documentation
* `break` out of loops
* `switch` statement
* Full variable block scoping
* `print`/`println` multiple arguments
* Errors with context
* Extensions
* Variable argument count functions
* Multiple function return values
* Optimize simple jump instructions
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/Vilsol/go-mlog
go 1.15

require (
github.com/davecgh/go-spew v1.1.1
github.com/sirupsen/logrus v1.7.0
github.com/spf13/cobra v1.1.1
github.com/spf13/viper v1.7.1
Expand Down
33 changes: 14 additions & 19 deletions tests/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ func TestErrors(t *testing.T) {
name: "NoExternalImports",
input: `package main
import "time"`,
output: `unregistered import used: "time"`,
output: `error at 21: unregistered import used: "time"`,
},
{
name: "GlobalScopeVariable",
input: `package main
var x = 1`,
output: `global scope may only contain constants not variables`,
output: `error at 14: global scope may only contain constants not variables`,
},
{
name: "NoMainFunction",
Expand All @@ -42,42 +42,37 @@ var x = 1`,
{
name: "InvalidOperator",
input: TestMain(`x := 1 &^ 1`),
output: `operator statement cannot use this operation: &^`,
output: `error at 103: operator statement cannot use this operation: &^`,
},
{
name: "NotSupportSelect",
input: TestMain(`select {}`),
output: `statement type not supported: *ast.SelectStmt`,
},
{
name: "NotSupportSwitch",
input: TestMain(`switch {}`),
output: `statement type not supported: *ast.SwitchStmt`,
output: `error at 103: statement type not supported: *ast.SelectStmt`,
},
{
name: "NotSupportGo",
input: TestMain(`go foo()`),
output: `statement type not supported: *ast.GoStmt`,
output: `error at 103: statement type not supported: *ast.GoStmt`,
},
{
name: "NotSupportSend",
input: TestMain(`foo <- 1`),
output: `statement type not supported: *ast.SendStmt`,
output: `error at 103: statement type not supported: *ast.SendStmt`,
},
{
name: "NotSupportDefer",
input: TestMain(`defer func() {}()`),
output: `statement type not supported: *ast.DeferStmt`,
output: `error at 103: statement type not supported: *ast.DeferStmt`,
},
{
name: "NotSupportRange",
input: TestMain(`for i := range nums {}`),
output: `statement type not supported: *ast.RangeStmt`,
output: `error at 103: statement type not supported: *ast.RangeStmt`,
},
{
name: "InvalidAssignment",
input: TestMain(`1 = 2`),
output: `left side variable assignment can only contain identifications`,
output: `error at 103: left side variable assignment can only contain identifications`,
},
{
name: "InvalidParamTypeString",
Expand All @@ -90,7 +85,7 @@ func main() {
func sample1(arg string) int {
return 1
}`,
output: `function parameters may only be integers or floating point numbers`,
output: `error at 57: function parameters may only be integers or floating point numbers`,
},
{
name: "InvalidParamTypeOther",
Expand All @@ -103,12 +98,12 @@ func main() {
func sample1(arg hello.world) int {
return 1
}`,
output: `function parameters may only be integers or floating point numbers`,
output: `error at 53: function parameters may only be integers or floating point numbers`,
},
{
name: "CallToUnknownFunction",
input: TestMain(`foo()`),
output: `unknown function: foo`,
output: `error at 89: unknown function: foo`,
},
{
name: "InvalidConstant",
Expand All @@ -118,7 +113,7 @@ const x = 1 + 2
func main() {
}`,
output: `unknown constant type: *ast.BinaryExpr`,
output: `error at 21: unknown constant type: *ast.BinaryExpr`,
},
{
name: "EmptyPrintlnError",
Expand Down Expand Up @@ -151,7 +146,7 @@ func main() {
func sample() (int, int) {
return 1, 2
}`,
output: `only single value returns are supported`,
output: `error at 70: only single value returns are supported`,
},
}
for _, test := range tests {
Expand Down
105 changes: 39 additions & 66 deletions tests/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,18 @@ func foo(x int) int {
5: set @return _foo_1
6: read @counter bank1 @stack
7: set _main_i 0
8: op add @stack @stack 1
9: write _main_i bank1 @stack
10: op add @stack @stack 1
11: write 13 bank1 @stack
12: jump 2 always
13: op sub @stack @stack 2
14: set _main_0 @return
15: print _main_0
16: print "\n"
17: op add _main_i _main_i 1
18: jump 8 lessThan _main_i 10`,
8: jump 20 lessThan _main_i 10
9: op add @stack @stack 1
10: write _main_i bank1 @stack
11: op add @stack @stack 1
12: write 14 bank1 @stack
13: jump 2 always
14: op sub @stack @stack 2
15: set _main_0 @return
16: print _main_0
17: print "\n"
18: op add _main_i _main_i 1
19: jump 9 lessThan _main_i 10`,
},
{
name: "Debug",
Expand Down Expand Up @@ -80,6 +81,9 @@ write @stack cell2 1
set _main_i 0
write @counter cell2 0
write @stack cell2 1
jump 54 lessThan _main_i 10
write @counter cell2 0
write @stack cell2 1
op add @stack @stack 1
write @counter cell2 0
write @stack cell2 1
Expand All @@ -89,7 +93,7 @@ write @stack cell2 1
op add @stack @stack 1
write @counter cell2 0
write @stack cell2 1
write 35 bank1 @stack
write 38 bank1 @stack
write @counter cell2 0
write @stack cell2 1
jump 4 always
Expand All @@ -108,7 +112,7 @@ write @stack cell2 1
op add _main_i _main_i 1
write @counter cell2 0
write @stack cell2 1
jump 22 lessThan _main_i 10`,
jump 25 lessThan _main_i 10`,
},
{
name: "Comments",
Expand All @@ -128,81 +132,50 @@ read @counter bank1 @stack // Trampoline back
// Function: main //
set _main_i 0 // Set the variable to the value
jump 20 lessThan _main_i 10 // Jump to end of loop
op add @stack @stack 1 // Update Stack Pointer
write _main_i bank1 @stack // Write argument to memory
op add @stack @stack 1 // Update Stack Pointer
write 13 bank1 @stack // Set Trampoline Address
write 14 bank1 @stack // Set Trampoline Address
jump 2 always // Jump to function: foo
op sub @stack @stack 2 // Update Stack Pointer
set _main_0 @return // Set the variable to the value
print _main_0 // Call to native function
print "\n" // Call to native function
op add _main_i _main_i 1 // Execute for loop post condition increment/decrement
jump 8 lessThan _main_i 10 // Jump to start of loop`,
jump 9 lessThan _main_i 10 // Jump to start of loop`,
},
{
name: "All",
input: testInput,
options: transpiler.Options{
Numbers: true,
Comments: true,
Debug: true,
},
output: ` 0: set @stack 0 // Reset Stack
1: jump 19 always // Jump to start of main
1: jump 7 always // Jump to start of main
// Function: foo //
2: write @counter cell2 0 // Debug
3: write @stack cell2 1 // Debug
4: op sub _foo_0 @stack 1 // Calculate address of parameter
5: write @counter cell2 0 // Debug
6: write @stack cell2 1 // Debug
7: read _foo_x bank1 _foo_0 // Read parameter into variable
8: write @counter cell2 0 // Debug
9: write @stack cell2 1 // Debug
10: op add _foo_1 _foo_x 20 // Execute operation
11: write @counter cell2 0 // Debug
12: write @stack cell2 1 // Debug
13: set @return _foo_1 // Set return data
14: write @counter cell2 0 // Debug
15: write @stack cell2 1 // Debug
16: read @counter bank1 @stack // Trampoline back
2: op sub _foo_0 @stack 1 // Calculate address of parameter
3: read _foo_x bank1 _foo_0 // Read parameter into variable
4: op add _foo_1 _foo_x 20 // Execute operation
5: set @return _foo_1 // Set return data
6: read @counter bank1 @stack // Trampoline back
// Function: main //
17: write @counter cell2 0 // Debug
18: write @stack cell2 1 // Debug
19: set _main_i 0 // Set the variable to the value
20: write @counter cell2 0 // Debug
21: write @stack cell2 1 // Debug
22: op add @stack @stack 1 // Update Stack Pointer
23: write @counter cell2 0 // Debug
24: write @stack cell2 1 // Debug
25: write _main_i bank1 @stack // Write argument to memory
26: write @counter cell2 0 // Debug
27: write @stack cell2 1 // Debug
28: op add @stack @stack 1 // Update Stack Pointer
29: write @counter cell2 0 // Debug
30: write @stack cell2 1 // Debug
31: write 35 bank1 @stack // Set Trampoline Address
32: write @counter cell2 0 // Debug
33: write @stack cell2 1 // Debug
34: jump 4 always // Jump to function: foo
35: write @counter cell2 0 // Debug
36: write @stack cell2 1 // Debug
37: op sub @stack @stack 2 // Update Stack Pointer
38: write @counter cell2 0 // Debug
39: write @stack cell2 1 // Debug
40: set _main_0 @return // Set the variable to the value
41: write @counter cell2 0 // Debug
42: write @stack cell2 1 // Debug
43: print _main_0 // Call to native function
44: print "\n" // Call to native function
45: write @counter cell2 0 // Debug
46: write @stack cell2 1 // Debug
47: op add _main_i _main_i 1 // Execute for loop post condition increment/decrement
48: write @counter cell2 0 // Debug
49: write @stack cell2 1 // Debug
50: jump 22 lessThan _main_i 10 // Jump to start of loop`,
7: set _main_i 0 // Set the variable to the value
8: jump 20 lessThan _main_i 10 // Jump to end of loop
9: op add @stack @stack 1 // Update Stack Pointer
10: write _main_i bank1 @stack // Write argument to memory
11: op add @stack @stack 1 // Update Stack Pointer
12: write 14 bank1 @stack // Set Trampoline Address
13: jump 2 always // Jump to function: foo
14: op sub @stack @stack 2 // Update Stack Pointer
15: set _main_0 @return // Set the variable to the value
16: print _main_0 // Call to native function
17: print "\n" // Call to native function
18: op add _main_i _main_i 1 // Execute for loop post condition increment/decrement
19: jump 9 lessThan _main_i 10 // Jump to start of loop`,
},
}
for _, test := range tests {
Expand Down
83 changes: 82 additions & 1 deletion tests/statement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,10 @@ print 6`,
name: "ForLoop",
input: TestMain(`for i := 0; i < 10; i++ { print(i) }`),
output: `set _main_i 0
jump 5 lessThan _main_i 10
print _main_i
op add _main_i _main_i 1
jump 1 lessThan _main_i 10`,
jump 2 lessThan _main_i 10`,
},
{
name: "Reassignment",
Expand All @@ -58,6 +59,86 @@ jump 1 lessThan _main_i 10`,
input: TestMain(`x := 'A'`),
output: `set _main_x "A"`,
},
{
name: "Break",
input: TestMain(`for i := 0; i < 10; i++ { if i == 5 { break; }; println(i); }`),
output: `set _main_i 0
jump 10 lessThan _main_i 10
op equal _main_0 _main_i 5
jump 5 equal _main_0 1
jump 6 always
jump 10 always
print _main_i
print "\n"
op add _main_i _main_i 1
jump 2 lessThan _main_i 10`,
},
{
name: "Continue",
input: TestMain(`for i := 0; i < 10; i++ { if i == 5 { continue; }; println(i); }`),
output: `set _main_i 0
jump 10 lessThan _main_i 10
op equal _main_0 _main_i 5
jump 5 equal _main_0 1
jump 6 always
jump 8 always
print _main_i
print "\n"
op add _main_i _main_i 1
jump 2 lessThan _main_i 10`,
},
{
name: "Switch",
input: TestMain(`switch 10 {
case 0:
println("0")
case 1:
println("1")
fallthrough
case 2:
println("2")
fallthrough
case 3, 4:
println("3, 4")
break
case 5, 6:
println("5, 6")
break
default:
println("default")
break
}`),
output: `jump 2 equal 10 0
jump 5 always
print "0"
print "\n"
jump 30 always
jump 7 equal 10 1
jump 10 always
print "1"
print "\n"
jump 12 always
jump 12 equal 10 2
jump 15 always
print "2"
print "\n"
jump 18 always
jump 18 equal 10 3
jump 18 equal 10 4
jump 21 always
print "3, 4"
print "\n"
jump 30 always
jump 24 equal 10 5
jump 24 equal 10 6
jump 27 always
print "5, 6"
print "\n"
jump 30 always
print "default"
print "\n"
jump 30 always`,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
Expand Down
Loading

0 comments on commit 09bd426

Please sign in to comment.