comparison lwasm/pass1.c @ 151:427e268e876b

renamed src to lwasm to better reflect its purpose
author lost
date Fri, 30 Jan 2009 04:01:55 +0000
parents src/pass1.c@11d38c9e5095
children bae1e3ecdce1
comparison
equal deleted inserted replaced
150:f0881c115010 151:427e268e876b
1 /*
2 pass1.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 Handles first pass of assembly
22
23 First pass involves the following:
24
25 1. read all lines from the main source file, following all "include"
26 directives as appropriate
27 2. each operand is evaluated for syntax and futher for value if there are
28 multiple addressing sizes available; any undefined or not fully resolved
29 value will default to the largest addressing size available (16 bit)
30 3. addresses are assigned to every symbol defined in the assembly
31 4. macros are defined and expanded at this pass
32
33 * note: the lines are re-evaluated on the second pass
34
35 All source lines are read into memory with a record of the file name and
36 line number within the files.
37
38 Lines are one of the following formats:
39
40 <symbol> <opcode> <operand> <comment>
41 <symbol> <opcode> <comment>
42 <opcode> <operand> <comment>
43 <opcode> <comment>
44
45 A "*" or ";" appearing anywhere on the line that is not otherwise interpreted
46 as part of an operation code or operand introduces a comment.
47
48 Certain lwasm specific operations are prefixed with a "*" to aid in source
49 code portability (like *pragma).
50 */
51
52 #ifdef HAVE_CONFIG_H
53 #include "config.h"
54 #endif
55
56 #include <errno.h>
57 #include <stdio.h>
58 #include <stdlib.h>
59
60 #include "lwasm.h"
61 #include "util.h"
62
63
64 extern int lwasm_parse_line(asmstate_t *as, lwasm_line_t *l);
65
66 // we can't use standard line inputting functions here because we have to
67 // handle non-standard line terminations (CR, LF, CRLF, or LFCR)
68 int lwasm_read_file(asmstate_t *as, const char *filename)
69 {
70 FILE *f;
71 int c, c2;
72 lwasm_line_t *nl;
73 int lineno = 1;
74 char *fnref;
75
76 // ought to be long enough...we truncate longer lines
77 char linebuff[2049];
78 int lbloc = 0;
79 int eol = 0;
80
81 // add filename to list
82 as -> filelist = lwasm_realloc(as -> filelist, sizeof(char *) * (as -> filelistlen + 1));
83 fnref = as -> filelist[as -> filelistlen] = lwasm_strdup(filename);
84 as -> filelistlen += 1;
85
86 f = fopen(filename, "rb");
87 if (!f)
88 return -1;
89
90 for (;;)
91 {
92 c = fgetc(f);
93 if (c == EOF)
94 {
95 linebuff[lbloc] = '\0';
96 eol = 1;
97 }
98 else if (c == '\r')
99 {
100 linebuff[lbloc] = '\0';
101 eol = 1;
102 // check for '\n':
103 c2 = fgetc(f);
104 if (c2 == EOF)
105 c = EOF;
106 else if (c2 != '\n')
107 ungetc(c2, f);
108 }
109 else if (c == '\n')
110 {
111 linebuff[lbloc] = '\0';
112 eol = 1;
113 // check for '\r':
114 c2 = fgetc(f);
115 if (c2 == EOF)
116 c = EOF;
117 else if (c2 != '\r')
118 ungetc(c2, f);
119 }
120 else
121 {
122 // silently ignore characters past 2K on a line... FIXME
123 if (lbloc < 2048)
124 linebuff[lbloc++] = c;
125 }
126 if (eol)
127 {
128 eol = 0;
129 lbloc = 0;
130 nl = lwasm_alloc(sizeof(lwasm_line_t));
131 nl -> text = lwasm_strdup(linebuff);
132 nl -> lineno = lineno++;
133 nl -> filename = fnref;
134 nl -> next = NULL;
135 nl -> prev = as -> linestail;
136 nl -> err = NULL;
137 nl -> fsize = 0;
138 nl -> sym = NULL;
139 nl -> bytes = NULL;
140 nl -> codelen = 0;
141 nl -> codesize = 0;
142 nl -> nocodelen = 0;
143 nl -> addrset = 0;
144 nl -> symaddr = -1;
145 nl -> badop = 0;
146 nl -> relocoff = -1;
147 if (as -> linestail)
148 as -> linestail -> next = nl;
149 as -> linestail = nl;
150 if (!(as -> lineshead))
151 as -> lineshead = nl;
152 lwasm_parse_line(as, nl);
153 if (as -> endseen)
154 break;
155 }
156 if (c == EOF)
157 break;
158 }
159
160 fclose(f);
161 return 0;
162 }
163
164 void lwasm_pass1(asmstate_t *as)
165 {
166 as -> passnum = 1;
167 as -> addr = 0;
168 as -> nextcontext = 1;
169
170 debug_message(1, "Entering pass 1");
171 if (lwasm_read_file(as, as -> infile) < 0)
172 {
173 fprintf(stderr, "Error reading input file '%s'", as -> infile);
174 perror("");
175 exit(1);
176 }
177
178 }