-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathassembler.go
More file actions
135 lines (122 loc) · 3.05 KB
/
Copy pathassembler.go
File metadata and controls
135 lines (122 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package main
import (
"bufio"
"fmt"
)
//KEEP ALL THE RESULTS TO RAX!
//For arithmetic for now
//TokenProcess general token prcessing function
func TokenProcess(tokens []Token) {
//Take tokens, covert them into RPN, and produce AST
t := tree(TokensPostfix(tokens))
//Get the syntax tree and output assembly
treeAssemble(&t)
}
func treeAssemble(tree *Tree) {
switch (*tree).Type {
//Operator means produce integer value ex) + - * ... etc
case "Operator":
Arithmetic(tree)
break
case "Int":
Arithmetic(tree)
break
case "Variable":
//Should change to allow dif variable types
Arithmetic(tree)
break
//Fix Later
case "FunctionCall":
//Should change to allow dif variable types
Arithmetic(tree)
break
case "Declaration":
Declaration(tree, string((*tree).Value))
break
//This is function call
case "Function":
if string((*tree).Value) == "출력" || string((*tree).Value) == "print" {
treeAssemble(tree.Right)
ASMWrite("callq inttostring\n")
ASMWrite("callq printout\n")
} else {
code := fmt.Sprintf("callq %s\n", string((*tree).Value))
ASMWrite(code)
}
break
//End of func but need to be scalable
case "}":
//If there was local variable
if stackindex > 8 {
ASMWrite("movq %rbp, %rsp\n")
ASMWrite("popq %rbp\n") //restore rbp
for i := 0; i < (stackindex/8)-1; i++ {
//pop remaining local variable
ASMWrite("popq %rcx\n")
}
//Reset local variable map
LocalVariable = make(map[string]int)
stackindex = 8
}
ASMWrite("retq\n")
}
}
//ScanAndGen takes a scanner object and generates code given string input
func ScanAndGen(scanner *bufio.Scanner) {
for scanner.Scan() {
code := scanner.Text()
if len(code) == 0 {
continue
}
tokenized := tokenizer(code)
class := ClassifyStatement(tokenized)
CodeGen(class, tokenized, scanner)
}
}
//CodeGen takes a statement classification and outputs corresponding assembly
func CodeGen(class string, tokens []Token, scanner *bufio.Scanner) {
switch class {
case "Test":
TokenProcess(tokens)
break
case "VariableDeclaration":
VariableDeclaration(tokens)
break
case "FunctionReturn":
FunctionReturn(tokens)
case "FunctionDeclaration":
EndStack = EndStack.Push("FunctionDeclaration")
FunctionDeclaration(tokens)
break
case "FunctionCall":
//Print exception need fix later
if string(tokens[0].Value) == "print" {
TokenProcess(tokens)
} else {
FunctionCall(AddFunctionCallToStack(tokens))
FunctionCallStack, _ = FunctionCallStack.Pop()
}
break
case "EndOf":
var endType string
//Check what is ending
EndStack, endType = EndStack.Pop()
if endType == "IfStatement" {
BlockEnd()
IfEnd()
} else if endType == "FunctionDeclaration" {
//Pop local variable, restore rsp to return address
FunctionEndRspReset()
LocalVariable = make(map[string]int)
FunctionCallStack = make([]Call, 0)
stackindex = 8
paramCount = 0 //reset param count for new function!
}
break
case "IfStatement":
EndStack = EndStack.Push("IfStatement")
IfStatement(tokens)
case "Redefinition":
RedefineVariable(tokens)
}
}