Updated link in README file.
[Hack-Assembler.git] / parse.c
blob6750ca79f67a15565f603786cbcfc079dc997507
1 #include <ctype.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdio.h>
6 #include "asm.h"
7 #include "parse.h"
8 #include "error.h"
9 #include "symbol.h"
11 FILE *pInfile;
13 char InBuff[MAXINBUFF];
15 char FilenameBuff[80];
17 char *current_command = InBuff;
18 int current_command_type;
20 int k = 0;
22 void dump_buffer()
24 int i = 0;
25 while(InBuff[i] != '\0')
27 printf("%c", InBuff[i++]);
29 printf("\n");
32 void reset_buffer()
34 current_command = InBuff;
37 int find_line_num()
39 int i = 1;
40 char *k = InBuff;
41 while(current_command != k)
43 if(*k == '\n') { ++i; }
44 ++k;
46 return i;
49 int search_command(const char *current_command, const char term)
51 int i = 0;
52 int found = 0;
53 while(*(current_command+i) != '\r' && *(current_command+i) != '\n' && *(current_command+i) != '\0')
55 if(*(current_command+i) == term) { ++found; }
56 ++i;
58 return found;
61 void print_current_command()
63 int i = 0;
64 while(*(current_command+i) != '\r' && *(current_command+i) != '\n' && *(current_command+i) != '\0' && i <= 20)
66 printf("%c", *(current_command+i));
67 ++i;
69 if(settings.code != 0 || settings.comments != 0) { printf("\n"); }
72 void init_parser(char *FilenameBuff)
74 if((pInfile = fopen(FilenameBuff, "rb")) == NULL)
75 exit_error(3, "Cannot Open Input (Source) File");
77 k = -1;
78 while(!feof(pInfile) && k < MAXINBUFF)
80 InBuff[++k] = fgetc(pInfile);
82 InBuff[k] = '\0';
84 if(k < MAXINBUFF)
86 /* printf("Input Buffer Loaded\n"); */
87 } else {
88 exit_error(4, "Input Too Large for Input Buffer");
92 int has_more_commands()
94 int i = 0;
95 while(isprint(*(current_command+i))) { ++i; }
96 if(*(current_command+i) == '\0') { return 0; }
97 if(isspace(*(current_command+i)))
99 do {
100 ++i;
101 } while (isspace(*(current_command+i)));
102 if(*(current_command+i) == '\0') { return 0; }
105 return 1;
108 void advance()
110 do {
111 ++current_command;
112 } while(*current_command != '\n' && *current_command != '\0');
113 while(isspace(*current_command)) { ++current_command; }
114 if(*(current_command+1) == '/')
116 ++current_command;
117 advance();
121 int command_type()
123 if(*current_command == '@')
125 current_command_type = A_COMMAND;
126 return A_COMMAND;
127 } else if(search_command(current_command, '(') > 0 || search_command(current_command, ')') > 0) {
128 current_command_type = L_COMMAND;
129 return L_COMMAND;
130 } else if(!isdigit(*current_command)){
131 current_command_type = C_COMMAND;
132 return C_COMMAND;
133 } else if(isdigit(*current_command)){
134 current_command_type = C_COMMAND;
135 return C_COMMAND;
136 } else {
137 int i = find_line_num();
138 line_notification(i);
139 exit_error(7, "Incorrect Command Type");
140 return -1;
144 int symbol()
146 int convert = 0, i = 0;
147 int address = 0;
148 char sym[MAXSYMBOL];
150 /* determine if this is a symbol or an address */
151 convert = isdigit(*(current_command+1));
153 if(current_command_type == A_COMMAND)
155 if(convert == 0) /* text (symbolic) entries */
157 i = 0;
158 while(!isspace(*(current_command+i+1)))
160 sym[i] = *(current_command+i+1);
161 ++i;
163 sym[i++] = '\0';
164 address = get_address(sym);
165 if(address == 0)
167 address = get_ram_address();
168 add_entry(sym,-1);
170 return address;
172 } else { /* numeric entries */
173 i = 0;
174 while(!isspace(*(current_command+i+1)))
176 sym[i] = *(current_command+i+1);
177 ++i;
179 sym[i++] = '\0';
180 /* value looks like a string of chars must be converted */
181 address = (int)strtol(sym, (char **) NULL, 10);
182 return address;
186 /* TODO: THIS MUST BE CHANGED TO LOOK IN HASH FOR THIS SYMBOL
187 BY NOW IT HAS ALREADY BEEN ADDED TO THE HASH TABLE
189 if(current_command_type == L_COMMAND)
191 if(convert == 0)
193 /* lookup this symbol in hash table and get it's address */
194 i = 0;
195 while(!isspace(*(current_command+i+1)) && *(current_command+i+1) != ')')
197 sym[i] = *(current_command+i+1);
198 ++i;
200 sym[i++] = '\0';
201 return get_address(sym);
202 } else {
203 /* convert numbers into integer and return current symbol as integer */
204 i = 0;
205 while(!isspace(*(current_command+i+1)) && *(current_command+i+1) != ')')
207 sym[i] = *(current_command+i+1);
208 ++i;
210 sym[i++] = '\0';
211 return (int)strtol(sym, (char **) NULL, 10);
214 exit_error(8, "Symbol Function Called on Incorrect Command Type.");
215 return 0;
218 int symbol_load()
220 char sym[MAXCOMMAND];
221 int i = 0;
222 while(!isspace(*(current_command+i+1)) && *(current_command+i+1) != ')')
224 sym[i] = *(current_command+i+1);
225 ++i;
227 sym[i++] = '\0';
228 add_entry(sym, get_rom_address());
229 return 0;
232 int dest(char dest[])
234 int i = 0;
235 int dest_exist = 0;
237 if(current_command_type == C_COMMAND)
239 while(*(current_command+i) != '\n' && *(current_command+i) != '\0')
241 if(*(current_command+i) == '=') { ++dest_exist; }
242 ++i;
244 if(dest_exist == 0) /* no dest in command */
246 dest[0] = '\0';
247 return 1;
249 i = 0;
250 while(*(current_command+i) != '=')
252 dest[i] = *(current_command+i);
253 i++;
255 dest[i] = '\0';
256 return 1;
258 i = find_line_num();
259 line_notification(i);
260 exit_error(8, "Symbol Function Called on Incorrect Command Type.");
261 return 0;
264 int comp(char comp[])
266 int i = 0;
267 int eq_exist = 0;
268 int semi_exist = 0;
269 char *delimiter = NULL;
271 while(*(current_command+i) != '\n' && *(current_command+i) != '\0')
273 if(*(current_command+i) == '=') { ++eq_exist; delimiter = current_command+i; }
274 if(*(current_command+i) == ';') { ++semi_exist; }
275 ++i;
278 if(!semi_exist && !eq_exist)
280 line_notification(i);
281 exit_error(9, "Command Does Not Contain Proper Delimiter.");
282 return 0;
285 if(current_command_type == C_COMMAND)
287 if(eq_exist) /* found '=' in command -- skip to char after equal and copy till new line */
289 i = 0;
290 ++delimiter;
291 while(*(delimiter+i) != ';' && !isspace(*(delimiter+i)) && *(delimiter+i) != '\0')
293 comp[i] = *(delimiter+i);
294 i++;
296 } else { /* no '=' in command -- copy until semicolon found */
297 i = 0;
298 while(*(current_command+i) != ';')
300 comp[i] = *(current_command+i);
301 i++;
304 comp[i] = '\0';
305 return 1;
307 i = find_line_num();
308 line_notification(i);
309 exit_error(8, "Symbol Function Called on Incorrect Command Type.");
310 return 0;
313 int jump(char jump[])
315 int i = 0;
316 char *delimiter = NULL;
317 int valid_command = 0;
318 if(current_command_type == C_COMMAND)
320 /* Test for semicolon before newline char */
321 i = 0;
322 while(*(current_command+i) != '\n' && *(current_command+i) != '\0')
324 if(*(current_command+i) == ';') { ++valid_command; }
325 ++i;
327 if(valid_command == 0)
329 jump[0] = '\0';
330 return 1;
331 } /* no jump in command */
332 delimiter = strchr(current_command, ';');
333 ++delimiter;
334 i = 0;
335 while(!isspace(*(delimiter+i)) && *(delimiter+i) != '\0')
337 jump[i] = *(delimiter+i);
338 ++i;
340 jump[i] = '\0';
341 return 1;
343 i = find_line_num();
344 line_notification(i);
345 exit_error(8, "Symbol Function Called on Incorrect Command Type.");
346 return 0;