-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode-gen.c
More file actions
124 lines (113 loc) · 3.82 KB
/
code-gen.c
File metadata and controls
124 lines (113 loc) · 3.82 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 "code-gen.h"
#include "lexical-scanner.h"
#include "symbolTable.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
typedef struct {
char* key;
char* value;
} KeyValuePair;
KeyValuePair comp_table[] = {
{"0", "101010"}, {"1", "111111"}, {"-1", "111010"}, {"D", "001100"},
{"A", "110000"}, {"!D", "001101"}, {"!A", "110001"}, {"-D", "001111"},
{"-A", "110011"}, {"D+1", "011111"}, {"A+1", "110111"}, {"D-1", "001110"},
{"A-1", "110010"}, {"D+A", "000010"}, {"D-A", "010011"}, {"A-D", "000111"},
{"D&A", "000000"}, {"D|A", "010101"}
};
KeyValuePair dest_table[] = {
{"", "000"}, {"M", "001"}, {"D", "010"}, {"MD", "011"},
{"A", "100"}, {"AM", "101"}, {"AD", "110"}, {"AMD", "111"}
};
KeyValuePair jump_table[] = {
{"", "000"}, {"JGT", "001"}, {"JEQ", "010"}, {"JGE", "011"},
{"JLT", "100"}, {"JNE", "101"}, {"JLE", "110"}, {"JMP", "111"}
};
extern struct symTable hackLangTable;
void fgenerate(ScannerTokens tokens){
unsigned int i=0,variable=16;
while(i<tokens.len){
enum tokenType curtt=tokens.arr[i]->tt;
char hackMachineCode[HACK_MACHINE_WORD+1];
hackMachineCode[HACK_MACHINE_WORD]='\0';
if(curtt==S_ID || curtt==S_NUMBER){
char *p_end = NULL;
hackMachineCode[0]='0';
unsigned long strInt;
//a ins
if(curtt==S_NUMBER){
//translate directly
strInt = strtoul(tokens.arr[i]->lexeme, &p_end, 10);
}else{
//lookup id in table
struct KVN *trow=getSymValue(hackLangTable.runtime,tokens.arr[i]->lexeme);
if(trow!=NULL){
strInt = trow->value;
}else{
strInt=variable;
setSymValue(hackLangTable.runtime,tokens.arr[i]->lexeme, variable++);
}
}
int startIndex=HACK_MACHINE_WORD-1,endIndex=1,shiftPlaces=0;
for(; startIndex>=endIndex;(startIndex--,shiftPlaces++)){
hackMachineCode[startIndex]=((strInt & 1<<shiftPlaces) > 0) ? '1':'0';
}
printf("%s\n",hackMachineCode);
//genc++;
i++;
}else {
char *dest = NULL;
char *comp = NULL;
char *jmp = NULL;
hackMachineCode[0] = '1';
hackMachineCode[1] = '1';
hackMachineCode[2] = '1';
hackMachineCode[3] = '0';
// Search dest_table
assert(tokens.arr[i]->tt == S_DEST);
{
for(int j = 0; j < DEST_TABLE_SIZE; j++) {
if(strcmp(dest_table[j].key, tokens.arr[i]->lexeme) == 0) {
dest = dest_table[j].value;
break;
}
}
}
// Search comp_table
assert(tokens.arr[i+1]->tt == S_COMP);
char comp_lexeme[4]; // Create a copy
strcpy(comp_lexeme, tokens.arr[i+1]->lexeme);
char *searchChar = strchr(comp_lexeme, 'M');
if(searchChar) {
*searchChar = 'A';
hackMachineCode[3] = '1';
}
{
for(int j = 0; j < COMP_TABLE_SIZE; j++) {
if(strcmp(comp_table[j].key, comp_lexeme) == 0) {
comp = comp_table[j].value;
break;
}
}
}
// Search jump_table
assert(tokens.arr[i+2]->tt == S_JMP);
{
for(int j = 0; j < JUMP_TABLE_SIZE; j++) {
if(strcmp(jump_table[j].key, tokens.arr[i+2]->lexeme) == 0) {
jmp = jump_table[j].value;
break;
}
}
}
assert(dest);
assert(comp);
assert(jmp);
memcpy(hackMachineCode+DEST_HACK_START_INDEX,dest, DEST_HACK_LEN);
memcpy(hackMachineCode+COMP_HACK_START_INDEX,comp, COMP_HACK_LEN);
memcpy(hackMachineCode+JUMP_HACK_START_INDEX,jmp , JUMP_HACK_LEN);
printf("%s\n",hackMachineCode);
i=i+3;
}
}
}