Mercurial > hg > index.cgi
comparison lwbasic/compiler.c @ 25:87590f43e76d
Started lwbasic parser; checkpoint
author | lost@l-w.ca |
---|---|
date | Mon, 24 Jan 2011 20:08:09 -0700 |
parents | |
children | 26aa76da75ad |
comparison
equal
deleted
inserted
replaced
24:421d7ceb4d86 | 25:87590f43e76d |
---|---|
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 "lwbasic.h" | |
29 | |
30 /* parse a type; the next token will be acquired as a result */ | |
31 /* the token advancement is to provide consistency */ | |
32 static int parse_type(cstate *state) | |
33 { | |
34 int pt = -1; | |
35 | |
36 switch (state -> lexer_token) | |
37 { | |
38 case token_kw_integer: | |
39 pt = 1; | |
40 break; | |
41 | |
42 default: | |
43 lwb_error("Invalid type specification"); | |
44 } | |
45 lexer(state); | |
46 /* look for "unsigned" modifier for integer types */ | |
47 return pt; | |
48 } | |
49 | |
50 | |
51 /* issub means RETURNS is not allowed; !issub means RETURNS is required */ | |
52 static void parse_subfunc(cstate *state, int issub) | |
53 { | |
54 int pt; | |
55 | |
56 lexer(state); | |
57 if (state -> lexer_token != token_identifier) | |
58 { | |
59 lwb_error("Invalid sub name '%s'", state -> lexer_token_string); | |
60 } | |
61 | |
62 printf("<name> = %s\n", state -> lexer_token_string); | |
63 | |
64 lexer(state); | |
65 if (state -> lexer_token == token_kw_public || state -> lexer_token == token_kw_private) | |
66 { | |
67 printf("<type> = %s\n", state -> lexer_token_string); | |
68 lexer(state); | |
69 } | |
70 | |
71 /* ignore the "PARAMS" keyword if present */ | |
72 if (state -> lexer_token == token_kw_params) | |
73 lexer(state); | |
74 | |
75 if (state -> lexer_token == token_eol) | |
76 goto noparms; | |
77 | |
78 paramagain: | |
79 if (state -> lexer_token != token_identifier) | |
80 { | |
81 lwb_error("Parameter name expected, get %d, %s\n", state -> lexer_token, state -> lexer_token_string); | |
82 } | |
83 printf("Got <param> = %s\n", state -> lexer_token_string); | |
84 lexer(state); | |
85 | |
86 if (state -> lexer_token != token_kw_as) | |
87 lwb_error("Expecting AS\n"); | |
88 lexer(state); | |
89 | |
90 pt = parse_type(state); | |
91 printf("Got <type> = %d\n", pt); | |
92 | |
93 if (state -> lexer_token == token_char && state -> lexer_token_string[0] == ',') | |
94 { | |
95 lexer(state); | |
96 goto paramagain; | |
97 } | |
98 | |
99 noparms: | |
100 if (!issub) | |
101 { | |
102 int rt; | |
103 | |
104 if (state -> lexer_token != token_kw_returns) | |
105 { | |
106 lwb_error("FUNCTION must have RETURNS\n"); | |
107 } | |
108 lexer(state); | |
109 if (state -> lexer_token == token_identifier) | |
110 { | |
111 printf("Return value named: %s\n", state -> lexer_token_string); | |
112 lexer(state); | |
113 if (state -> lexer_token != token_kw_as) | |
114 lwb_error("Execting AS after RETURNS"); | |
115 lexer(state); | |
116 } | |
117 rt = parse_type(state); | |
118 printf("Return type: %d\n", rt); | |
119 } | |
120 else | |
121 { | |
122 if (state -> lexer_token == token_kw_returns) | |
123 { | |
124 lwb_error("SUB cannot specify RETURNS\n"); | |
125 } | |
126 } | |
127 | |
128 | |
129 if (state -> lexer_token != token_eol) | |
130 { | |
131 lwb_error("EOL expected; found %d, %s\n", state -> lexer_token, state -> lexer_token_string); | |
132 } | |
133 } | |
134 | |
135 void compiler(cstate *state) | |
136 { | |
137 state -> lexer_curchar = -1; | |
138 | |
139 /* now look for a global declaration */ | |
140 for (;;) | |
141 { | |
142 state -> parser_state = parser_state_global; | |
143 lexer(state); | |
144 switch (state -> lexer_token) | |
145 { | |
146 case token_kw_function: | |
147 printf("Function\n"); | |
148 parse_subfunc(state, 0); | |
149 break; | |
150 | |
151 case token_kw_sub: | |
152 printf("Sub\n"); | |
153 parse_subfunc(state, 1); | |
154 break; | |
155 | |
156 /* blank lines are allowed */ | |
157 case token_eol: | |
158 continue; | |
159 | |
160 /* EOF is allowed - end of parsing */ | |
161 case token_eof: | |
162 return; | |
163 | |
164 default: | |
165 lwb_error("Invalid token %d, %s in global state\n", state -> lexer_token, state -> lexer_token_string); | |
166 } | |
167 } | |
168 } |