summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuleyman Farajli <suleyman@farajli.net>2025-01-03 22:47:10 +0400
committerSuleyman Farajli <suleyman@farajli.net>2025-01-03 22:47:10 +0400
commitc0157deb77104be4522fe2694dbb7e7bdec005c8 (patch)
tree3d592d9c8864a2473b780539745cb16dc40617b2
parent162a641ed34ebc68fa1f30a32c698695146f0d86 (diff)
variables added
-rw-r--r--src/main.go86
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])