-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGenerateAssembly.h
More file actions
124 lines (110 loc) · 3.5 KB
/
GenerateAssembly.h
File metadata and controls
124 lines (110 loc) · 3.5 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
#include<iostream>
#include<fstream>
#include<string>
#include <vector>
#include <sstream>
#include <optional>
#include <unordered_set>
#include <variant>
std::unordered_set<std::string> FUNCTIONAL_KEYWORDS {"exitProg","print"};
std::unordered_set<std::string> NON_FUNCTIONAL_KEYWORDS {"int","float","double","bool","string","char","array"};
std::unordered_set<std::string> Variables;
struct NodeExpr{
std::string expr;
std::variant<int,bool> exprValue;
};
struct NodeExit{
std::string exitExpr;
NodeExpr exitValue;
};
enum TokenType{
_integerLiteral,
_floatLiteral,
_doubleLiteral,
_stringLiteral,
_semiColon,
_equals,
_parenthesis,
_flowerBrackets,
_squareBrackets,
_variable,
_func_keyWord,
_non_func_keyWord,
_expr,
_operator
};
struct Token{
TokenType type;
std::optional<std::string> value;
};
struct Variable{
std::string name;
int offset;
};
std::vector<Variable> _Variables;
class GenerateAssembly{
public:
GenerateAssembly() {
fileHandle.open("assemblySource.asm", std::ios::out);
if (fileHandle.is_open()) {
fileHandle << "global _start" << std::endl;
fileHandle << "_start:" << std::endl;
}
else
{
std::cerr<<"Unable to write to assembly file"<<std::endl;
exit(EXIT_FAILURE);
}
}
void _exitProg(NodeExit& exitNode)
{
fileHandle<<" mov rax, 60"<<std::endl;
fileHandle<<" mov rdi,"<< std::get<int>(exitNode.exitValue.exprValue)<<std::endl; //-> can throw error if an int value is not found;
fileHandle<<" syscall"<<std::endl;
fileHandle<<std::endl;
}
void _print(const std::string& printExpr)
{
fileHandle<<" sub rsp ,"<<printExpr.length()<<std::endl;
for(int i=0;i<printExpr.length();i++)
{
fileHandle<<" mov byte[rsp+"<<printExpr.length()-i<<"], "<<"'"<<printExpr[printExpr.length()-1-i]<<"'"<<std::endl;
}
fileHandle<<" lea rsi, [rsp+1]"<<std::endl;
fileHandle<<" mov rax, 1"<<std::endl;
fileHandle<<" mov rdi, 1"<<std::endl;
fileHandle<<" mov rdx, "<<printExpr.length()<<std::endl;
fileHandle<<" syscall"<<std::endl;
fileHandle<<std::endl;
}
void _print(int length)
{
fileHandle<<" mov rsi, rsp"<<std::endl;
fileHandle<<" mov rax, 1"<<std::endl;
fileHandle<<" mov rdi, 1"<<std::endl;
fileHandle<<" mov rdx, "<<length<<std::endl;
fileHandle<<" syscall"<<std::endl;
fileHandle<<std::endl;
}
void _allocateVar(std::vector<Token> tokens){
_Variables.push_back({.name = tokens[1].value.value(),.offset = stackPointer++});
fileHandle<<" push "<<tokens[3].value.value()<<std::endl;
}
void _accessVar(const std::string& varName){ //->puts a copy of the required value and puts it at the top of the stack
for(const Variable& x: _Variables){
if(x.name ==varName){
fileHandle<<" push QWORD [rsp+"<<(stackPointer-x.offset-1)*8<<"]"<<std::endl;
}
}
}
~GenerateAssembly()
{
fileHandle<<" mov rax, 60"<<std::endl;
fileHandle<<" mov rdi, 0"<<std::endl;
fileHandle<<" syscall"<<std::endl;
fileHandle.close();
}
private:
std::fstream fileHandle;
int stackPointer =0;
};