Mercurial > hg > index.cgi
comparison lwbasic/parser.c @ 32:49d608aecc4d
Framework for handling local stack frame and/or variables
author | lost@l-w.ca |
---|---|
date | Thu, 03 Feb 2011 22:00:47 -0700 |
parents | 574931d87abd |
children | 890a8f688889 |
comparison
equal
deleted
inserted
replaced
31:574931d87abd | 32:49d608aecc4d |
---|---|
27 | 27 |
28 #include <lw_alloc.h> | 28 #include <lw_alloc.h> |
29 #include <lw_string.h> | 29 #include <lw_string.h> |
30 | 30 |
31 #include "lwbasic.h" | 31 #include "lwbasic.h" |
32 #include "symtab.h" | |
33 | |
34 | |
35 /* size of a type */ | |
36 static int sizeof_type(int type) | |
37 { | |
38 /* everything is an "int" right now; 2 bytes */ | |
39 return 2; | |
40 } | |
32 | 41 |
33 /* parse a type; the next token will be acquired as a result */ | 42 /* parse a type; the next token will be acquired as a result */ |
34 /* the token advancement is to provide consistency */ | 43 /* the token advancement is to provide consistency */ |
35 static int parse_type(cstate *state) | 44 static int parse_type(cstate *state) |
36 { | 45 { |
48 lexer(state); | 57 lexer(state); |
49 /* look for "unsigned" modifier for integer types */ | 58 /* look for "unsigned" modifier for integer types */ |
50 return pt; | 59 return pt; |
51 } | 60 } |
52 | 61 |
62 static void parse_decls(cstate *state) | |
63 { | |
64 /* declarations */ | |
65 switch (state -> lexer_token) | |
66 { | |
67 default: | |
68 return; | |
69 } | |
70 } | |
71 | |
53 | 72 |
54 /* issub means RETURNS is not allowed; !issub means RETURNS is required */ | 73 /* issub means RETURNS is not allowed; !issub means RETURNS is required */ |
74 | |
55 static void parse_subfunc(cstate *state, int issub) | 75 static void parse_subfunc(cstate *state, int issub) |
56 { | 76 { |
57 int pt; | 77 int pt, rt; |
58 char *subname; | 78 char *subname, *pn; |
59 int vis = 0; | 79 int vis = 0; |
60 | 80 symtab_entry_t *se; |
81 int paramsize = 0; | |
82 | |
83 state -> local_syms = symtab_init(); | |
84 state -> framesize = 0; | |
85 | |
61 lexer(state); | 86 lexer(state); |
62 if (state -> lexer_token != token_identifier) | 87 if (state -> lexer_token != token_identifier) |
63 { | 88 { |
64 lwb_error("Invalid sub name '%s'", state -> lexer_token_string); | 89 lwb_error("Invalid sub name '%s'", state -> lexer_token_string); |
65 } | 90 } |
84 paramagain: | 109 paramagain: |
85 if (state -> lexer_token != token_identifier) | 110 if (state -> lexer_token != token_identifier) |
86 { | 111 { |
87 lwb_error("Parameter name expected, got %s\n", lexer_return_token(state)); | 112 lwb_error("Parameter name expected, got %s\n", lexer_return_token(state)); |
88 } | 113 } |
89 printf("Got <param> = %s\n", state -> lexer_token_string); | 114 pn = lw_strdup(state -> lexer_token_string); |
90 lexer(state); | 115 lexer(state); |
91 | 116 |
92 if (state -> lexer_token != token_kw_as) | 117 if (state -> lexer_token != token_kw_as) |
93 lwb_error("Expecting AS\n"); | 118 lwb_error("Expecting AS\n"); |
94 lexer(state); | 119 lexer(state); |
95 | 120 |
96 pt = parse_type(state); | 121 pt = parse_type(state); |
97 printf("Got <type> = %d\n", pt); | 122 |
123 se = symtab_find(state -> local_syms, pn); | |
124 if (se) | |
125 { | |
126 lwb_error("Duplicate parameter name %s\n", pn); | |
127 } | |
128 symtab_register(state -> local_syms, pn, paramsize, symtype_param, NULL); | |
129 paramsize += sizeof_type(pt); | |
130 lw_free(pn); | |
98 | 131 |
99 if (state -> lexer_token == token_char && state -> lexer_token_string[0] == ',') | 132 if (state -> lexer_token == token_char && state -> lexer_token_string[0] == ',') |
100 { | 133 { |
101 lexer(state); | 134 lexer(state); |
102 goto paramagain; | 135 goto paramagain; |
103 } | 136 } |
104 | 137 |
105 noparms: | 138 noparms: |
139 rt = -1; | |
106 if (!issub) | 140 if (!issub) |
107 { | 141 { |
108 int rt; | |
109 | |
110 if (state -> lexer_token != token_kw_returns) | 142 if (state -> lexer_token != token_kw_returns) |
111 { | 143 { |
112 lwb_error("FUNCTION must have RETURNS\n"); | 144 lwb_error("FUNCTION must have RETURNS\n"); |
113 } | 145 } |
114 lexer(state); | 146 lexer(state); |
115 if (state -> lexer_token == token_identifier) | 147 /* if (state -> lexer_token == token_identifier) |
116 { | 148 { |
117 printf("Return value named: %s\n", state -> lexer_token_string); | 149 printf("Return value named: %s\n", state -> lexer_token_string); |
150 | |
118 lexer(state); | 151 lexer(state); |
119 if (state -> lexer_token != token_kw_as) | 152 if (state -> lexer_token != token_kw_as) |
120 lwb_error("Execting AS after RETURNS"); | 153 lwb_error("Execting AS after RETURNS"); |
121 lexer(state); | 154 lexer(state); |
122 } | 155 } |
156 */ | |
123 rt = parse_type(state); | 157 rt = parse_type(state); |
124 printf("Return type: %d\n", rt); | |
125 } | 158 } |
126 else | 159 else |
127 { | 160 { |
128 if (state -> lexer_token == token_kw_returns) | 161 if (state -> lexer_token == token_kw_returns) |
129 { | 162 { |
136 { | 169 { |
137 lwb_error("EOL expected; found %s\n", lexer_return_token(state)); | 170 lwb_error("EOL expected; found %s\n", lexer_return_token(state)); |
138 } | 171 } |
139 | 172 |
140 | 173 |
141 printf("Sub/Func %s, vis %s\n", subname, vis ? "public" : "private"); | 174 se = symtab_find(state -> global_syms, subname); |
175 if (se) | |
176 { | |
177 lwb_error("Multiply defined symbol %s\n", subname); | |
178 } | |
179 | |
180 symtab_register(state -> global_syms, subname, -1, issub ? symtype_sub : symtype_func, NULL); | |
142 | 181 |
143 state -> currentsub = subname; | 182 state -> currentsub = subname; |
144 | 183 state -> returntype = rt; |
145 /* consume EOL */ | 184 /* consume EOL */ |
146 lexer(state); | 185 lexer(state); |
147 | 186 |
148 /* variable declarations */ | 187 /* variable declarations */ |
149 /* parse_decls(state); */ | 188 parse_decls(state); |
150 | 189 |
151 /* output function/sub prolog */ | 190 /* output function/sub prolog */ |
152 emit_prolog(state, vis, 0); | 191 emit_prolog(state, vis); |
153 | 192 |
154 /* parse statement block */ | 193 /* parse statement block */ |
155 /* parse_statemetns(state); */ | 194 /* parse_statements(state); */ |
156 | 195 |
157 if (issub) | 196 if (issub) |
158 { | 197 { |
159 if (state -> lexer_token != token_kw_endsub) | 198 if (state -> lexer_token != token_kw_endsub) |
160 { | 199 { |
167 { | 206 { |
168 lwb_error("Expecting ENDFUNCTION, got %s\n", lexer_return_token(state)); | 207 lwb_error("Expecting ENDFUNCTION, got %s\n", lexer_return_token(state)); |
169 } | 208 } |
170 } | 209 } |
171 /* output function/sub epilog */ | 210 /* output function/sub epilog */ |
172 emit_epilog(state, 0); | 211 emit_epilog(state); |
173 | 212 |
174 lw_free(state -> currentsub); | 213 lw_free(state -> currentsub); |
175 state -> currentsub = NULL; | 214 state -> currentsub = NULL; |
176 | 215 symtab_destroy(state -> local_syms); |
216 state -> local_syms = NULL; | |
177 } | 217 } |
178 | 218 |
179 void parser(cstate *state) | 219 void parser(cstate *state) |
180 { | 220 { |
181 state -> lexer_curchar = -1; | 221 state -> lexer_curchar = -1; |
182 | 222 state -> global_syms = symtab_init(); |
223 | |
183 /* now look for a global declaration */ | 224 /* now look for a global declaration */ |
184 for (;;) | 225 for (;;) |
185 { | 226 { |
186 state -> parser_state = parser_state_global; | 227 state -> parser_state = parser_state_global; |
187 lexer(state); | 228 lexer(state); |