diff --git a/examples/fizzbuzz/fizzbuzz.q b/examples/fizzbuzz/fizzbuzz.q new file mode 100644 index 0000000..14724a8 --- /dev/null +++ b/examples/fizzbuzz/fizzbuzz.q @@ -0,0 +1,39 @@ +import log +import sys + +main() { + fizzbuzz(15) +} + +fizzbuzz(n) { + x := 1 + + loop { + // TODO: implement switch statement + if x % 15 == 0 { + print("FizzBuzz", 8) + } else { + if x % 5 == 0 { + print("Buzz", 4) + } else { + if x % 3 == 0 { + print("Fizz", 4) + } else { + log.number(x) + } + } + } + + x += 1 + + if x > n { + return + } else { + print(" ", 1) + } + } +} + +print(address, length) { + sys.write(1, address, length) +} \ No newline at end of file diff --git a/src/build/asm/Finalize.go b/src/build/asm/Finalize.go index 340b6d4..97aa786 100644 --- a/src/build/asm/Finalize.go +++ b/src/build/asm/Finalize.go @@ -3,6 +3,7 @@ package asm import ( "encoding/binary" "fmt" + "strings" "git.akyoto.dev/cli/q/src/build/arch/x64" "git.akyoto.dev/cli/q/src/build/config" @@ -287,6 +288,10 @@ restart: } for key, address := range labels { + if strings.HasPrefix(key, "data_") { + continue + } + if address > pointer.Position { labels[key] += offset } diff --git a/src/build/core/AddBytes.go b/src/build/core/AddBytes.go index d75c11d..bd620e0 100644 --- a/src/build/core/AddBytes.go +++ b/src/build/core/AddBytes.go @@ -7,7 +7,7 @@ import ( // AddBytes adds a sequence of bytes and returns its address as a label. func (f *Function) AddBytes(value []byte) string { f.count.data++ - label := fmt.Sprintf("%s_data_%d", f.UniqueName, f.count.data) + label := fmt.Sprintf("data_%s_%d", f.UniqueName, f.count.data) f.Assembler.SetData(label, value) return label } diff --git a/src/build/scope/Scope.go b/src/build/scope/Scope.go index 42021e6..9bbb3db 100644 --- a/src/build/scope/Scope.go +++ b/src/build/scope/Scope.go @@ -14,7 +14,6 @@ type Scope struct { // AddVariable adds a new variable to the current scope. func (s *Scope) AddVariable(variable *Variable) { - variable.Depth = s.Depth s.Variables = append(s.Variables, variable) s.Use(variable.Register) } diff --git a/src/build/scope/Stack.go b/src/build/scope/Stack.go index ceca9e3..94fec99 100644 --- a/src/build/scope/Stack.go +++ b/src/build/scope/Stack.go @@ -47,7 +47,6 @@ func (stack *Stack) PushScope(body ast.AST, buffer []byte) *Scope { Name: v.Name, Register: v.Register, Alive: count, - Depth: uint8(len(stack.Scopes)), }) } } @@ -58,8 +57,8 @@ func (stack *Stack) PushScope(body ast.AST, buffer []byte) *Scope { // UseVariable reduces the lifetime of the variable in all scopes. func (stack *Stack) UseVariable(variable *Variable) { - for depth, scope := range stack.Scopes { - if scope.InLoop && variable.Depth != uint8(depth) { + for _, scope := range stack.Scopes { + if scope.InLoop { continue } diff --git a/src/build/scope/Variable.go b/src/build/scope/Variable.go index 28e845a..491bb78 100644 --- a/src/build/scope/Variable.go +++ b/src/build/scope/Variable.go @@ -8,7 +8,6 @@ import ( type Variable struct { Name string Alive uint8 - Depth uint8 Register cpu.Register } diff --git a/tests/examples_test.go b/tests/examples_test.go index 116e270..b378045 100644 --- a/tests/examples_test.go +++ b/tests/examples_test.go @@ -23,6 +23,7 @@ var examples = []struct { {"echo", "Echo", "Echo", 0}, {"itoa", "", "9223372036854775807", 0}, {"collatz", "", "6 3 10 5 16 8 4 2 1", 0}, + {"fizzbuzz", "", "1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz", 0}, } func TestExamples(t *testing.T) {