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);