diff options
author | Suleyman Farajli <suleyman@farajli.net> | 2025-01-03 22:47:10 +0400 |
---|---|---|
committer | Suleyman Farajli <suleyman@farajli.net> | 2025-01-03 22:47:10 +0400 |
commit | c0157deb77104be4522fe2694dbb7e7bdec005c8 (patch) | |
tree | 3d592d9c8864a2473b780539745cb16dc40617b2 | |
parent | 162a641ed34ebc68fa1f30a32c698695146f0d86 (diff) |
variables added
-rw-r--r-- | src/main.go | 86 |
1 files changed, 81 insertions, 5 deletions
diff --git a/src/main.go b/src/main.go index 41097de..ca19e84 100644 --- a/src/main.go +++ b/src/main.go @@ -10,8 +10,6 @@ import ( "io" ) -var print = fmt.Println - type Operation struct { name string label string @@ -20,7 +18,6 @@ type Operation struct { intData int } -/* TODO: Add file name */ type Token struct { str string file string @@ -117,6 +114,7 @@ var looplabel int = 0 var stringlabel int = 0 func parse(tokens[]Token) []Operation { var ops[] Operation + var variables[] string var externalWords[] Word var iflabels[] int var looplabels[] int @@ -178,6 +176,64 @@ func parse(tokens[]Token) []Operation { op.label = fmt.Sprintf(".done%d", looplabels[len(looplabels) - 1]) looplabels = looplabels[:len(looplabels) - 1] + case "push": + if i + 1 >= len(tokens) { + /* FIXME: Better error message */ + panic("invalid push usage") + } + variableIndex := -1 + for y := 0; y < len(variables); y++ { + if tokens[i + 1].str == variables[y] { + variableIndex = y + } + } + if variableIndex == -1 { + panic("undeclared variable") + } + op.name = "push" + op.strData = variables[variableIndex] + i++ + /* FIXME: better solution */ + ops = append(ops, op) + continue + + + case "pull": + if i + 1 >= len(tokens) { + /* FIXME: Better error message */ + panic("invalid pull usage") + } + variableIndex := -1 + for y := 0; y < len(variables); y++ { + if tokens[i + 1].str == variables[y] { + variableIndex = y + } + } + if variableIndex == -1 { + panic("undeclared variable") + } + op.name = "pull" + op.strData = variables[variableIndex] + i++ + /* FIXME: better solution */ + ops = append(ops, op) + continue + + + case "var": + if i + 1 >= len(tokens) { + /* FIXME: Better error message */ + panic("invalid var usage") + } + op.name = "variable" + op.strData = tokens[i + 1].str + variables = append(variables, tokens[i + 1].str) + i++ + /* FIXME: better solution */ + ops = append(ops, op) + continue + + case "const": if i + 2 >= len(tokens) { /* FIXME: Better error message */ @@ -246,6 +302,8 @@ func parse(tokens[]Token) []Operation { goto done } + /* FIXME: check for variable names that comes without push or pull */ + if op.name == "" { fmt.Fprintf(os.Stderr, "Undefined word `%s` %s: %d:%d\n", tokens[i].str, tokens[i].file, tokens[i].line, tokens[i].offset) os.Exit(1) @@ -442,6 +500,14 @@ func mapX86_64linux(op Operation) string{ case "number": buf += fmt.Sprintf("\tpush %d\n", op.intData) + case "push": + buf += "\tpop r10\n" + buf += fmt.Sprintf("\tmov [%s], r10\n", op.strData) + + case "pull": + buf += fmt.Sprintf("\tmov r10, [%s]\n", op.strData) + buf += "\tpush r10\n" + case "syscall": /* FIXME: Consider making it more consise */ switch op.intData { @@ -495,18 +561,23 @@ func mapX86_64linux(op Operation) string{ func compile(ops[] Operation, w io.Writer) { comment_str := ";;" var strings[][2] string + var variables[] string printDumpFunc := false fmt.Fprintf(w, mapX86_64linux(Operation{name: "boilerPlateStart"})) for i := 0; i < len(ops); i++ { - fmt.Fprintf(w, "\t%s %s\n", comment_str, ops[i].name) - fmt.Fprintf(w, mapX86_64linux(ops[i])) switch ops[i].name { case "string": strings = append(strings, [2]string{ops[i].strData, ops[i].label}) case "dump": printDumpFunc = true + case "variable": + variables = append(variables, ops[i].strData) + continue } + + fmt.Fprintf(w, "\t%s %s\n", comment_str, ops[i].name) + fmt.Fprintf(w, mapX86_64linux(ops[i])) } fmt.Fprintf(w, mapX86_64linux(Operation{name: "boilerPlateExit"})) @@ -514,6 +585,11 @@ func compile(ops[] Operation, w io.Writer) { fmt.Fprintf(w, mapX86_64linux(Operation{name: "dumpFunc"})) } + fmt.Fprintf(w, "section .bss\n") + for i := 0; i < len(variables); i++ { + fmt.Fprintf(w, "%s: resb 8\n", variables[i]) + } + fmt.Fprintf(w, "section .data\n") for i := 0; i < len(strings); i++ { fmt.Fprintf(w, "%s: db %s, 10\n", strings[i][1], strings[i][0]) |