36
|
1 /*
|
|
2 parse.c
|
|
3 Copyright © 2008 William Astle
|
|
4
|
|
5 This file is part of LWASM.
|
|
6
|
|
7 LWASM is free software: you can redistribute it and/or modify it under the
|
|
8 terms of the GNU General Public License as published by the Free Software
|
|
9 Foundation, either version 3 of the License, or (at your option) any later
|
|
10 version.
|
|
11
|
|
12 This program is distributed in the hope that it will be useful, but WITHOUT
|
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
15 more details.
|
|
16
|
|
17 You should have received a copy of the GNU General Public License along with
|
|
18 this program. If not, see <http://www.gnu.org/licenses/>.
|
|
19 */
|
|
20
|
|
21 /*
|
|
22 Contains the general parser
|
|
23 */
|
|
24
|
|
25 #define __parse_c_seen__
|
|
26
|
|
27 #include <ctype.h>
|
|
28 #include <string.h>
|
|
29
|
|
30 #include "lwasm.h"
|
|
31 #include "instab.h"
|
|
32 #include "util.h"
|
|
33
|
|
34 // parse a line and despatch to the appropriate handlers for opcodes
|
|
35 int lwasm_parse_line(asmstate_t *as, lwasm_line_t *l)
|
|
36 {
|
|
37 char *p, *p2;
|
|
38 char *opc;
|
|
39 int opnum;
|
|
40
|
|
41 p = l -> text;
|
|
42
|
|
43 if (!*p)
|
|
44 return 0;
|
|
45
|
|
46 if (!isspace(*p) && *p != '*' && *p != ';')
|
|
47 {
|
|
48 // we have a symbol specified here
|
|
49 // parse it and define
|
|
50 // need to handle local symbols here...
|
|
51 }
|
|
52
|
|
53 // skip white space
|
|
54 while (*p && isspace(*p))
|
|
55 p++;
|
|
56
|
|
57 // if comment or end of line, return
|
|
58 if (!*p || *p == '*' || *p == ';')
|
|
59 return 0;
|
|
60
|
|
61 // parse the opcode
|
|
62 for (p2 = p; *p2 && !isspace(*p2); p2++)
|
|
63 /* do nothing */ ;
|
|
64
|
|
65 opc = lwasm_alloc((p2 - p) + 1);
|
|
66 memcpy(opc, p, p2 - p);
|
|
67 opc[p2 - p] = '\0';
|
|
68
|
|
69 // skip intervening whitespace if present
|
|
70 while (*p2 && isspace(*p2))
|
|
71 p2++;
|
|
72
|
|
73 // check for macro (pass 1)
|
|
74
|
|
75 // look up instruction in insn table
|
|
76 for (opnum = 0; instab[opnum].opcode; opnum++)
|
|
77 {
|
|
78 if (!strcasecmp(instab[opnum].opcode, opc))
|
|
79 break;
|
|
80 }
|
|
81
|
|
82 if (!(instab[opnum].opcode) || !(instab[opnum].fn))
|
|
83 {
|
|
84 // invalid operation code, throw error
|
|
85 register_error(as, l, 1, "Invalid operation code '%s'", opc);
|
|
86 lwasm_free(opc);
|
|
87 return -1;
|
|
88 }
|
|
89
|
|
90 // dispatch handler
|
|
91 (instab[opnum].fn)(as, l, &p2, opnum);
|
|
92
|
|
93 lwasm_free(opc);
|
|
94 }
|