-
Notifications
You must be signed in to change notification settings - Fork 1
/
symbol_table.c
156 lines (132 loc) · 2.99 KB
/
symbol_table.c
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "symbol_table.h"
int symbol_num = 0;
char *dec_to_bin(int n)
{
char *bin;
int i = 0, b;
if (!(bin = malloc(sizeof(char) * BUS_SIZE))) {
perror("malloc");
return NULL;
}
for (b = 14; b >= 0; b--) {
int bit = n >> b;
if (bit & 1) {
bin[i] = '1';
}
else {
bin[i] = '0';
}
i++;
}
return bin;
}
struct symbol_entry *create_sym_entry(char *symbol, int val)
{
struct symbol_entry *entry;
if (! ( entry = malloc(sizeof(struct symbol_entry)) ) ) {
perror("malloc");
return NULL;
}
if (!symbol || strlen(symbol) > SYMBOL_SIZE) {
fprintf(stderr,
"create_sym_entry: symbol is empty or exceeds over %d character " \
"limit\n",
SYMBOL_SIZE);
return NULL;
}
strncpy(entry->symbol, symbol, strlen(symbol));
entry->symbol[strlen(symbol)] = '\0';
entry->val = val;
entry->next = NULL;
return entry;
}
struct symbol_entry *insert_to_table(struct symbol_entry *table,
char * symbol,
int val)
{
struct symbol_entry *entry = table;
int i = 0;
if (!table) {
fprintf(stderr, "insert_to_table: table cannot be NULL\n");
return NULL;
}
while (entry->next) {
entry = entry->next;
i++;
}
if (i < PREDEF_SYMBOL_NUM) {
fprintf(stderr,
"insert_to_table: Table is missing pre-defined symbols\n");
goto terminate;
}
//if address needs to be dynamically allocated
if (val < 0) {
val = 16 + symbol_num;
symbol_num++;
}
if ( ! (entry->next = create_sym_entry(symbol, val)) ) {
goto terminate;
}
return table;
terminate:
destroy_table(table);
return NULL;
}
void destroy_table (struct symbol_entry *entry) {
if (!entry) {
return;
}
struct symbol_entry *next = entry->next;
free(entry);
destroy_table(next);
}
void print_sym_table(struct symbol_entry *entry) {
while (entry) {
printf("sym: %-3s\t val: %d\n", entry->symbol, entry->val);
entry = entry->next;
}
}
int find_symbol(struct symbol_entry *entry, char *symbol) {
while (entry) {
if (strncmp(entry->symbol, symbol, strlen(symbol)) == 0) {
return entry->val;
}
entry = entry->next;
}
return -1;
}
struct symbol_entry *init_sym_table() {
struct symbol_entry *table = create_sym_entry("R0", 0);
struct symbol_entry *entry = table;
int i, n;
char *symbols[7] = {"SCREEN", "KBD", "SP", "LCL", "ARG", "THIS","THAT"};
int values[7] = {16384, 24576, 0, 1, 2, 3, 4};
char sym[7];
//Add Register 1-15 to symbol table
for(i = 1; i < 16; i++) {
if (i < 10 ) {
n = 3; //'Rx' + '\0'
}
else {
n = 4; //'Rxx' + '\0'
}
snprintf(sym, n, "R%d", i);
if ( !(entry->next = create_sym_entry(sym, i)) ) {
destroy_table(table);
return NULL;
}
entry = entry->next;
}
//Add Screen and Keyboard and special pre-defined symbols
for (i = 0; i < 7; i++) {
if ( !(entry->next = create_sym_entry(symbols[i], values[i])) ) {
destroy_table(table);
return NULL;
}
entry = entry->next;
}
return table;
}