Updated link in README file.
[Hack-Assembler.git] / asm.c
blob12d7e1670a84e6dfaf8b635fec646c214beb654b
1 #include <ctype.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
6 #include "asm.h"
7 #include "code.h"
8 #include "error.h"
9 #include "parse.h"
10 #include "symbol.h"
12 #define MAXOUTBUFF 10000
14 struct settings settings;
16 void usage(void)
18 printf("\n<options> <file>\n");
19 printf("<file> Filename to assemble.\n");
20 printf(" Filename must end with .asm.\n");
21 printf("-C Print code output to stdout - with comments.\n");
22 printf("-c Print code output to stdout - without comments.\n");
23 printf("-t Print final hash table to stdout.\n");
24 printf("-v Verbose output to stdout.\n");
25 printf("-x Print commands to stdout.\n\n");
28 void settings_init(void)
30 settings.verbose = 0;
31 settings.verbose = 0;
32 settings.hash = 0;
33 settings.code = 0;
34 settings.comments = 0;
35 settings.commands = 0;
38 int main(int argc, char *argv[])
40 char FilenameBuff[80];
41 register int i = 0;
42 int address = 0;
43 int c;
45 settings_init();
47 if(argc <2) { usage(); return 0;}
49 while(-1 != (c = getopt(argc, argv,
50 "-v" /* verbose output to stdout */
51 "-t" /* print final hash table to stdout */
52 "-c" /* print code output to stdout - without comments */
53 "-C" /* print code output to stdout - with comments */
54 "-x" /* print commands to stdout */
55 "--help" /*print out usage statement */
56 ))) {
58 switch (c)
60 case 'v':
61 settings.verbose = 1;
62 settings.hash = 1;
63 settings.code = 1;
64 settings.comments = 1;
65 settings.commands = 1;
66 break;
67 case 't':
68 settings.hash = 1;
69 break;
70 case 'c':
71 settings.code = 1;
72 break;
73 case 'C':
74 settings.code = 1;
75 settings.comments = 1;
76 break;
77 case 'x':
78 settings.commands = 1;
79 break;
83 /* find path location */
84 if(argv[1][0] == '-') { c = 2; } else { c = 1; }
86 if(argc < 2) { exit_error(1, "No Input Files."); usage(); }
87 /* TODO: future versions will accept more than one file */
88 if(argc > 3) { exit_error(2, "Too Many Files Listed."); usage(); }
90 strcpy(FilenameBuff, argv[c]);
92 /* verify filename extension */
93 i = strlen(argv[c]) - 1;
94 if( (argv[c][i-2] != 'a') ||
95 (argv[c][i-1] != 's') ||
96 (argv[c][i] != 'm' ) ) { exit_error(5, "Filename Extension Not Correct."); usage(); }
98 init_parser(FilenameBuff);
100 /* modify filename to output filename and then open file */
101 FilenameBuff[i-2] = 'h';
102 FilenameBuff[i-1] = 'a';
103 FilenameBuff[i] = 'c';
104 FilenameBuff[i+1] = 'k';
105 FilenameBuff[i+2] = '\0';
107 /* load symbol table with pre-defined symbols */
108 add_entry("SP", 0);
109 add_entry("LCL", 1);
110 add_entry("ARG", 2);
111 add_entry("THIS", 3);
112 add_entry("THAT", 4);
113 add_entry("SCREEN", 16384);
114 add_entry("KBD", 24576);
116 add_entry("R0", 0);
117 add_entry("R1", 1);
118 add_entry("R2", 2);
119 add_entry("R3", 3);
120 add_entry("R4", 4);
121 add_entry("R5", 5);
122 add_entry("R6", 6);
123 add_entry("R7", 7);
124 add_entry("R8", 8);
125 add_entry("R9", 9);
126 add_entry("R10", 10);
127 add_entry("R11", 11);
128 add_entry("R12", 12);
129 add_entry("R13", 13);
130 add_entry("R14", 14);
131 add_entry("R15", 15);
133 while(has_more_commands())
135 advance();
136 if(command_type() == A_COMMAND || command_type() == C_COMMAND)
137 inc_rom_address();
138 if(command_type() == L_COMMAND)
139 symbol_load();
142 init_coder(FilenameBuff);
143 reset_buffer();
145 while(has_more_commands())
147 char sym[MAXCOMMAND];
149 advance();
150 if(command_type() == A_COMMAND || command_type() == L_COMMAND)
152 address = symbol(sym);
153 if(command_type() == A_COMMAND) { enc_symbol(address); }
156 if(command_type() == C_COMMAND)
158 if(comp(sym) != 0) { enc_comp(sym); }
159 if(dest(sym) != 0) { enc_dest(sym); }
160 if(jump(sym) != 0) { enc_jump(sym); }
162 if(command_type() != L_COMMAND)
164 advance_ouptut_file();
165 if(settings.code != 0 || settings.comments != 0 ) { printf(" "); }
166 } else {
167 if(settings.code != 0 || settings.comments != 0)
169 printf(" ");
173 if(settings.commands != 0) { print_current_command(); }
174 if((settings.code == 0 || settings.comments == 0) && argc > 2) { printf("\n"); }
177 if(settings.hash != 0) { print_hash(); }
178 return 0;