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 }