annotate lwbasic/attic/parser.c @ 207:07e1fac76321

Added pragma to allow non case sensitive symbols Added "nosymbolcase" and "symbolnocase" pragmas to cause symbols defined while the pragma is in effect to be treated as case insensitive. Also documented the new pragma.
author William Astle <lost@l-w.ca>
date Sat, 09 Jun 2012 15:47:22 -0600
parents cca933d32298
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
1 /*
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
2 compiler.c
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
3
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
4 Copyright © 2011 William Astle
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
5
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
6 This file is part of LWTOOLS.
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
7
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
8 LWTOOLS is free software: you can redistribute it and/or modify it under the
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
9 terms of the GNU General Public License as published by the Free Software
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
10 Foundation, either version 3 of the License, or (at your option) any later
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
11 version.
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
12
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
13 This program is distributed in the hope that it will be useful, but WITHOUT
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
16 more details.
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
17
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
18 You should have received a copy of the GNU General Public License along with
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
19 this program. If not, see <http://www.gnu.org/licenses/>.
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
20 */
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
21
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
22 /*
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
23 This is the actual compiler bit; it drives the parser and code generation
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
24 */
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
26 #include <stdio.h>
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
27
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
28 #include <lw_alloc.h>
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
29 #include <lw_string.h>
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
30
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
31 #include "lwbasic.h"
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
32 #include "symtab.h"
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
33
34
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
34 static void expect(cstate *state, int tt)
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
35 {
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
36 if (state -> lexer_token != tt)
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
37 lwb_error("Expecting %s, got %s\n", lexer_token_name(tt), lexer_return_token(state));
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
38 lexer(state);
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
39 }
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
40
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
41
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
42 /* size of a type */
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
43 static int sizeof_type(int type)
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
44 {
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
45 /* everything is an "int" right now; 2 bytes */
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
46 return 2;
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
47 }
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
48
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
49 /* parse a type; the next token will be acquired as a result */
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
50 /* the token advancement is to provide consistency */
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
51 static int parse_type(cstate *state)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
52 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
53 int pt = -1;
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
54
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
55 switch (state -> lexer_token)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
56 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
57 case token_kw_integer:
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
58 pt = 1;
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
59 break;
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
60
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
61 default:
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
62 lwb_error("Invalid type specification");
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
63 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
64 lexer(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
65 /* look for "unsigned" modifier for integer types */
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
66 return pt;
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
67 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
68
36
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
69 static void parse_expr(cstate *state, int prec);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
70 static void parse_term(cstate *state);
35
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
71 static int parse_expression(cstate *state)
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
72 {
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
73 state -> expression = 1;
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
74
36
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
75 parse_expr(state, 0);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
76
35
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
77 state -> expression = 0;
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
78 return 1;
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
79 }
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
80
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
81 static void parse_decls(cstate *state)
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
82 {
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
83 /* declarations */
33
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
84 /* the first thing that doesn't look like a declaration is assumed */
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
85 /* to be a statement and will trigger a bailout */
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
86 int vt;
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
87 char *vn;
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
88 symtab_entry_t *se;
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
89
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
90 for (;;)
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
91 {
33
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
92 switch (state -> lexer_token)
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
93 {
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
94 /* DIM keyword */
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
95 case token_kw_dim:
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
96 lexer(state);
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
97 if (state -> lexer_token != token_identifier)
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
98 {
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
99 lwb_error("Expecting identifier, got %s\n", lexer_return_token(state));
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
100 }
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
101 vn = lw_strdup(state -> lexer_token_string);
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
102 lexer(state);
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
103 if (state -> lexer_token != token_kw_as)
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
104 {
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
105 lwb_error("Expecting AS, got %s\n", lexer_return_token(state));
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
106 }
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
107 lexer(state);
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
108 vt = parse_type(state);
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
109
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
110 se = symtab_find(state -> local_syms, vn);
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
111 if (se)
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
112 {
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
113 lwb_error("Multiply defined local variable %s", vn);
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
114 }
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
115 state -> framesize += sizeof_type(vt);
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
116 symtab_register(state -> local_syms, vn, -(state -> framesize), symtype_var, NULL);
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
117
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
118 lw_free(vn);
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
119 break;
34
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
120
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
121 /* blank lines allowed */
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
122 case token_eol:
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
123 break;
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
124
33
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
125 default:
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
126 return;
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
127 }
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
128 if (state -> lexer_token != token_eol)
34
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
129 lwb_error("Expecting end of line; got %s\n", lexer_return_token(state));
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
130 lexer(state);
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
131 }
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
132 }
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
133
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
134 static void parse_statements(cstate *state)
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
135 {
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
136 symtab_entry_t *se;
35
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
137 int et;
34
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
138
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
139 for (;;)
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
140 {
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
141 switch (state -> lexer_token)
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
142 {
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
143 /* blank lines allowed */
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
144 case token_eol:
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
145 break;
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
146
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
147 /* variable assignment */
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
148 case token_identifier:
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
149 se = symtab_find(state -> local_syms, state -> lexer_token_string);
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
150 if (!se)
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
151 {
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
152 se = symtab_find(state -> global_syms, state -> lexer_token_string);
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
153 }
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
154 if (!se)
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
155 lwb_error("Unknown variable %s\n", state -> lexer_token_string);
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
156 lexer(state);
35
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
157 /* ensure the first token of the expression will be parsed correctly */
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
158 state -> expression = 1;
34
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
159 expect(state, token_op_assignment);
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
160
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
161 /* parse the expression */
35
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
162 et = parse_expression(state);
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
163
cdb0175e1063 More work on expressions
Lost Wizard (lost@starbug3)
parents: 34
diff changeset
164 /* check type compatibility */
34
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
165
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
166 /* actually do the assignment */
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
167
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
168 break;
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
169
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
170 /* anything we don't recognize as a statement token breaks out */
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
171 default:
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
172 return;
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
173 }
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
174 if (state -> lexer_token != token_eol)
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
175 lwb_error("Expecting end of line; got %s\n", lexer_return_token(state));
33
890a8f688889 Basic parsing of local variable decls
lost@l-w.ca
parents: 32
diff changeset
176 lexer(state);
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
177 }
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
178 }
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
179
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
180
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
181 /* issub means RETURNS is not allowed; !issub means RETURNS is required */
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
182
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
183 static void parse_subfunc(cstate *state, int issub)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
184 {
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
185 int pt, rt;
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
186 char *subname, *pn;
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
187 int vis = 0;
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
188 symtab_entry_t *se;
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
189 int paramsize = 0;
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
190
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
191 state -> local_syms = symtab_init();
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
192 state -> framesize = 0;
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
193
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
194 lexer(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
195 if (state -> lexer_token != token_identifier)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
196 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
197 lwb_error("Invalid sub name '%s'", state -> lexer_token_string);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
198 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
199
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
200 subname = lw_strdup(state -> lexer_token_string);
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
201
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
202 lexer(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
203 if (state -> lexer_token == token_kw_public || state -> lexer_token == token_kw_private)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
204 {
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
205 if (state -> lexer_token == token_kw_public)
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
206 vis = 1;
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
207 lexer(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
208 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
209
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
210 /* ignore the "PARAMS" keyword if present */
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
211 if (state -> lexer_token == token_kw_params)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
212 lexer(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
213
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
214 if (state -> lexer_token == token_eol || state -> lexer_token == token_kw_returns)
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
215 goto noparms;
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
216
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
217 paramagain:
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
218 if (state -> lexer_token != token_identifier)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
219 {
31
574931d87abd Created a function to prettyprint the current lexer token
lost@l-w.ca
parents: 30
diff changeset
220 lwb_error("Parameter name expected, got %s\n", lexer_return_token(state));
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
221 }
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
222 pn = lw_strdup(state -> lexer_token_string);
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
223 lexer(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
224
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
225 if (state -> lexer_token != token_kw_as)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
226 lwb_error("Expecting AS\n");
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
227 lexer(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
228
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
229 pt = parse_type(state);
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
230
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
231 se = symtab_find(state -> local_syms, pn);
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
232 if (se)
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
233 {
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
234 lwb_error("Duplicate parameter name %s\n", pn);
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
235 }
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
236 symtab_register(state -> local_syms, pn, paramsize, symtype_param, NULL);
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
237 paramsize += sizeof_type(pt);
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
238 lw_free(pn);
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
239
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
240 if (state -> lexer_token == token_char && state -> lexer_token_string[0] == ',')
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
241 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
242 lexer(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
243 goto paramagain;
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
244 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
245
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
246 noparms:
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
247 rt = -1;
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
248 if (!issub)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
249 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
250 if (state -> lexer_token != token_kw_returns)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
251 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
252 lwb_error("FUNCTION must have RETURNS\n");
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
253 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
254 lexer(state);
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
255 /* if (state -> lexer_token == token_identifier)
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
256 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
257 printf("Return value named: %s\n", state -> lexer_token_string);
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
258
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
259 lexer(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
260 if (state -> lexer_token != token_kw_as)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
261 lwb_error("Execting AS after RETURNS");
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
262 lexer(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
263 }
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
264 */
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
265 rt = parse_type(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
266 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
267 else
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
268 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
269 if (state -> lexer_token == token_kw_returns)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
270 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
271 lwb_error("SUB cannot specify RETURNS\n");
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
272 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
273 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
274
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
275
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
276 if (state -> lexer_token != token_eol)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
277 {
31
574931d87abd Created a function to prettyprint the current lexer token
lost@l-w.ca
parents: 30
diff changeset
278 lwb_error("EOL expected; found %s\n", lexer_return_token(state));
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
279 }
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
280
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
281
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
282 se = symtab_find(state -> global_syms, subname);
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
283 if (se)
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
284 {
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
285 lwb_error("Multiply defined symbol %s\n", subname);
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
286 }
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
287
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
288 symtab_register(state -> global_syms, subname, -1, issub ? symtype_sub : symtype_func, NULL);
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
289
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
290 state -> currentsub = subname;
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
291 state -> returntype = rt;
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
292 /* consume EOL */
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
293 lexer(state);
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
294
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
295 /* variable declarations */
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
296 parse_decls(state);
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
297
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
298 /* output function/sub prolog */
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
299 emit_prolog(state, vis);
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
300
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
301 /* parse statement block */
34
bfea77812e64 Start of assignment code
Lost Wizard (lost@starbug3)
parents: 33
diff changeset
302 parse_statements(state);
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
303
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
304 if (issub)
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
305 {
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
306 if (state -> lexer_token != token_kw_endsub)
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
307 {
31
574931d87abd Created a function to prettyprint the current lexer token
lost@l-w.ca
parents: 30
diff changeset
308 lwb_error("Expecting ENDSUB, got %s\n", lexer_return_token(state));
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
309 }
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
310 }
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
311 else
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
312 {
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
313 if (state -> lexer_token != token_kw_endfunction)
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
314 {
31
574931d87abd Created a function to prettyprint the current lexer token
lost@l-w.ca
parents: 30
diff changeset
315 lwb_error("Expecting ENDFUNCTION, got %s\n", lexer_return_token(state));
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
316 }
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
317 }
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
318 /* output function/sub epilog */
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
319 emit_epilog(state);
26
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
320
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
321 lw_free(state -> currentsub);
26aa76da75ad Additional parsing in function/sub; emission of prolog/epilog code
lost@l-w.ca
parents: 25
diff changeset
322 state -> currentsub = NULL;
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
323 symtab_destroy(state -> local_syms);
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
324 state -> local_syms = NULL;
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
325 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
326
30
bcd532a90e53 Renamed "compiler" to "parser" for more consistent terminology
lost@l-w.ca
parents: 27
diff changeset
327 void parser(cstate *state)
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
328 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
329 state -> lexer_curchar = -1;
32
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
330 state -> global_syms = symtab_init();
49d608aecc4d Framework for handling local stack frame and/or variables
lost@l-w.ca
parents: 31
diff changeset
331
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
332 /* now look for a global declaration */
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
333 for (;;)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
334 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
335 state -> parser_state = parser_state_global;
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
336 lexer(state);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
337 switch (state -> lexer_token)
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
338 {
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
339 case token_kw_function:
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
340 printf("Function\n");
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
341 parse_subfunc(state, 0);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
342 break;
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
343
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
344 case token_kw_sub:
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
345 printf("Sub\n");
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
346 parse_subfunc(state, 1);
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
347 break;
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
348
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
349 /* blank lines are allowed */
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
350 case token_eol:
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
351 continue;
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
352
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
353 /* EOF is allowed - end of parsing */
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
354 case token_eof:
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
355 return;
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
356
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
357 default:
31
574931d87abd Created a function to prettyprint the current lexer token
lost@l-w.ca
parents: 30
diff changeset
358 lwb_error("Invalid token '%s' in global state\n", lexer_return_token(state));
25
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
359 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
360 }
87590f43e76d Started lwbasic parser; checkpoint
lost@l-w.ca
parents:
diff changeset
361 }
36
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
362
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
363 static void parse_expr(cstate *state, int prec)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
364 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
365 static const struct operinfo {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
366 int opernum;
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
367 int operprec;
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
368 } operators[] =
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
369 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
370 { token_op_plus, 100 },
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
371 { token_op_minus, 100 },
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
372 { token_op_times, 150 },
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
373 { token_op_divide, 150 },
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
374 { token_op_modulus, 150 },
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
375 { token_op_and, 25 },
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
376 { token_op_or, 20 },
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
377 { token_op_xor, 20 },
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
378 { token_op_band, 50 },
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
379 { token_op_bor, 45 },
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
380 { token_op_bxor, 45 },
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
381 { -1, -1 }
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
382 };
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
383 int opern;
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
384
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
385 parse_term(state);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
386
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
387 eval_next:
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
388 for (opern = 0; operators[opern].opernum != -1; opern++)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
389 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
390 if (operators[opern].opernum == state -> lexer_token)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
391 break;
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
392 }
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
393 if (operators[opern].opernum == -1)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
394 return;
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
395
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
396 if (operators[opern].operprec <= prec)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
397 return;
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
398
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
399 lexer(state);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
400
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
401 parse_expr(state, operators[opern].operprec);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
402
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
403 /* push operator */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
404
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
405 goto eval_next;
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
406 }
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
407
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
408 static void parse_term(cstate *state)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
409 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
410 eval_next:
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
411 /* parens */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
412 if (state -> lexer_token == token_op_oparen)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
413 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
414 lexer(state);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
415 parse_expr(state, 0);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
416 expect(state, token_op_cparen);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
417 return;
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
418 }
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
419
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
420 /* unary plus; ignore it */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
421 if (state -> lexer_token == token_op_plus)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
422 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
423 lexer(state);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
424 goto eval_next;
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
425 }
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
426
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
427 /* unary minus, precision 200 */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
428 if (state -> lexer_token == token_op_minus)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
429 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
430 lexer(state);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
431 parse_expr(state, 200);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
432
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
433 /* push unary negation */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
434 }
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
435
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
436 /* BNOT, NOT */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
437 if (state -> lexer_token == token_op_not || state -> lexer_token == token_op_bnot)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
438 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
439 lexer(state);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
440 parse_expr(state, 200);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
441
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
442 /* push unary operator */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
443 }
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
444
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
445 /* integer */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
446 if (state -> lexer_token == token_int)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
447 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
448 }
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
449
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
450 /* unsigned integer */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
451 if (state -> lexer_token == token_uint)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
452 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
453 }
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
454
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
455 /* variable or function call */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
456 if (state -> lexer_token == token_identifier)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
457 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
458 lexer(state);
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
459 if (state -> lexer_token == token_op_oparen)
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
460 {
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
461 /* function call */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
462 return;
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
463 }
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
464 /* variable */
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
465 return;
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
466 }
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
467
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
468 lwb_error("Invalid input in expression; got %s\n", lexer_return_token(state));
5325b640424d First pass expression parsing
Lost Wizard (lost@starbug3)
parents: 35
diff changeset
469 }