comparison lwasm/pass1.c @ 340:1a6fc6ebb31c

Checkpoint
author lost
date Fri, 19 Mar 2010 02:54:43 +0000
parents 04c80c51b16a
children 7b4123dce741
comparison
equal deleted inserted replaced
339:eb230fa7d28e 340:1a6fc6ebb31c
28 #include "lwasm.h" 28 #include "lwasm.h"
29 #include "input.h" 29 #include "input.h"
30 30
31 /* 31 /*
32 pass 1: parse the lines 32 pass 1: parse the lines
33
34 line format:
35
36 [<symbol>] <opcode> <operand>[ <comment>]
37
38 If <symbol> is followed by a :, whitespace may precede the symbol
39
40 A line may optionally start with a number which must not be preceded by
41 white space and must be followed by a single whitespace character. After
42 that whitespace character, the line is parsed as if it had no line number.
43
33 */ 44 */
34 void do_pass1(asmstate_t *as) 45 void do_pass1(asmstate_t *as)
35 { 46 {
36 char *line; 47 char *line;
37 line_t *cl; 48 line_t *cl;
38 49 char *p1;
50 int stpace;
51 char *tok, *sym;
52 int opnum;
53
39 for (;;) 54 for (;;)
40 { 55 {
56 sym = NULL;
41 line = input_readline(as); 57 line = input_readline(as);
42 if (!line) 58 if (!line)
43 break; 59 break;
44 printf("%s\n", line); 60 printf("%s\n", line);
45 61
62 lw_expr_destroy(te); 78 lw_expr_destroy(te);
63 lw_expr_simplify(cl -> addr); 79 lw_expr_simplify(cl -> addr);
64 } 80 }
65 as -> line_tail = cl; 81 as -> line_tail = cl;
66 82
83 // blank lines don't count for anything
84 if (!*line)
85 {
86 goto nextline;
87 }
88
89 // skip comments
90 if (*line == '*' || *line == ';' || *line == '#')
91 goto nextline;
92
93 p1 = line;
94 if (isdigit(*p1))
95 {
96 // skip line number
97 while (*p1 && isdigit(*p1))
98 p1++;
99 if (!*p1 && !isspace(*p1))
100 p1 = line;
101 else if (*p1 && isspace(*p1))
102 p1++;
103 }
104
105 if (!*p1)
106 goto nextline;
107
108 if (*p1 == '*' || *p1 == ';' || *p1 == '#')
109 goto nextline;
110
111 if (isspace(*p1))
112 {
113 for (; *p1 && isspace(*p1); p1++)
114 /* do nothing */ ;
115 stspace = 1;
116 }
117 else
118 stspace = 0;
119
120 if (*p1 == '*' || *p1 == ';' || *p1 == '#' || !*p1)
121 goto nextline;
122
123
124 for (tok = p1; *p1 && !isspace(*p1) && *p1 != ':'; p1++)
125 /* do nothing */ ;
126
127 if (*p1 == ':' || stspace == 0)
128 {
129 // have a symbol here
130 sym = lw_strndup(tok, p1 - tok);
131 if (*p1 == ':')
132 p1++;
133 for (; *p1 && isspace(*p1); p1++)
134 /* do nothing */ ;
135
136 for (tok = p1; *p1 && !isspace(*p1); p1++)
137 /* do nothing */ ;
138 }
139
140 cl -> sym = sym;
141 cl -> symset = 0;
142
143 // tok points to the opcode for the line or NUL if none
144 if (*tok)
145 {
146 // look up operation code
147 sym = lw_strndup(tok, p1 - tok);
148 for (; *p1 && isspace(p1); p1++)
149 /* do nothing */ ;
150
151 for (opnum = 0; instab[opnum].opcode; opnum++)
152 {
153 if (!strcasecmp(instab[opnum].opcode, sym))
154 break;
155 }
156 lw_free(sym);
157
158 // p1 points to the start of the operand
159
160 if (instab[opnum].opcode == NULL)
161 {
162 cl -> insn = -1;
163 if (*tok != ';' && *tok != '*')
164 {
165 // bad opcode; check for macro here
166 }
167 }
168 else
169 {
170 cl -> insn = opnum;
171 // call parse function
172
173 if (*p1 && !isspace(*p1))
174 {
175 // flag bad operand error
176 }
177 }
178 }
179
180 if (cl -> sym && cl -> symset == 0)
181 {
182 // register symbol at line address
183 }
184
67 lw_expr_print(cl -> addr); 185 lw_expr_print(cl -> addr);
68 printf("\n"); 186 printf("\n");
69 // now parse the line 187 // now parse the line
70 188
189 nextline:
71 lw_free(line); 190 lw_free(line);
72 } 191 }
73 } 192 }