Mercurial > hg > index.cgi
comparison lwbasic/parser.c @ 30:bcd532a90e53
Renamed "compiler" to "parser" for more consistent terminology
author | lost@l-w.ca |
---|---|
date | Thu, 03 Feb 2011 21:19:11 -0700 |
parents | lwbasic/compiler.c@77626fc37af2 |
children | 574931d87abd |
comparison
equal
deleted
inserted
replaced
29:bc96cd02fbf4 | 30:bcd532a90e53 |
---|---|
1 /* | |
2 compiler.c | |
3 | |
4 Copyright © 2011 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
22 /* | |
23 This is the actual compiler bit; it drives the parser and code generation | |
24 */ | |
25 | |
26 #include <stdio.h> | |
27 | |
28 #include <lw_alloc.h> | |
29 #include <lw_string.h> | |
30 | |
31 #include "lwbasic.h" | |
32 | |
33 /* parse a type; the next token will be acquired as a result */ | |
34 /* the token advancement is to provide consistency */ | |
35 static int parse_type(cstate *state) | |
36 { | |
37 int pt = -1; | |
38 | |
39 switch (state -> lexer_token) | |
40 { | |
41 case token_kw_integer: | |
42 pt = 1; | |
43 break; | |
44 | |
45 default: | |
46 lwb_error("Invalid type specification"); | |
47 } | |
48 lexer(state); | |
49 /* look for "unsigned" modifier for integer types */ | |
50 return pt; | |
51 } | |
52 | |
53 | |
54 /* issub means RETURNS is not allowed; !issub means RETURNS is required */ | |
55 static void parse_subfunc(cstate *state, int issub) | |
56 { | |
57 int pt; | |
58 char *subname; | |
59 int vis = 0; | |
60 | |
61 lexer(state); | |
62 if (state -> lexer_token != token_identifier) | |
63 { | |
64 lwb_error("Invalid sub name '%s'", state -> lexer_token_string); | |
65 } | |
66 | |
67 subname = lw_strdup(state -> lexer_token_string); | |
68 | |
69 lexer(state); | |
70 if (state -> lexer_token == token_kw_public || state -> lexer_token == token_kw_private) | |
71 { | |
72 if (state -> lexer_token == token_kw_public) | |
73 vis = 1; | |
74 lexer(state); | |
75 } | |
76 | |
77 /* ignore the "PARAMS" keyword if present */ | |
78 if (state -> lexer_token == token_kw_params) | |
79 lexer(state); | |
80 | |
81 if (state -> lexer_token == token_eol || state -> lexer_token == token_kw_returns) | |
82 goto noparms; | |
83 | |
84 paramagain: | |
85 if (state -> lexer_token != token_identifier) | |
86 { | |
87 lwb_error("Parameter name expected, got %d, %s\n", state -> lexer_token, state -> lexer_token_string); | |
88 } | |
89 printf("Got <param> = %s\n", state -> lexer_token_string); | |
90 lexer(state); | |
91 | |
92 if (state -> lexer_token != token_kw_as) | |
93 lwb_error("Expecting AS\n"); | |
94 lexer(state); | |
95 | |
96 pt = parse_type(state); | |
97 printf("Got <type> = %d\n", pt); | |
98 | |
99 if (state -> lexer_token == token_char && state -> lexer_token_string[0] == ',') | |
100 { | |
101 lexer(state); | |
102 goto paramagain; | |
103 } | |
104 | |
105 noparms: | |
106 if (!issub) | |
107 { | |
108 int rt; | |
109 | |
110 if (state -> lexer_token != token_kw_returns) | |
111 { | |
112 lwb_error("FUNCTION must have RETURNS\n"); | |
113 } | |
114 lexer(state); | |
115 if (state -> lexer_token == token_identifier) | |
116 { | |
117 printf("Return value named: %s\n", state -> lexer_token_string); | |
118 lexer(state); | |
119 if (state -> lexer_token != token_kw_as) | |
120 lwb_error("Execting AS after RETURNS"); | |
121 lexer(state); | |
122 } | |
123 rt = parse_type(state); | |
124 printf("Return type: %d\n", rt); | |
125 } | |
126 else | |
127 { | |
128 if (state -> lexer_token == token_kw_returns) | |
129 { | |
130 lwb_error("SUB cannot specify RETURNS\n"); | |
131 } | |
132 } | |
133 | |
134 | |
135 if (state -> lexer_token != token_eol) | |
136 { | |
137 lwb_error("EOL expected; found %d, %s\n", state -> lexer_token, state -> lexer_token_string); | |
138 } | |
139 | |
140 | |
141 printf("Sub/Func %s, vis %s\n", subname, vis ? "public" : "private"); | |
142 | |
143 state -> currentsub = subname; | |
144 | |
145 /* consume EOL */ | |
146 lexer(state); | |
147 | |
148 /* variable declarations */ | |
149 /* parse_decls(state); */ | |
150 | |
151 /* output function/sub prolog */ | |
152 emit_prolog(state, vis, 0); | |
153 | |
154 /* parse statement block */ | |
155 /* parse_statemetns(state); */ | |
156 | |
157 if (issub) | |
158 { | |
159 if (state -> lexer_token != token_kw_endsub) | |
160 { | |
161 lwb_error("Expecting ENDSUB, got %d (%s)\n", state -> lexer_token, state -> lexer_token_string); | |
162 } | |
163 } | |
164 else | |
165 { | |
166 if (state -> lexer_token != token_kw_endfunction) | |
167 { | |
168 lwb_error("Expecting ENDFUNCTION, got %d (%s)\n", state -> lexer_token, state -> lexer_token_string); | |
169 } | |
170 } | |
171 /* output function/sub epilog */ | |
172 emit_epilog(state, 0); | |
173 | |
174 lw_free(state -> currentsub); | |
175 state -> currentsub = NULL; | |
176 | |
177 } | |
178 | |
179 void parser(cstate *state) | |
180 { | |
181 state -> lexer_curchar = -1; | |
182 | |
183 /* now look for a global declaration */ | |
184 for (;;) | |
185 { | |
186 state -> parser_state = parser_state_global; | |
187 lexer(state); | |
188 switch (state -> lexer_token) | |
189 { | |
190 case token_kw_function: | |
191 printf("Function\n"); | |
192 parse_subfunc(state, 0); | |
193 break; | |
194 | |
195 case token_kw_sub: | |
196 printf("Sub\n"); | |
197 parse_subfunc(state, 1); | |
198 break; | |
199 | |
200 /* blank lines are allowed */ | |
201 case token_eol: | |
202 continue; | |
203 | |
204 /* EOF is allowed - end of parsing */ | |
205 case token_eof: | |
206 return; | |
207 | |
208 default: | |
209 lwb_error("Invalid token %d, %s in global state\n", state -> lexer_token, state -> lexer_token_string); | |
210 } | |
211 } | |
212 } |