Rev 7693 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 7693 | Rev 7696 | ||
---|---|---|---|
1 | (* |
1 | (* |
2 | BSD 2-Clause License |
2 | BSD 2-Clause License |
3 | 3 | ||
4 | Copyright (c) 2018, 2019, Anton Krotov |
4 | Copyright (c) 2018-2019, Anton Krotov |
5 | All rights reserved. |
5 | All rights reserved. |
6 | *) |
6 | *) |
7 | 7 | ||
8 | MODULE PARS; |
8 | MODULE PARS; |
9 | 9 | ||
10 | IMPORT PROG, SCAN, ARITH, STRINGS, ERRORS, LISTS, IL, CONSOLE, PATHS, UTILS, C := COLLECTIONS, mConst := CONSTANTS; |
10 | IMPORT PROG, SCAN, ARITH, STRINGS, ERRORS, LISTS, IL, CONSOLE, PATHS, UTILS, C := COLLECTIONS, mConst := CONSTANTS; |
11 | 11 | ||
12 | 12 | ||
13 | CONST |
13 | CONST |
14 | 14 | ||
15 | eCONST* = 1; eTYPE* = 2; eVAR* = 3; eEXPR* = 4; |
15 | eCONST* = 1; eTYPE* = 2; eVAR* = 3; eEXPR* = 4; |
16 | eVREC* = 5; ePROC* = 6; eVPAR* = 7; ePARAM* = 8; |
16 | eVREC* = 5; ePROC* = 6; eVPAR* = 7; ePARAM* = 8; |
17 | eSTPROC* = 9; eSTFUNC* = 10; eSYSFUNC* = 11; eSYSPROC* = 12; |
17 | eSTPROC* = 9; eSTFUNC* = 10; eSYSFUNC* = 11; eSYSPROC* = 12; |
18 | eIMP* = 13; |
18 | eIMP* = 13; |
19 | 19 | ||
20 | 20 | ||
21 | TYPE |
21 | TYPE |
22 | 22 | ||
23 | PATH* = PATHS.PATH; |
23 | PATH* = PATHS.PATH; |
24 | 24 | ||
25 | PARSER* = POINTER TO rPARSER; |
25 | PARSER* = POINTER TO rPARSER; |
26 | 26 | ||
27 | POSITION* = RECORD (SCAN.POSITION) |
27 | POSITION* = RECORD (SCAN.POSITION) |
28 | 28 | ||
29 | parser*: PARSER |
29 | parser*: PARSER |
30 | 30 | ||
31 | END; |
31 | END; |
32 | 32 | ||
33 | EXPR* = RECORD |
33 | EXPR* = RECORD |
34 | 34 | ||
35 | obj*: INTEGER; |
35 | obj*: INTEGER; |
36 | type*: PROG.TYPE_; |
36 | type*: PROG.TYPE_; |
37 | value*: ARITH.VALUE; |
37 | value*: ARITH.VALUE; |
38 | stproc*: INTEGER; |
38 | stproc*: INTEGER; |
39 | readOnly*: BOOLEAN; |
39 | readOnly*: BOOLEAN; |
40 | ident*: PROG.IDENT |
40 | ident*: PROG.IDENT |
41 | 41 | ||
42 | END; |
42 | END; |
43 | 43 | ||
44 | STATPROC = PROCEDURE (parser: PARSER); |
44 | STATPROC = PROCEDURE (parser: PARSER); |
45 | EXPRPROC = PROCEDURE (parser: PARSER; VAR e: EXPR); |
45 | EXPRPROC = PROCEDURE (parser: PARSER; VAR e: EXPR); |
46 | RETPROC = PROCEDURE (parser: PARSER; e: EXPR; t: PROG.TYPE_; pos: POSITION): BOOLEAN; |
46 | RETPROC = PROCEDURE (parser: PARSER; e: EXPR; t: PROG.TYPE_; pos: POSITION): BOOLEAN; |
47 | 47 | ||
48 | rPARSER = RECORD (C.ITEM) |
48 | rPARSER = RECORD (C.ITEM) |
49 | 49 | ||
50 | fname*: PATH; |
50 | fname*: PATH; |
51 | path: PATH; |
51 | path: PATH; |
52 | lib_path: PATH; |
52 | lib_path: PATH; |
53 | ext: PATH; |
53 | ext: PATH; |
54 | modname: PATH; |
54 | modname: PATH; |
55 | scanner: SCAN.SCANNER; |
55 | scanner: SCAN.SCANNER; |
56 | lex*: SCAN.LEX; |
56 | lex*: SCAN.LEX; |
57 | sym*: INTEGER; |
57 | sym*: INTEGER; |
58 | unit*: PROG.UNIT; |
58 | unit*: PROG.UNIT; |
59 | constexp*: BOOLEAN; |
59 | constexp*: BOOLEAN; |
60 | main*: BOOLEAN; |
60 | main*: BOOLEAN; |
61 | 61 | ||
62 | open*: PROCEDURE (parser: PARSER; modname: ARRAY OF CHAR): BOOLEAN; |
62 | open*: PROCEDURE (parser: PARSER; modname: ARRAY OF CHAR): BOOLEAN; |
63 | parse*: PROCEDURE (parser: PARSER); |
63 | parse*: PROCEDURE (parser: PARSER); |
64 | StatSeq*: STATPROC; |
64 | StatSeq*: STATPROC; |
65 | expression*: EXPRPROC; |
65 | expression*: EXPRPROC; |
66 | designator*: EXPRPROC; |
66 | designator*: EXPRPROC; |
67 | chkreturn: RETPROC; |
67 | chkreturn: RETPROC; |
68 | 68 | ||
69 | create*: PROCEDURE (path, lib_path: PATH; StatSeq: STATPROC; expression, designator: EXPRPROC; chkreturn: RETPROC): PARSER |
69 | create*: PROCEDURE (path, lib_path: PATH; StatSeq: STATPROC; expression, designator: EXPRPROC; chkreturn: RETPROC): PARSER |
70 | 70 | ||
71 | END; |
71 | END; |
72 | 72 | ||
73 | 73 | ||
74 | VAR |
74 | VAR |
75 | 75 | ||
76 | program*: PROG.PROGRAM; |
76 | program*: PROG.PROGRAM; |
77 | 77 | ||
78 | parsers: C.COLLECTION; |
78 | parsers: C.COLLECTION; |
- | 79 | ||
- | 80 | lines*: INTEGER; |
|
79 | 81 | ||
80 | 82 | ||
81 | PROCEDURE destroy* (VAR parser: PARSER); |
83 | PROCEDURE destroy* (VAR parser: PARSER); |
82 | BEGIN |
84 | BEGIN |
83 | IF parser.scanner # NIL THEN |
85 | IF parser.scanner # NIL THEN |
84 | SCAN.close(parser.scanner) |
86 | SCAN.close(parser.scanner) |
85 | END; |
87 | END; |
86 | 88 | ||
87 | C.push(parsers, parser); |
89 | C.push(parsers, parser); |
88 | parser := NIL |
90 | parser := NIL |
89 | END destroy; |
91 | END destroy; |
90 | 92 | ||
91 | 93 | ||
92 | PROCEDURE getpos (parser: PARSER; VAR pos: POSITION); |
94 | PROCEDURE getpos (parser: PARSER; VAR pos: POSITION); |
93 | BEGIN |
95 | BEGIN |
94 | pos.line := parser.lex.pos.line; |
96 | pos.line := parser.lex.pos.line; |
95 | pos.col := parser.lex.pos.col; |
97 | pos.col := parser.lex.pos.col; |
96 | pos.parser := parser |
98 | pos.parser := parser |
97 | END getpos; |
99 | END getpos; |
98 | 100 | ||
99 | 101 | ||
100 | PROCEDURE error* (pos: POSITION; errno: INTEGER); |
102 | PROCEDURE error* (pos: POSITION; errno: INTEGER); |
101 | BEGIN |
103 | BEGIN |
102 | ERRORS.ErrorMsg(pos.parser.fname, pos.line, pos.col, errno) |
104 | ERRORS.ErrorMsg(pos.parser.fname, pos.line, pos.col, errno) |
103 | END error; |
105 | END error; |
104 | 106 | ||
105 | 107 | ||
106 | PROCEDURE check* (condition: BOOLEAN; pos: POSITION; errno: INTEGER); |
108 | PROCEDURE check* (condition: BOOLEAN; pos: POSITION; errno: INTEGER); |
107 | BEGIN |
109 | BEGIN |
108 | IF ~condition THEN |
110 | IF ~condition THEN |
109 | error(pos, errno) |
111 | error(pos, errno) |
110 | END |
112 | END |
111 | END check; |
113 | END check; |
112 | 114 | ||
113 | 115 | ||
114 | PROCEDURE check1* (condition: BOOLEAN; parser: PARSER; errno: INTEGER); |
116 | PROCEDURE check1* (condition: BOOLEAN; parser: PARSER; errno: INTEGER); |
115 | VAR |
117 | VAR |
116 | pos: POSITION; |
118 | pos: POSITION; |
117 | 119 | ||
118 | BEGIN |
120 | BEGIN |
119 | IF ~condition THEN |
121 | IF ~condition THEN |
120 | getpos(parser, pos); |
122 | getpos(parser, pos); |
121 | error(pos, errno) |
123 | error(pos, errno) |
122 | END |
124 | END |
123 | END check1; |
125 | END check1; |
124 | 126 | ||
125 | 127 | ||
126 | PROCEDURE Next* (parser: PARSER); |
128 | PROCEDURE Next* (parser: PARSER); |
127 | VAR |
129 | VAR |
128 | errno: INTEGER; |
130 | errno: INTEGER; |
129 | 131 | ||
130 | BEGIN |
132 | BEGIN |
131 | SCAN.Next(parser.scanner, parser.lex); |
133 | SCAN.Next(parser.scanner, parser.lex); |
132 | errno := parser.lex.error; |
134 | errno := parser.lex.error; |
133 | IF (errno = 0) & (program.target.sys = mConst.Target_iMSP430) THEN |
135 | IF (errno = 0) & (program.target.sys = mConst.Target_iMSP430) THEN |
134 | IF parser.lex.sym = SCAN.lxFLOAT THEN |
136 | IF parser.lex.sym = SCAN.lxFLOAT THEN |
135 | errno := -SCAN.lxERROR13 |
137 | errno := -SCAN.lxERROR13 |
136 | ELSIF (parser.lex.sym = SCAN.lxCHAR) & (parser.lex.value.typ = ARITH.tWCHAR) THEN |
138 | ELSIF (parser.lex.sym = SCAN.lxCHAR) & (parser.lex.value.typ = ARITH.tWCHAR) THEN |
137 | errno := -SCAN.lxERROR10 |
139 | errno := -SCAN.lxERROR10 |
138 | END |
140 | END |
139 | END; |
141 | END; |
140 | 142 | ||
141 | IF errno # 0 THEN |
143 | IF errno # 0 THEN |
142 | check1(FALSE, parser, errno) |
144 | check1(FALSE, parser, errno) |
143 | END; |
145 | END; |
144 | parser.sym := parser.lex.sym |
146 | parser.sym := parser.lex.sym |
145 | END Next; |
147 | END Next; |
146 | 148 | ||
147 | 149 | ||
148 | PROCEDURE NextPos (parser: PARSER; VAR pos: POSITION); |
150 | PROCEDURE NextPos (parser: PARSER; VAR pos: POSITION); |
149 | BEGIN |
151 | BEGIN |
150 | Next(parser); |
152 | Next(parser); |
151 | getpos(parser, pos) |
153 | getpos(parser, pos) |
152 | END NextPos; |
154 | END NextPos; |
153 | 155 | ||
154 | 156 | ||
155 | PROCEDURE checklex* (parser: PARSER; sym: INTEGER); |
157 | PROCEDURE checklex* (parser: PARSER; sym: INTEGER); |
156 | VAR |
158 | VAR |
157 | err: INTEGER; |
159 | err: INTEGER; |
158 | 160 | ||
159 | BEGIN |
161 | BEGIN |
160 | 162 | ||
161 | IF parser.sym # sym THEN |
163 | IF parser.sym # sym THEN |
162 | 164 | ||
163 | CASE sym OF |
165 | CASE sym OF |
164 | |SCAN.lxCOMMA: err := 65 |
166 | |SCAN.lxCOMMA: err := 65 |
165 | |SCAN.lxRROUND: err := 33 |
167 | |SCAN.lxRROUND: err := 33 |
166 | |SCAN.lxPOINT: err := 26 |
168 | |SCAN.lxPOINT: err := 26 |
167 | |SCAN.lxIDENT: err := 22 |
169 | |SCAN.lxIDENT: err := 22 |
168 | |SCAN.lxRSQUARE: err := 71 |
170 | |SCAN.lxRSQUARE: err := 71 |
169 | |SCAN.lxRCURLY: err := 35 |
171 | |SCAN.lxRCURLY: err := 35 |
170 | |SCAN.lxUNDEF: err := 34 |
172 | |SCAN.lxUNDEF: err := 34 |
171 | |SCAN.lxTHEN: err := 88 |
173 | |SCAN.lxTHEN: err := 88 |
172 | |SCAN.lxEND: err := 27 |
174 | |SCAN.lxEND: err := 27 |
173 | |SCAN.lxDO: err := 89 |
175 | |SCAN.lxDO: err := 89 |
174 | |SCAN.lxUNTIL: err := 90 |
176 | |SCAN.lxUNTIL: err := 90 |
175 | |SCAN.lxCOLON: err := 53 |
177 | |SCAN.lxCOLON: err := 53 |
176 | |SCAN.lxOF: err := 67 |
178 | |SCAN.lxOF: err := 67 |
177 | |SCAN.lxASSIGN: err := 96 |
179 | |SCAN.lxASSIGN: err := 96 |
178 | |SCAN.lxTO: err := 57 |
180 | |SCAN.lxTO: err := 57 |
179 | |SCAN.lxLROUND: err := 64 |
181 | |SCAN.lxLROUND: err := 64 |
180 | |SCAN.lxEQ: err := 32 |
182 | |SCAN.lxEQ: err := 32 |
181 | |SCAN.lxSEMI: err := 24 |
183 | |SCAN.lxSEMI: err := 24 |
182 | |SCAN.lxRETURN: err := 38 |
184 | |SCAN.lxRETURN: err := 38 |
183 | |SCAN.lxMODULE: err := 21 |
185 | |SCAN.lxMODULE: err := 21 |
184 | |SCAN.lxSTRING: err := 66 |
186 | |SCAN.lxSTRING: err := 66 |
185 | END; |
187 | END; |
186 | 188 | ||
187 | check1(FALSE, parser, err) |
189 | check1(FALSE, parser, err) |
188 | END |
190 | END |
189 | END checklex; |
191 | END checklex; |
190 | 192 | ||
191 | 193 | ||
192 | PROCEDURE ExpectSym* (parser: PARSER; sym: INTEGER); |
194 | PROCEDURE ExpectSym* (parser: PARSER; sym: INTEGER); |
193 | BEGIN |
195 | BEGIN |
194 | Next(parser); |
196 | Next(parser); |
195 | checklex(parser, sym) |
197 | checklex(parser, sym) |
196 | END ExpectSym; |
198 | END ExpectSym; |
197 | 199 | ||
198 | 200 | ||
199 | PROCEDURE ImportList (parser: PARSER); |
201 | PROCEDURE ImportList (parser: PARSER); |
200 | VAR |
202 | VAR |
201 | name: SCAN.IDENT; |
203 | name: SCAN.IDENT; |
202 | parser2: PARSER; |
204 | parser2: PARSER; |
203 | pos: POSITION; |
205 | pos: POSITION; |
204 | alias: BOOLEAN; |
206 | alias: BOOLEAN; |
205 | unit: PROG.UNIT; |
207 | unit: PROG.UNIT; |
206 | ident: PROG.IDENT; |
208 | ident: PROG.IDENT; |
207 | 209 | ||
208 | BEGIN |
210 | BEGIN |
209 | alias := FALSE; |
211 | alias := FALSE; |
210 | 212 | ||
211 | REPEAT |
213 | REPEAT |
212 | 214 | ||
213 | ExpectSym(parser, SCAN.lxIDENT); |
215 | ExpectSym(parser, SCAN.lxIDENT); |
214 | name := parser.lex.ident; |
216 | name := parser.lex.ident; |
215 | 217 | ||
216 | getpos(parser, pos); |
218 | getpos(parser, pos); |
217 | 219 | ||
218 | IF ~alias THEN |
220 | IF ~alias THEN |
219 | ident := PROG.addIdent(parser.unit, name, PROG.idMODULE); |
221 | ident := PROG.addIdent(parser.unit, name, PROG.idMODULE); |
220 | check(ident # NIL, pos, 30) |
222 | check(ident # NIL, pos, 30) |
221 | END; |
223 | END; |
222 | 224 | ||
223 | Next(parser); |
225 | Next(parser); |
224 | 226 | ||
225 | IF (parser.sym = SCAN.lxCOMMA) OR (parser.sym = SCAN.lxSEMI) THEN |
227 | IF (parser.sym = SCAN.lxCOMMA) OR (parser.sym = SCAN.lxSEMI) THEN |
226 | alias := FALSE; |
228 | alias := FALSE; |
227 | unit := PROG.getUnit(program, name); |
229 | unit := PROG.getUnit(program, name); |
228 | 230 | ||
229 | IF unit # NIL THEN |
231 | IF unit # NIL THEN |
230 | check(unit.closed, pos, 31) |
232 | check(unit.closed, pos, 31) |
231 | ELSE |
233 | ELSE |
232 | parser2 := parser.create(parser.path, parser.lib_path, |
234 | parser2 := parser.create(parser.path, parser.lib_path, |
233 | parser.StatSeq, parser.expression, parser.designator, parser.chkreturn); |
235 | parser.StatSeq, parser.expression, parser.designator, parser.chkreturn); |
234 | 236 | ||
235 | IF ~parser2.open(parser2, name.s) THEN |
237 | IF ~parser2.open(parser2, name.s) THEN |
236 | IF parser.path # parser.lib_path THEN |
238 | IF parser.path # parser.lib_path THEN |
237 | destroy(parser2); |
239 | destroy(parser2); |
238 | parser2 := parser.create(parser.lib_path, parser.lib_path, |
240 | parser2 := parser.create(parser.lib_path, parser.lib_path, |
239 | parser.StatSeq, parser.expression, parser.designator, parser.chkreturn); |
241 | parser.StatSeq, parser.expression, parser.designator, parser.chkreturn); |
240 | check(parser2.open(parser2, name.s), pos, 29) |
242 | check(parser2.open(parser2, name.s), pos, 29) |
241 | ELSE |
243 | ELSE |
242 | error(pos, 29) |
244 | error(pos, 29) |
243 | END |
245 | END |
244 | END; |
246 | END; |
245 | 247 | ||
246 | parser2.parse(parser2); |
248 | parser2.parse(parser2); |
247 | unit := parser2.unit; |
249 | unit := parser2.unit; |
248 | destroy(parser2) |
250 | destroy(parser2) |
249 | END; |
251 | END; |
250 | IF unit = program.sysunit THEN |
252 | IF unit = program.sysunit THEN |
251 | parser.unit.sysimport := TRUE |
253 | parser.unit.sysimport := TRUE |
252 | END; |
254 | END; |
253 | ident.unit := unit |
255 | ident.unit := unit |
254 | 256 | ||
255 | ELSIF parser.sym = SCAN.lxASSIGN THEN |
257 | ELSIF parser.sym = SCAN.lxASSIGN THEN |
256 | alias := TRUE |
258 | alias := TRUE |
257 | 259 | ||
258 | ELSE |
260 | ELSE |
259 | check1(FALSE, parser, 28) |
261 | check1(FALSE, parser, 28) |
260 | END |
262 | END |
261 | 263 | ||
262 | UNTIL parser.sym = SCAN.lxSEMI; |
264 | UNTIL parser.sym = SCAN.lxSEMI; |
263 | 265 | ||
264 | Next(parser) |
266 | Next(parser) |
265 | 267 | ||
266 | END ImportList; |
268 | END ImportList; |
267 | 269 | ||
268 | 270 | ||
269 | PROCEDURE QIdent (parser: PARSER; forward: BOOLEAN): PROG.IDENT; |
271 | PROCEDURE QIdent (parser: PARSER; forward: BOOLEAN): PROG.IDENT; |
270 | VAR |
272 | VAR |
271 | ident: PROG.IDENT; |
273 | ident: PROG.IDENT; |
272 | unit: PROG.UNIT; |
274 | unit: PROG.UNIT; |
273 | 275 | ||
274 | BEGIN |
276 | BEGIN |
275 | ASSERT(parser.sym = SCAN.lxIDENT); |
277 | ASSERT(parser.sym = SCAN.lxIDENT); |
276 | 278 | ||
277 | ident := PROG.getIdent(parser.unit, parser.lex.ident, FALSE); |
279 | ident := PROG.getIdent(parser.unit, parser.lex.ident, FALSE); |
278 | 280 | ||
279 | IF ~forward THEN |
281 | IF ~forward THEN |
280 | check1(ident # NIL, parser, 48) |
282 | check1(ident # NIL, parser, 48) |
281 | END; |
283 | END; |
282 | 284 | ||
283 | IF (ident # NIL) & (ident.typ = PROG.idMODULE) THEN |
285 | IF (ident # NIL) & (ident.typ = PROG.idMODULE) THEN |
284 | unit := ident.unit; |
286 | unit := ident.unit; |
285 | ExpectSym(parser, SCAN.lxPOINT); |
287 | ExpectSym(parser, SCAN.lxPOINT); |
286 | ExpectSym(parser, SCAN.lxIDENT); |
288 | ExpectSym(parser, SCAN.lxIDENT); |
287 | ident := PROG.getIdent(unit, parser.lex.ident, FALSE); |
289 | ident := PROG.getIdent(unit, parser.lex.ident, FALSE); |
288 | check1((ident # NIL) & ident.export, parser, 48) |
290 | check1((ident # NIL) & ident.export, parser, 48) |
289 | END |
291 | END |
290 | 292 | ||
291 | RETURN ident |
293 | RETURN ident |
292 | END QIdent; |
294 | END QIdent; |
293 | 295 | ||
294 | 296 | ||
295 | PROCEDURE strcmp* (VAR v: ARITH.VALUE; v2: ARITH.VALUE; operator: INTEGER); |
297 | PROCEDURE strcmp* (VAR v: ARITH.VALUE; v2: ARITH.VALUE; operator: INTEGER); |
296 | VAR |
298 | VAR |
297 | str: SCAN.LEXSTR; |
299 | str: SCAN.LEXSTR; |
298 | string1, string2: SCAN.IDENT; |
300 | string1, string2: SCAN.IDENT; |
299 | bool: BOOLEAN; |
301 | bool: BOOLEAN; |
300 | 302 | ||
301 | BEGIN |
303 | BEGIN |
302 | 304 | ||
303 | IF v.typ = ARITH.tCHAR THEN |
305 | IF v.typ = ARITH.tCHAR THEN |
304 | ASSERT(v2.typ = ARITH.tSTRING); |
306 | ASSERT(v2.typ = ARITH.tSTRING); |
305 | ARITH.charToStr(v, str); |
307 | ARITH.charToStr(v, str); |
306 | string1 := SCAN.enterid(str); |
308 | string1 := SCAN.enterid(str); |
307 | string2 := v2.string(SCAN.IDENT) |
309 | string2 := v2.string(SCAN.IDENT) |
308 | END; |
310 | END; |
309 | 311 | ||
310 | IF v2.typ = ARITH.tCHAR THEN |
312 | IF v2.typ = ARITH.tCHAR THEN |
311 | ASSERT(v.typ = ARITH.tSTRING); |
313 | ASSERT(v.typ = ARITH.tSTRING); |
312 | ARITH.charToStr(v2, str); |
314 | ARITH.charToStr(v2, str); |
313 | string2 := SCAN.enterid(str); |
315 | string2 := SCAN.enterid(str); |
314 | string1 := v.string(SCAN.IDENT) |
316 | string1 := v.string(SCAN.IDENT) |
315 | END; |
317 | END; |
316 | 318 | ||
317 | IF v.typ = v2.typ THEN |
319 | IF v.typ = v2.typ THEN |
318 | string1 := v.string(SCAN.IDENT); |
320 | string1 := v.string(SCAN.IDENT); |
319 | string2 := v2.string(SCAN.IDENT) |
321 | string2 := v2.string(SCAN.IDENT) |
320 | END; |
322 | END; |
321 | 323 | ||
322 | CASE operator OF |
324 | CASE operator OF |
323 | |SCAN.lxEQ: bool := string1.s = string2.s |
325 | |SCAN.lxEQ: bool := string1.s = string2.s |
324 | |SCAN.lxNE: bool := string1.s # string2.s |
326 | |SCAN.lxNE: bool := string1.s # string2.s |
325 | |SCAN.lxLT: bool := string1.s < string2.s |
327 | |SCAN.lxLT: bool := string1.s < string2.s |
326 | |SCAN.lxGT: bool := string1.s > string2.s |
328 | |SCAN.lxGT: bool := string1.s > string2.s |
327 | |SCAN.lxLE: bool := string1.s <= string2.s |
329 | |SCAN.lxLE: bool := string1.s <= string2.s |
328 | |SCAN.lxGE: bool := string1.s >= string2.s |
330 | |SCAN.lxGE: bool := string1.s >= string2.s |
329 | END; |
331 | END; |
330 | 332 | ||
331 | ARITH.setbool(v, bool) |
333 | ARITH.setbool(v, bool) |
332 | END strcmp; |
334 | END strcmp; |
333 | 335 | ||
334 | 336 | ||
335 | PROCEDURE ConstExpression* (parser: PARSER; VAR v: ARITH.VALUE); |
337 | PROCEDURE ConstExpression* (parser: PARSER; VAR v: ARITH.VALUE); |
336 | VAR |
338 | VAR |
337 | e: EXPR; |
339 | e: EXPR; |
338 | pos: POSITION; |
340 | pos: POSITION; |
339 | 341 | ||
340 | BEGIN |
342 | BEGIN |
341 | getpos(parser, pos); |
343 | getpos(parser, pos); |
342 | parser.constexp := TRUE; |
344 | parser.constexp := TRUE; |
343 | parser.expression(parser, e); |
345 | parser.expression(parser, e); |
344 | parser.constexp := FALSE; |
346 | parser.constexp := FALSE; |
345 | check(e.obj = eCONST, pos, 62); |
347 | check(e.obj = eCONST, pos, 62); |
346 | v := e.value |
348 | v := e.value |
347 | END ConstExpression; |
349 | END ConstExpression; |
348 | 350 | ||
349 | 351 | ||
350 | PROCEDURE FieldList (parser: PARSER; rec: PROG.TYPE_); |
352 | PROCEDURE FieldList (parser: PARSER; rec: PROG.TYPE_); |
351 | VAR |
353 | VAR |
352 | name: SCAN.IDENT; |
354 | name: SCAN.IDENT; |
353 | export: BOOLEAN; |
355 | export: BOOLEAN; |
354 | pos: POSITION; |
356 | pos: POSITION; |
355 | 357 | ||
356 | BEGIN |
358 | BEGIN |
357 | ASSERT(parser.sym = SCAN.lxIDENT); |
359 | ASSERT(parser.sym = SCAN.lxIDENT); |
358 | 360 | ||
359 | WHILE parser.sym = SCAN.lxIDENT DO |
361 | WHILE parser.sym = SCAN.lxIDENT DO |
360 | 362 | ||
361 | getpos(parser, pos); |
363 | getpos(parser, pos); |
362 | 364 | ||
363 | name := parser.lex.ident; |
365 | name := parser.lex.ident; |
364 | 366 | ||
365 | Next(parser); |
367 | Next(parser); |
366 | 368 | ||
367 | export := parser.sym = SCAN.lxMUL; |
369 | export := parser.sym = SCAN.lxMUL; |
368 | 370 | ||
369 | IF export THEN |
371 | IF export THEN |
370 | check1(parser.unit.scopeLvl = 0, parser, 61); |
372 | check1(parser.unit.scopeLvl = 0, parser, 61); |
371 | Next(parser) |
373 | Next(parser) |
372 | END; |
374 | END; |
373 | 375 | ||
374 | check(PROG.addField(rec, name, export), pos, 30); |
376 | check(PROG.addField(rec, name, export), pos, 30); |
375 | 377 | ||
376 | IF parser.sym = SCAN.lxCOMMA THEN |
378 | IF parser.sym = SCAN.lxCOMMA THEN |
377 | ExpectSym(parser, SCAN.lxIDENT) |
379 | ExpectSym(parser, SCAN.lxIDENT) |
378 | ELSE |
380 | ELSE |
379 | checklex(parser, SCAN.lxCOLON) |
381 | checklex(parser, SCAN.lxCOLON) |
380 | END |
382 | END |
381 | 383 | ||
382 | END |
384 | END |
383 | 385 | ||
384 | END FieldList; |
386 | END FieldList; |
385 | 387 | ||
386 | 388 | ||
387 | PROCEDURE FormalParameters (parser: PARSER; type: PROG.TYPE_); |
389 | PROCEDURE FormalParameters (parser: PARSER; type: PROG.TYPE_); |
388 | VAR |
390 | VAR |
389 | ident: PROG.IDENT; |
391 | ident: PROG.IDENT; |
390 | 392 | ||
391 | 393 | ||
392 | PROCEDURE FPSection (parser: PARSER; type: PROG.TYPE_); |
394 | PROCEDURE FPSection (parser: PARSER; type: PROG.TYPE_); |
393 | VAR |
395 | VAR |
394 | ident: PROG.IDENT; |
396 | ident: PROG.IDENT; |
395 | exit: BOOLEAN; |
397 | exit: BOOLEAN; |
396 | vPar: BOOLEAN; |
398 | vPar: BOOLEAN; |
397 | dim: INTEGER; |
399 | dim: INTEGER; |
398 | t0, t1: PROG.TYPE_; |
400 | t0, t1: PROG.TYPE_; |
399 | 401 | ||
400 | BEGIN |
402 | BEGIN |
401 | vPar := parser.sym = SCAN.lxVAR; |
403 | vPar := parser.sym = SCAN.lxVAR; |
402 | IF vPar THEN |
404 | IF vPar THEN |
403 | Next(parser) |
405 | Next(parser) |
404 | END; |
406 | END; |
405 | 407 | ||
406 | checklex(parser, SCAN.lxIDENT); |
408 | checklex(parser, SCAN.lxIDENT); |
407 | exit := FALSE; |
409 | exit := FALSE; |
408 | 410 | ||
409 | WHILE (parser.sym = SCAN.lxIDENT) & ~exit DO |
411 | WHILE (parser.sym = SCAN.lxIDENT) & ~exit DO |
410 | check1(PROG.addParam(type, parser.lex.ident, vPar), parser, 30); |
412 | check1(PROG.addParam(type, parser.lex.ident, vPar), parser, 30); |
411 | Next(parser); |
413 | Next(parser); |
412 | IF parser.sym = SCAN.lxCOMMA THEN |
414 | IF parser.sym = SCAN.lxCOMMA THEN |
413 | ExpectSym(parser, SCAN.lxIDENT) |
415 | ExpectSym(parser, SCAN.lxIDENT) |
414 | ELSIF parser.sym = SCAN.lxCOLON THEN |
416 | ELSIF parser.sym = SCAN.lxCOLON THEN |
415 | Next(parser); |
417 | Next(parser); |
416 | dim := 0; |
418 | dim := 0; |
417 | WHILE parser.sym = SCAN.lxARRAY DO |
419 | WHILE parser.sym = SCAN.lxARRAY DO |
418 | INC(dim); |
420 | INC(dim); |
419 | check1(dim <= PROG.MAXARRDIM, parser, 84); |
421 | check1(dim <= PROG.MAXARRDIM, parser, 84); |
420 | ExpectSym(parser, SCAN.lxOF); |
422 | ExpectSym(parser, SCAN.lxOF); |
421 | Next(parser) |
423 | Next(parser) |
422 | END; |
424 | END; |
423 | checklex(parser, SCAN.lxIDENT); |
425 | checklex(parser, SCAN.lxIDENT); |
424 | ident := QIdent(parser, FALSE); |
426 | ident := QIdent(parser, FALSE); |
425 | check1(ident.typ = PROG.idTYPE, parser, 68); |
427 | check1(ident.typ = PROG.idTYPE, parser, 68); |
426 | 428 | ||
427 | t0 := ident.type; |
429 | t0 := ident.type; |
428 | t1 := t0; |
430 | t1 := t0; |
429 | 431 | ||
430 | WHILE dim > 0 DO |
432 | WHILE dim > 0 DO |
431 | t1 := PROG.enterType(program, PROG.tARRAY, -1, 0, parser.unit); |
433 | t1 := PROG.enterType(program, PROG.tARRAY, -1, 0, parser.unit); |
432 | t1.base := t0; |
434 | t1.base := t0; |
433 | t0 := t1; |
435 | t0 := t1; |
434 | DEC(dim) |
436 | DEC(dim) |
435 | END; |
437 | END; |
436 | 438 | ||
437 | PROG.setParams(type, t1); |
439 | PROG.setParams(type, t1); |
438 | Next(parser); |
440 | Next(parser); |
439 | exit := TRUE |
441 | exit := TRUE |
440 | ELSE |
442 | ELSE |
441 | checklex(parser, SCAN.lxCOLON) |
443 | checklex(parser, SCAN.lxCOLON) |
442 | END |
444 | END |
443 | END |
445 | END |
444 | 446 | ||
445 | END FPSection; |
447 | END FPSection; |
446 | 448 | ||
447 | 449 | ||
448 | BEGIN |
450 | BEGIN |
449 | IF parser.sym = SCAN.lxLROUND THEN |
451 | IF parser.sym = SCAN.lxLROUND THEN |
450 | 452 | ||
451 | Next(parser); |
453 | Next(parser); |
452 | 454 | ||
453 | IF (parser.sym = SCAN.lxVAR) OR (parser.sym = SCAN.lxIDENT) THEN |
455 | IF (parser.sym = SCAN.lxVAR) OR (parser.sym = SCAN.lxIDENT) THEN |
454 | FPSection(parser, type); |
456 | FPSection(parser, type); |
455 | WHILE parser.sym = SCAN.lxSEMI DO |
457 | WHILE parser.sym = SCAN.lxSEMI DO |
456 | Next(parser); |
458 | Next(parser); |
457 | FPSection(parser, type) |
459 | FPSection(parser, type) |
458 | END |
460 | END |
459 | END; |
461 | END; |
460 | 462 | ||
461 | checklex(parser, SCAN.lxRROUND); |
463 | checklex(parser, SCAN.lxRROUND); |
462 | Next(parser); |
464 | Next(parser); |
463 | 465 | ||
464 | IF parser.sym = SCAN.lxCOLON THEN |
466 | IF parser.sym = SCAN.lxCOLON THEN |
465 | ExpectSym(parser, SCAN.lxIDENT); |
467 | ExpectSym(parser, SCAN.lxIDENT); |
466 | ident := QIdent(parser, FALSE); |
468 | ident := QIdent(parser, FALSE); |
467 | check1(ident.typ = PROG.idTYPE, parser, 68); |
469 | check1(ident.typ = PROG.idTYPE, parser, 68); |
468 | check1(~(ident.type.typ IN {PROG.tRECORD, PROG.tARRAY}), parser, 69); |
470 | check1(~(ident.type.typ IN {PROG.tRECORD, PROG.tARRAY}), parser, 69); |
469 | check1( ~(ODD(type.call) & (ident.type.typ = PROG.tREAL)), parser, 113); |
471 | check1( ~(ODD(type.call) & (ident.type.typ = PROG.tREAL)), parser, 113); |
470 | type.base := ident.type; |
472 | type.base := ident.type; |
471 | Next(parser) |
473 | Next(parser) |
472 | ELSE |
474 | ELSE |
473 | type.base := NIL |
475 | type.base := NIL |
474 | END |
476 | END |
475 | 477 | ||
476 | END |
478 | END |
477 | END FormalParameters; |
479 | END FormalParameters; |
478 | 480 | ||
479 | 481 | ||
480 | PROCEDURE sysflag (parser: PARSER; proc: BOOLEAN): INTEGER; |
482 | PROCEDURE sysflag (parser: PARSER; proc: BOOLEAN): INTEGER; |
481 | VAR |
483 | VAR |
482 | res, sf: INTEGER; |
484 | res, sf: INTEGER; |
483 | 485 | ||
484 | BEGIN |
486 | BEGIN |
485 | IF parser.lex.s = "stdcall" THEN |
487 | IF parser.lex.s = "stdcall" THEN |
486 | sf := PROG.sf_stdcall |
488 | sf := PROG.sf_stdcall |
487 | ELSIF parser.lex.s = "stdcall64" THEN |
489 | ELSIF parser.lex.s = "stdcall64" THEN |
488 | sf := PROG.sf_stdcall64 |
490 | sf := PROG.sf_stdcall64 |
489 | ELSIF parser.lex.s = "ccall" THEN |
491 | ELSIF parser.lex.s = "ccall" THEN |
490 | sf := PROG.sf_ccall |
492 | sf := PROG.sf_ccall |
491 | ELSIF parser.lex.s = "ccall16" THEN |
493 | ELSIF parser.lex.s = "ccall16" THEN |
492 | sf := PROG.sf_ccall16 |
494 | sf := PROG.sf_ccall16 |
493 | ELSIF parser.lex.s = "win64" THEN |
495 | ELSIF parser.lex.s = "win64" THEN |
494 | sf := PROG.sf_win64 |
496 | sf := PROG.sf_win64 |
495 | ELSIF parser.lex.s = "systemv" THEN |
497 | ELSIF parser.lex.s = "systemv" THEN |
496 | sf := PROG.sf_systemv |
498 | sf := PROG.sf_systemv |
497 | ELSIF parser.lex.s = "windows" THEN |
499 | ELSIF parser.lex.s = "windows" THEN |
498 | sf := PROG.sf_windows |
500 | sf := PROG.sf_windows |
499 | ELSIF parser.lex.s = "linux" THEN |
501 | ELSIF parser.lex.s = "linux" THEN |
500 | sf := PROG.sf_linux |
502 | sf := PROG.sf_linux |
501 | ELSIF parser.lex.s = "code" THEN |
503 | ELSIF parser.lex.s = "code" THEN |
502 | sf := PROG.sf_code |
504 | sf := PROG.sf_code |
503 | ELSIF parser.lex.s = "noalign" THEN |
505 | ELSIF parser.lex.s = "noalign" THEN |
504 | sf := PROG.sf_noalign |
506 | sf := PROG.sf_noalign |
505 | ELSE |
507 | ELSE |
506 | check1(FALSE, parser, 124) |
508 | check1(FALSE, parser, 124) |
507 | END; |
509 | END; |
508 | 510 | ||
509 | check1(sf IN program.target.sysflags, parser, 125); |
511 | check1(sf IN program.target.sysflags, parser, 125); |
510 | 512 | ||
511 | IF proc THEN |
513 | IF proc THEN |
512 | check1(sf IN PROG.proc_flags, parser, 123) |
514 | check1(sf IN PROG.proc_flags, parser, 123) |
513 | ELSE |
515 | ELSE |
514 | check1(sf IN PROG.rec_flags, parser, 123) |
516 | check1(sf IN PROG.rec_flags, parser, 123) |
515 | END; |
517 | END; |
516 | 518 | ||
517 | CASE sf OF |
519 | CASE sf OF |
518 | |PROG.sf_stdcall: |
520 | |PROG.sf_stdcall: |
519 | res := PROG.stdcall |
521 | res := PROG.stdcall |
520 | |PROG.sf_stdcall64: |
522 | |PROG.sf_stdcall64: |
521 | res := PROG.stdcall64 |
523 | res := PROG.stdcall64 |
522 | |PROG.sf_ccall: |
524 | |PROG.sf_ccall: |
523 | res := PROG.ccall |
525 | res := PROG.ccall |
524 | |PROG.sf_ccall16: |
526 | |PROG.sf_ccall16: |
525 | res := PROG.ccall16 |
527 | res := PROG.ccall16 |
526 | |PROG.sf_win64: |
528 | |PROG.sf_win64: |
527 | res := PROG.win64 |
529 | res := PROG.win64 |
528 | |PROG.sf_systemv: |
530 | |PROG.sf_systemv: |
529 | res := PROG.systemv |
531 | res := PROG.systemv |
530 | |PROG.sf_code: |
532 | |PROG.sf_code: |
531 | res := PROG.code |
533 | res := PROG.code |
532 | |PROG.sf_windows: |
534 | |PROG.sf_windows: |
533 | IF program.target.sys IN {mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL} THEN |
535 | IF program.target.sys IN {mConst.Target_iConsole, mConst.Target_iGUI, mConst.Target_iDLL} THEN |
534 | res := PROG.stdcall |
536 | res := PROG.stdcall |
535 | ELSIF program.target.sys IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64} THEN |
537 | ELSIF program.target.sys IN {mConst.Target_iConsole64, mConst.Target_iGUI64, mConst.Target_iDLL64} THEN |
536 | res := PROG.win64 |
538 | res := PROG.win64 |
537 | END |
539 | END |
538 | |PROG.sf_linux: |
540 | |PROG.sf_linux: |
539 | IF program.target.sys IN {mConst.Target_iELF32, mConst.Target_iELFSO32} THEN |
541 | IF program.target.sys IN {mConst.Target_iELF32, mConst.Target_iELFSO32} THEN |
540 | res := PROG.ccall16 |
542 | res := PROG.ccall16 |
541 | ELSIF program.target.sys IN {mConst.Target_iELF64, mConst.Target_iELFSO64} THEN |
543 | ELSIF program.target.sys IN {mConst.Target_iELF64, mConst.Target_iELFSO64} THEN |
542 | res := PROG.systemv |
544 | res := PROG.systemv |
543 | END |
545 | END |
544 | |PROG.sf_noalign: |
546 | |PROG.sf_noalign: |
545 | res := PROG.noalign |
547 | res := PROG.noalign |
546 | END |
548 | END |
547 | 549 | ||
548 | RETURN res |
550 | RETURN res |
549 | END sysflag; |
551 | END sysflag; |
550 | 552 | ||
551 | 553 | ||
552 | PROCEDURE procflag (parser: PARSER; VAR import: IL.IMPORT_PROC; isProc: BOOLEAN): INTEGER; |
554 | PROCEDURE procflag (parser: PARSER; VAR import: IL.IMPORT_PROC; isProc: BOOLEAN): INTEGER; |
553 | VAR |
555 | VAR |
554 | call: INTEGER; |
556 | call: INTEGER; |
555 | dll, proc: SCAN.LEXSTR; |
557 | dll, proc: SCAN.LEXSTR; |
556 | pos: POSITION; |
558 | pos: POSITION; |
557 | 559 | ||
558 | BEGIN |
560 | BEGIN |
559 | 561 | ||
560 | import := NIL; |
562 | import := NIL; |
561 | 563 | ||
562 | IF parser.sym = SCAN.lxLSQUARE THEN |
564 | IF parser.sym = SCAN.lxLSQUARE THEN |
563 | getpos(parser, pos); |
565 | getpos(parser, pos); |
564 | check1(parser.unit.sysimport, parser, 54); |
566 | check1(parser.unit.sysimport, parser, 54); |
565 | Next(parser); |
567 | Next(parser); |
566 | call := sysflag(parser, TRUE); |
568 | call := sysflag(parser, TRUE); |
567 | Next(parser); |
569 | Next(parser); |
568 | IF parser.sym = SCAN.lxMINUS THEN |
570 | IF parser.sym = SCAN.lxMINUS THEN |
569 | Next(parser); |
571 | Next(parser); |
570 | INC(call) |
572 | INC(call) |
571 | END; |
573 | END; |
572 | IF ~isProc THEN |
574 | IF ~isProc THEN |
573 | checklex(parser, SCAN.lxRSQUARE) |
575 | checklex(parser, SCAN.lxRSQUARE) |
574 | END; |
576 | END; |
575 | IF parser.sym = SCAN.lxCOMMA THEN |
577 | IF parser.sym = SCAN.lxCOMMA THEN |
576 | ExpectSym(parser, SCAN.lxSTRING); |
578 | ExpectSym(parser, SCAN.lxSTRING); |
577 | dll := parser.lex.s; |
579 | dll := parser.lex.s; |
578 | ExpectSym(parser, SCAN.lxCOMMA); |
580 | ExpectSym(parser, SCAN.lxCOMMA); |
579 | ExpectSym(parser, SCAN.lxSTRING); |
581 | ExpectSym(parser, SCAN.lxSTRING); |
580 | proc := parser.lex.s; |
582 | proc := parser.lex.s; |
581 | Next(parser); |
583 | Next(parser); |
582 | import := IL.AddImp(dll, proc) |
584 | import := IL.AddImp(dll, proc) |
583 | END; |
585 | END; |
584 | checklex(parser, SCAN.lxRSQUARE); |
586 | checklex(parser, SCAN.lxRSQUARE); |
585 | Next(parser) |
587 | Next(parser) |
586 | ELSE |
588 | ELSE |
587 | CASE program.target.bit_depth OF |
589 | CASE program.target.bit_depth OF |
588 | |16: call := PROG.default16 |
590 | |16: call := PROG.default16 |
589 | |32: call := PROG.default32 |
591 | |32: call := PROG.default32 |
590 | |64: call := PROG.default64 |
592 | |64: call := PROG.default64 |
591 | END |
593 | END |
592 | END; |
594 | END; |
593 | 595 | ||
594 | IF import # NIL THEN |
596 | IF import # NIL THEN |
595 | check(~(program.target.sys IN {mConst.Target_iELF32, mConst.Target_iELF64, mConst.Target_iELFSO32, |
597 | check(~(program.target.sys IN {mConst.Target_iELF32, mConst.Target_iELF64, mConst.Target_iELFSO32, |
596 | mConst.Target_iELFSO64, mConst.Target_iMSP430}), pos, 70) |
598 | mConst.Target_iELFSO64, mConst.Target_iMSP430}), pos, 70) |
597 | END |
599 | END |
598 | 600 | ||
599 | RETURN call |
601 | RETURN call |
600 | END procflag; |
602 | END procflag; |
601 | 603 | ||
602 | 604 | ||
603 | PROCEDURE type (parser: PARSER; VAR t: PROG.TYPE_; flags: SET); |
605 | PROCEDURE type (parser: PARSER; VAR t: PROG.TYPE_; flags: SET); |
604 | CONST |
606 | CONST |
605 | comma = 0; |
607 | comma = 0; |
606 | closed = 1; |
608 | closed = 1; |
607 | forward = 2; |
609 | forward = 2; |
608 | 610 | ||
609 | VAR |
611 | VAR |
610 | arrLen: ARITH.VALUE; |
612 | arrLen: ARITH.VALUE; |
611 | typeSize: ARITH.VALUE; |
613 | typeSize: ARITH.VALUE; |
612 | ident: PROG.IDENT; |
614 | ident: PROG.IDENT; |
613 | unit: PROG.UNIT; |
615 | unit: PROG.UNIT; |
614 | pos, pos2: POSITION; |
616 | pos, pos2: POSITION; |
615 | fieldType: PROG.TYPE_; |
617 | fieldType: PROG.TYPE_; |
616 | baseIdent: SCAN.IDENT; |
618 | baseIdent: SCAN.IDENT; |
617 | a, b: INTEGER; |
619 | a, b: INTEGER; |
618 | RecFlag: INTEGER; |
620 | RecFlag: INTEGER; |
619 | import: IL.IMPORT_PROC; |
621 | import: IL.IMPORT_PROC; |
620 | 622 | ||
621 | BEGIN |
623 | BEGIN |
622 | unit := parser.unit; |
624 | unit := parser.unit; |
623 | t := NIL; |
625 | t := NIL; |
624 | 626 | ||
625 | IF parser.sym = SCAN.lxIDENT THEN |
627 | IF parser.sym = SCAN.lxIDENT THEN |
626 | ident := QIdent(parser, forward IN flags); |
628 | ident := QIdent(parser, forward IN flags); |
627 | 629 | ||
628 | IF ident # NIL THEN |
630 | IF ident # NIL THEN |
629 | check1(ident.typ = PROG.idTYPE, parser, 49); |
631 | check1(ident.typ = PROG.idTYPE, parser, 49); |
630 | t := ident.type; |
632 | t := ident.type; |
631 | check1(t # NIL, parser, 50); |
633 | check1(t # NIL, parser, 50); |
632 | IF closed IN flags THEN |
634 | IF closed IN flags THEN |
633 | check1(t.closed, parser, 50) |
635 | check1(t.closed, parser, 50) |
634 | END |
636 | END |
635 | END; |
637 | END; |
636 | 638 | ||
637 | Next(parser) |
639 | Next(parser) |
638 | 640 | ||
639 | ELSIF (parser.sym = SCAN.lxARRAY) OR ((parser.sym = SCAN.lxCOMMA) & (comma IN flags)) THEN |
641 | ELSIF (parser.sym = SCAN.lxARRAY) OR ((parser.sym = SCAN.lxCOMMA) & (comma IN flags)) THEN |
640 | 642 | ||
641 | IF parser.sym = SCAN.lxARRAY THEN |
643 | IF parser.sym = SCAN.lxARRAY THEN |
642 | getpos(parser, pos2) |
644 | getpos(parser, pos2) |
643 | END; |
645 | END; |
644 | NextPos(parser, pos); |
646 | NextPos(parser, pos); |
645 | 647 | ||
646 | ConstExpression(parser, arrLen); |
648 | ConstExpression(parser, arrLen); |
647 | 649 | ||
648 | check(arrLen.typ = ARITH.tINTEGER, pos, 43); |
650 | check(arrLen.typ = ARITH.tINTEGER, pos, 43); |
649 | check(ARITH.check(arrLen), pos, 39); |
651 | check(ARITH.check(arrLen), pos, 39); |
650 | check(ARITH.getInt(arrLen) > 0, pos, 51); |
652 | check(ARITH.getInt(arrLen) > 0, pos, 51); |
651 | 653 | ||
652 | t := PROG.enterType(program, PROG.tARRAY, -1, ARITH.getInt(arrLen), unit); |
654 | t := PROG.enterType(program, PROG.tARRAY, -1, ARITH.getInt(arrLen), unit); |
653 | 655 | ||
654 | IF parser.sym = SCAN.lxCOMMA THEN |
656 | IF parser.sym = SCAN.lxCOMMA THEN |
655 | type(parser, t.base, {comma, closed}) |
657 | type(parser, t.base, {comma, closed}) |
656 | ELSIF parser.sym = SCAN.lxOF THEN |
658 | ELSIF parser.sym = SCAN.lxOF THEN |
657 | Next(parser); |
659 | Next(parser); |
658 | type(parser, t.base, {closed}) |
660 | type(parser, t.base, {closed}) |
659 | ELSE |
661 | ELSE |
660 | check1(FALSE, parser, 47) |
662 | check1(FALSE, parser, 47) |
661 | END; |
663 | END; |
662 | 664 | ||
663 | t.align := t.base.align; |
665 | t.align := t.base.align; |
664 | 666 | ||
665 | a := t.length; |
667 | a := t.length; |
666 | b := t.base.size; |
668 | b := t.base.size; |
667 | check(ARITH.mulInt(a, b), pos2, 104); |
669 | check(ARITH.mulInt(a, b), pos2, 104); |
668 | check(ARITH.setInt(typeSize, a), pos2, 104); |
670 | check(ARITH.setInt(typeSize, a), pos2, 104); |
669 | t.size := a; |
671 | t.size := a; |
670 | 672 | ||
671 | t.closed := TRUE |
673 | t.closed := TRUE |
672 | 674 | ||
673 | ELSIF parser.sym = SCAN.lxRECORD THEN |
675 | ELSIF parser.sym = SCAN.lxRECORD THEN |
674 | getpos(parser, pos2); |
676 | getpos(parser, pos2); |
675 | Next(parser); |
677 | Next(parser); |
676 | 678 | ||
677 | t := PROG.enterType(program, PROG.tRECORD, 0, 0, unit); |
679 | t := PROG.enterType(program, PROG.tRECORD, 0, 0, unit); |
678 | t.align := 1; |
680 | t.align := 1; |
679 | 681 | ||
680 | IF parser.sym = SCAN.lxLSQUARE THEN |
682 | IF parser.sym = SCAN.lxLSQUARE THEN |
681 | check1(parser.unit.sysimport, parser, 54); |
683 | check1(parser.unit.sysimport, parser, 54); |
682 | Next(parser); |
684 | Next(parser); |
683 | RecFlag := sysflag(parser, FALSE); |
685 | RecFlag := sysflag(parser, FALSE); |
684 | t.noalign := RecFlag = PROG.noalign; |
686 | t.noalign := RecFlag = PROG.noalign; |
685 | ExpectSym(parser, SCAN.lxRSQUARE); |
687 | ExpectSym(parser, SCAN.lxRSQUARE); |
686 | Next(parser) |
688 | Next(parser) |
687 | END; |
689 | END; |
688 | 690 | ||
689 | IF parser.sym = SCAN.lxLROUND THEN |
691 | IF parser.sym = SCAN.lxLROUND THEN |
690 | check1(~t.noalign, parser, 111); |
692 | check1(~t.noalign, parser, 111); |
691 | ExpectSym(parser, SCAN.lxIDENT); |
693 | ExpectSym(parser, SCAN.lxIDENT); |
692 | getpos(parser, pos); |
694 | getpos(parser, pos); |
693 | 695 | ||
694 | type(parser, t.base, {closed}); |
696 | type(parser, t.base, {closed}); |
695 | 697 | ||
696 | check(t.base.typ IN {PROG.tRECORD, PROG.tPOINTER}, pos, 52); |
698 | check(t.base.typ IN {PROG.tRECORD, PROG.tPOINTER}, pos, 52); |
697 | 699 | ||
698 | IF t.base.typ = PROG.tPOINTER THEN |
700 | IF t.base.typ = PROG.tPOINTER THEN |
699 | t.base := t.base.base; |
701 | t.base := t.base.base; |
700 | check(t.base # NIL, pos, 55) |
702 | check(t.base # NIL, pos, 55) |
701 | END; |
703 | END; |
702 | 704 | ||
703 | check(~t.base.noalign, pos, 112); |
705 | check(~t.base.noalign, pos, 112); |
704 | 706 | ||
705 | checklex(parser, SCAN.lxRROUND); |
707 | checklex(parser, SCAN.lxRROUND); |
706 | Next(parser); |
708 | Next(parser); |
707 | 709 | ||
708 | t.size := t.base.size; |
710 | t.size := t.base.size; |
709 | IF t.base.align > t.align THEN |
711 | IF t.base.align > t.align THEN |
710 | t.align := t.base.align |
712 | t.align := t.base.align |
711 | END |
713 | END |
712 | ELSE |
714 | ELSE |
713 | t.base := program.stTypes.tANYREC |
715 | t.base := program.stTypes.tANYREC |
714 | END; |
716 | END; |
715 | 717 | ||
716 | WHILE parser.sym = SCAN.lxIDENT DO |
718 | WHILE parser.sym = SCAN.lxIDENT DO |
717 | FieldList(parser, t); |
719 | FieldList(parser, t); |
718 | 720 | ||
719 | ASSERT(parser.sym = SCAN.lxCOLON); |
721 | ASSERT(parser.sym = SCAN.lxCOLON); |
720 | Next(parser); |
722 | Next(parser); |
721 | 723 | ||
722 | type(parser, fieldType, {closed}); |
724 | type(parser, fieldType, {closed}); |
723 | check(PROG.setFields(t, fieldType), pos2, 104); |
725 | check(PROG.setFields(t, fieldType), pos2, 104); |
724 | 726 | ||
725 | IF (fieldType.align > t.align) & ~t.noalign THEN |
727 | IF (fieldType.align > t.align) & ~t.noalign THEN |
726 | t.align := fieldType.align |
728 | t.align := fieldType.align |
727 | END; |
729 | END; |
728 | 730 | ||
729 | IF parser.sym = SCAN.lxSEMI THEN |
731 | IF parser.sym = SCAN.lxSEMI THEN |
730 | ExpectSym(parser, SCAN.lxIDENT) |
732 | ExpectSym(parser, SCAN.lxIDENT) |
731 | ELSE |
733 | ELSE |
732 | checklex(parser, SCAN.lxEND) |
734 | checklex(parser, SCAN.lxEND) |
733 | END |
735 | END |
734 | END; |
736 | END; |
735 | 737 | ||
736 | t.closed := TRUE; |
738 | t.closed := TRUE; |
737 | 739 | ||
738 | IL.AddRec(t.base.num); |
740 | IL.AddRec(t.base.num); |
739 | 741 | ||
740 | IF ~t.noalign THEN |
742 | IF ~t.noalign THEN |
741 | check(UTILS.Align(t.size, t.align), pos2, 104); |
743 | check(UTILS.Align(t.size, t.align), pos2, 104); |
742 | check(ARITH.setInt(typeSize, t.size), pos2, 104) |
744 | check(ARITH.setInt(typeSize, t.size), pos2, 104) |
743 | END; |
745 | END; |
744 | 746 | ||
745 | checklex(parser, SCAN.lxEND); |
747 | checklex(parser, SCAN.lxEND); |
746 | Next(parser) |
748 | Next(parser) |
747 | 749 | ||
748 | ELSIF parser.sym = SCAN.lxPOINTER THEN |
750 | ELSIF parser.sym = SCAN.lxPOINTER THEN |
749 | ExpectSym(parser, SCAN.lxTO); |
751 | ExpectSym(parser, SCAN.lxTO); |
750 | Next(parser); |
752 | Next(parser); |
751 | 753 | ||
752 | t := PROG.enterType(program, PROG.tPOINTER, program.target.adr, 0, unit); |
754 | t := PROG.enterType(program, PROG.tPOINTER, program.target.adr, 0, unit); |
753 | t.align := program.target.adr; |
755 | t.align := program.target.adr; |
754 | 756 | ||
755 | getpos(parser, pos); |
757 | getpos(parser, pos); |
756 | 758 | ||
757 | IF parser.sym = SCAN.lxIDENT THEN |
759 | IF parser.sym = SCAN.lxIDENT THEN |
758 | baseIdent := parser.lex.ident |
760 | baseIdent := parser.lex.ident |
759 | END; |
761 | END; |
760 | 762 | ||
761 | type(parser, t.base, {forward}); |
763 | type(parser, t.base, {forward}); |
762 | 764 | ||
763 | IF t.base # NIL THEN |
765 | IF t.base # NIL THEN |
764 | check(t.base.typ = PROG.tRECORD, pos, 58) |
766 | check(t.base.typ = PROG.tRECORD, pos, 58) |
765 | ELSE |
767 | ELSE |
766 | PROG.frwPtr(unit, t, baseIdent, pos) |
768 | PROG.frwPtr(unit, t, baseIdent, pos) |
767 | END |
769 | END |
768 | 770 | ||
769 | ELSIF parser.sym = SCAN.lxPROCEDURE THEN |
771 | ELSIF parser.sym = SCAN.lxPROCEDURE THEN |
770 | NextPos(parser, pos); |
772 | NextPos(parser, pos); |
771 | t := PROG.enterType(program, PROG.tPROCEDURE, program.target.adr, 0, unit); |
773 | t := PROG.enterType(program, PROG.tPROCEDURE, program.target.adr, 0, unit); |
772 | t.align := program.target.adr; |
774 | t.align := program.target.adr; |
773 | t.call := procflag(parser, import, FALSE); |
775 | t.call := procflag(parser, import, FALSE); |
774 | FormalParameters(parser, t) |
776 | FormalParameters(parser, t) |
775 | ELSE |
777 | ELSE |
776 | check1(FALSE, parser, 49) |
778 | check1(FALSE, parser, 49) |
777 | END |
779 | END |
778 | 780 | ||
779 | END type; |
781 | END type; |
780 | 782 | ||
781 | 783 | ||
782 | PROCEDURE IdentDef (parser: PARSER; typ: INTEGER; VAR name: SCAN.IDENT): PROG.IDENT; |
784 | PROCEDURE IdentDef (parser: PARSER; typ: INTEGER; VAR name: SCAN.IDENT): PROG.IDENT; |
783 | VAR |
785 | VAR |
784 | ident: PROG.IDENT; |
786 | ident: PROG.IDENT; |
785 | pos: POSITION; |
787 | pos: POSITION; |
786 | 788 | ||
787 | BEGIN |
789 | BEGIN |
788 | ASSERT(parser.sym = SCAN.lxIDENT); |
790 | ASSERT(parser.sym = SCAN.lxIDENT); |
789 | 791 | ||
790 | name := parser.lex.ident; |
792 | name := parser.lex.ident; |
791 | getpos(parser, pos); |
793 | getpos(parser, pos); |
792 | ident := PROG.addIdent(parser.unit, name, typ); |
794 | ident := PROG.addIdent(parser.unit, name, typ); |
793 | check(ident # NIL, pos, 30); |
795 | check(ident # NIL, pos, 30); |
794 | ident.pos := pos; |
796 | ident.pos := pos; |
795 | Next(parser); |
797 | Next(parser); |
796 | 798 | ||
797 | IF parser.sym = SCAN.lxMUL THEN |
799 | IF parser.sym = SCAN.lxMUL THEN |
798 | check1(ident.global, parser, 61); |
800 | check1(ident.global, parser, 61); |
799 | ident.export := TRUE; |
801 | ident.export := TRUE; |
800 | Next(parser) |
802 | Next(parser) |
801 | END |
803 | END |
802 | 804 | ||
803 | RETURN ident |
805 | RETURN ident |
804 | END IdentDef; |
806 | END IdentDef; |
805 | 807 | ||
806 | 808 | ||
807 | PROCEDURE ConstTypeDeclaration (parser: PARSER; const: BOOLEAN); |
809 | PROCEDURE ConstTypeDeclaration (parser: PARSER; const: BOOLEAN); |
808 | VAR |
810 | VAR |
809 | ident: PROG.IDENT; |
811 | ident: PROG.IDENT; |
810 | name: SCAN.IDENT; |
812 | name: SCAN.IDENT; |
811 | pos: POSITION; |
813 | pos: POSITION; |
812 | 814 | ||
813 | BEGIN |
815 | BEGIN |
814 | IF const THEN |
816 | IF const THEN |
815 | ident := IdentDef(parser, PROG.idNONE, name) |
817 | ident := IdentDef(parser, PROG.idNONE, name) |
816 | ELSE |
818 | ELSE |
817 | ident := IdentDef(parser, PROG.idTYPE, name) |
819 | ident := IdentDef(parser, PROG.idTYPE, name) |
818 | END; |
820 | END; |
819 | 821 | ||
820 | checklex(parser, SCAN.lxEQ); |
822 | checklex(parser, SCAN.lxEQ); |
821 | NextPos(parser, pos); |
823 | NextPos(parser, pos); |
822 | 824 | ||
823 | IF const THEN |
825 | IF const THEN |
824 | ConstExpression(parser, ident.value); |
826 | ConstExpression(parser, ident.value); |
825 | IF ident.value.typ = ARITH.tINTEGER THEN |
827 | IF ident.value.typ = ARITH.tINTEGER THEN |
826 | check(ARITH.check(ident.value), pos, 39) |
828 | check(ARITH.check(ident.value), pos, 39) |
827 | ELSIF ident.value.typ = ARITH.tREAL THEN |
829 | ELSIF ident.value.typ = ARITH.tREAL THEN |
828 | check(ARITH.check(ident.value), pos, 40) |
830 | check(ARITH.check(ident.value), pos, 40) |
829 | END; |
831 | END; |
830 | ident.typ := PROG.idCONST; |
832 | ident.typ := PROG.idCONST; |
831 | ident.type := PROG.getType(program, ident.value.typ) |
833 | ident.type := PROG.getType(program, ident.value.typ) |
832 | ELSE |
834 | ELSE |
833 | type(parser, ident.type, {}) |
835 | type(parser, ident.type, {}) |
834 | END; |
836 | END; |
835 | 837 | ||
836 | checklex(parser, SCAN.lxSEMI); |
838 | checklex(parser, SCAN.lxSEMI); |
837 | Next(parser) |
839 | Next(parser) |
838 | 840 | ||
839 | END ConstTypeDeclaration; |
841 | END ConstTypeDeclaration; |
840 | 842 | ||
841 | 843 | ||
842 | PROCEDURE VarDeclaration (parser: PARSER); |
844 | PROCEDURE VarDeclaration (parser: PARSER); |
843 | VAR |
845 | VAR |
844 | ident: PROG.IDENT; |
846 | ident: PROG.IDENT; |
845 | name: SCAN.IDENT; |
847 | name: SCAN.IDENT; |
846 | t: PROG.TYPE_; |
848 | t: PROG.TYPE_; |
847 | 849 | ||
848 | BEGIN |
850 | BEGIN |
849 | 851 | ||
850 | REPEAT |
852 | REPEAT |
851 | ident := IdentDef(parser, PROG.idVAR, name); |
853 | ident := IdentDef(parser, PROG.idVAR, name); |
852 | 854 | ||
853 | IF parser.sym = SCAN.lxCOMMA THEN |
855 | IF parser.sym = SCAN.lxCOMMA THEN |
854 | ExpectSym(parser, SCAN.lxIDENT) |
856 | ExpectSym(parser, SCAN.lxIDENT) |
855 | ELSIF parser.sym = SCAN.lxCOLON THEN |
857 | ELSIF parser.sym = SCAN.lxCOLON THEN |
856 | Next(parser); |
858 | Next(parser); |
857 | type(parser, t, {}); |
859 | type(parser, t, {}); |
858 | PROG.setVarsType(parser.unit, t); |
860 | PROG.setVarsType(parser.unit, t); |
859 | checklex(parser, SCAN.lxSEMI); |
861 | checklex(parser, SCAN.lxSEMI); |
860 | Next(parser) |
862 | Next(parser) |
861 | ELSE |
863 | ELSE |
862 | checklex(parser, SCAN.lxCOLON) |
864 | checklex(parser, SCAN.lxCOLON) |
863 | END |
865 | END |
864 | 866 | ||
865 | UNTIL parser.sym # SCAN.lxIDENT |
867 | UNTIL parser.sym # SCAN.lxIDENT |
866 | 868 | ||
867 | END VarDeclaration; |
869 | END VarDeclaration; |
868 | 870 | ||
869 | 871 | ||
870 | PROCEDURE DeclarationSequence (parser: PARSER): BOOLEAN; |
872 | PROCEDURE DeclarationSequence (parser: PARSER): BOOLEAN; |
871 | VAR |
873 | VAR |
872 | ptr: PROG.FRWPTR; |
874 | ptr: PROG.FRWPTR; |
873 | endmod: BOOLEAN; |
875 | endmod: BOOLEAN; |
874 | pos: POSITION; |
876 | pos: POSITION; |
875 | 877 | ||
876 | 878 | ||
877 | PROCEDURE ProcDeclaration (parser: PARSER): BOOLEAN; |
879 | PROCEDURE ProcDeclaration (parser: PARSER): BOOLEAN; |
878 | VAR |
880 | VAR |
879 | proc: PROG.IDENT; |
881 | proc: PROG.IDENT; |
880 | endname, |
882 | endname, |
881 | name: SCAN.IDENT; |
883 | name: SCAN.IDENT; |
882 | param: PROG.PARAM; |
884 | param: PROG.PARAM; |
883 | unit: PROG.UNIT; |
885 | unit: PROG.UNIT; |
884 | ident: PROG.IDENT; |
886 | ident: PROG.IDENT; |
885 | e: EXPR; |
887 | e: EXPR; |
886 | pos, pos1, |
888 | pos, pos1, |
887 | pos2: POSITION; |
889 | pos2: POSITION; |
888 | label: INTEGER; |
890 | label: INTEGER; |
889 | enter: IL.COMMAND; |
891 | enter: IL.COMMAND; |
890 | call: INTEGER; |
892 | call: INTEGER; |
891 | t: PROG.TYPE_; |
893 | t: PROG.TYPE_; |
892 | import: IL.IMPORT_PROC; |
894 | import: IL.IMPORT_PROC; |
893 | endmod, b: BOOLEAN; |
895 | endmod, b: BOOLEAN; |
894 | fparams: SET; |
896 | fparams: SET; |
895 | variables: LISTS.LIST; |
897 | variables: LISTS.LIST; |
896 | int, flt: INTEGER; |
898 | int, flt: INTEGER; |
897 | comma: BOOLEAN; |
899 | comma: BOOLEAN; |
898 | code: ARITH.VALUE; |
900 | code: ARITH.VALUE; |
899 | codeProc: BOOLEAN; |
901 | codeProc: BOOLEAN; |
900 | 902 | ||
901 | BEGIN |
903 | BEGIN |
902 | endmod := FALSE; |
904 | endmod := FALSE; |
903 | 905 | ||
904 | unit := parser.unit; |
906 | unit := parser.unit; |
905 | 907 | ||
906 | call := procflag(parser, import, TRUE); |
908 | call := procflag(parser, import, TRUE); |
907 | 909 | ||
908 | getpos(parser, pos); |
910 | getpos(parser, pos); |
909 | pos1 := pos; |
911 | pos1 := pos; |
910 | checklex(parser, SCAN.lxIDENT); |
912 | checklex(parser, SCAN.lxIDENT); |
911 | 913 | ||
912 | IF import # NIL THEN |
914 | IF import # NIL THEN |
913 | proc := IdentDef(parser, PROG.idIMP, name); |
915 | proc := IdentDef(parser, PROG.idIMP, name); |
914 | proc.import := import; |
916 | proc.import := import; |
915 | program.procs.last(PROG.PROC).import := import |
917 | program.procs.last(PROG.PROC).import := import |
916 | ELSE |
918 | ELSE |
917 | proc := IdentDef(parser, PROG.idPROC, name) |
919 | proc := IdentDef(parser, PROG.idPROC, name) |
918 | END; |
920 | END; |
919 | 921 | ||
920 | check(PROG.openScope(unit, proc.proc), pos, 116); |
922 | check(PROG.openScope(unit, proc.proc), pos, 116); |
921 | 923 | ||
922 | proc.type := PROG.enterType(program, PROG.tPROCEDURE, program.target.adr, 0, unit); |
924 | proc.type := PROG.enterType(program, PROG.tPROCEDURE, program.target.adr, 0, unit); |
923 | t := proc.type; |
925 | t := proc.type; |
924 | t.align := program.target.adr; |
926 | t.align := program.target.adr; |
925 | t.call := call; |
927 | t.call := call; |
926 | 928 | ||
927 | FormalParameters(parser, t); |
929 | FormalParameters(parser, t); |
928 | 930 | ||
929 | codeProc := call IN {PROG.code, PROG._code}; |
931 | codeProc := call IN {PROG.code, PROG._code}; |
930 | 932 | ||
931 | IF call IN {PROG.systemv, PROG._systemv} THEN |
933 | IF call IN {PROG.systemv, PROG._systemv} THEN |
932 | check(t.parSize <= PROG.MAXSYSVPARAM, pos, 120) |
934 | check(t.parSize <= PROG.MAXSYSVPARAM, pos, 120) |
933 | END; |
935 | END; |
934 | 936 | ||
935 | param := t.params.first(PROG.PARAM); |
937 | param := t.params.first(PROG.PARAM); |
936 | WHILE param # NIL DO |
938 | WHILE param # NIL DO |
937 | ident := PROG.addIdent(unit, param.name, PROG.idPARAM); |
939 | ident := PROG.addIdent(unit, param.name, PROG.idPARAM); |
938 | ASSERT(ident # NIL); |
940 | ASSERT(ident # NIL); |
939 | ident.type := param.type; |
941 | ident.type := param.type; |
940 | ident.offset := param.offset; |
942 | ident.offset := param.offset; |
941 | IF param.vPar THEN |
943 | IF param.vPar THEN |
942 | ident.typ := PROG.idVPAR |
944 | ident.typ := PROG.idVPAR |
943 | END; |
945 | END; |
944 | param := param.next(PROG.PARAM) |
946 | param := param.next(PROG.PARAM) |
945 | END; |
947 | END; |
946 | 948 | ||
947 | IF import = NIL THEN |
949 | IF import = NIL THEN |
948 | label := IL.NewLabel(); |
950 | label := IL.NewLabel(); |
949 | proc.proc.label := label |
951 | proc.proc.label := label |
950 | END; |
952 | END; |
951 | 953 | ||
952 | IF codeProc THEN |
954 | IF codeProc THEN |
953 | enter := IL.EnterC(label); |
955 | enter := IL.EnterC(label); |
954 | comma := FALSE; |
956 | comma := FALSE; |
955 | WHILE (parser.sym # SCAN.lxSEMI) OR comma DO |
957 | WHILE (parser.sym # SCAN.lxSEMI) OR comma DO |
956 | getpos(parser, pos2); |
958 | getpos(parser, pos2); |
957 | ConstExpression(parser, code); |
959 | ConstExpression(parser, code); |
958 | check(code.typ = ARITH.tINTEGER, pos2, 43); |
960 | check(code.typ = ARITH.tINTEGER, pos2, 43); |
959 | IF program.target.sys # mConst.Target_iMSP430 THEN |
961 | IF program.target.sys # mConst.Target_iMSP430 THEN |
960 | check(ARITH.range(code, 0, 255), pos2, 42) |
962 | check(ARITH.range(code, 0, 255), pos2, 42) |
961 | END; |
963 | END; |
962 | IL.AddCmd(IL.opCODE, ARITH.getInt(code)); |
964 | IL.AddCmd(IL.opCODE, ARITH.getInt(code)); |
963 | comma := parser.sym = SCAN.lxCOMMA; |
965 | comma := parser.sym = SCAN.lxCOMMA; |
964 | IF comma THEN |
966 | IF comma THEN |
965 | Next(parser) |
967 | Next(parser) |
966 | ELSE |
968 | ELSE |
967 | checklex(parser, SCAN.lxSEMI) |
969 | checklex(parser, SCAN.lxSEMI) |
968 | END |
970 | END |
969 | END |
971 | END |
970 | END; |
972 | END; |
971 | 973 | ||
972 | checklex(parser, SCAN.lxSEMI); |
974 | checklex(parser, SCAN.lxSEMI); |
973 | Next(parser); |
975 | Next(parser); |
974 | 976 | ||
975 | IF import = NIL THEN |
977 | IF import = NIL THEN |
976 | 978 | ||
977 | IF parser.main & proc.export & program.dll THEN |
979 | IF parser.main & proc.export & program.dll THEN |
978 | IF program.obj THEN |
980 | IF program.obj THEN |
979 | check((proc.name.s # "lib_init") & (proc.name.s # "version"), pos, 114) |
981 | check((proc.name.s # "lib_init") & (proc.name.s # "version"), pos, 114) |
980 | END; |
982 | END; |
981 | IL.AddExp(label, proc.name.s); |
983 | IL.AddExp(label, proc.name.s); |
982 | proc.proc.used := TRUE |
984 | proc.proc.used := TRUE |
983 | END; |
985 | END; |
984 | 986 | ||
985 | IF ~codeProc THEN |
987 | IF ~codeProc THEN |
986 | b := DeclarationSequence(parser) |
988 | b := DeclarationSequence(parser) |
987 | END; |
989 | END; |
988 | 990 | ||
989 | program.locsize := 0; |
991 | program.locsize := 0; |
990 | IF call IN {PROG._win64, PROG.win64} THEN |
992 | IF call IN {PROG._win64, PROG.win64} THEN |
991 | fparams := PROG.getFloatParamsPos(proc.type, 3, int, flt); |
993 | fparams := PROG.getFloatParamsPos(proc.type, 3, int, flt); |
992 | enter := IL.Enter(label, LSL(ORD(fparams), 5) + MIN(proc.type.parSize, 4)) |
994 | enter := IL.Enter(label, LSL(ORD(fparams), 5) + MIN(proc.type.parSize, 4)) |
993 | ELSIF call IN {PROG._systemv, PROG.systemv} THEN |
995 | ELSIF call IN {PROG._systemv, PROG.systemv} THEN |
994 | fparams := PROG.getFloatParamsPos(proc.type, PROG.MAXSYSVPARAM - 1, int, flt); |
996 | fparams := PROG.getFloatParamsPos(proc.type, PROG.MAXSYSVPARAM - 1, int, flt); |
995 | enter := IL.Enter(label, -(LSL(ORD(fparams), 5) + proc.type.parSize)) |
997 | enter := IL.Enter(label, -(LSL(ORD(fparams), 5) + proc.type.parSize)) |
996 | ELSIF codeProc THEN |
998 | ELSIF codeProc THEN |
997 | 999 | ||
998 | ELSE |
1000 | ELSE |
999 | enter := IL.Enter(label, 0) |
1001 | enter := IL.Enter(label, 0) |
1000 | END; |
1002 | END; |
1001 | proc.proc.enter := enter; |
1003 | proc.proc.enter := enter; |
1002 | 1004 | ||
1003 | IF ~codeProc & (parser.sym = SCAN.lxBEGIN) THEN |
1005 | IF ~codeProc & (parser.sym = SCAN.lxBEGIN) THEN |
1004 | Next(parser); |
1006 | Next(parser); |
1005 | parser.StatSeq(parser) |
1007 | parser.StatSeq(parser) |
1006 | END; |
1008 | END; |
1007 | 1009 | ||
1008 | IF ~codeProc & (t.base # NIL) THEN |
1010 | IF ~codeProc & (t.base # NIL) THEN |
1009 | checklex(parser, SCAN.lxRETURN); |
1011 | checklex(parser, SCAN.lxRETURN); |
1010 | NextPos(parser, pos); |
1012 | NextPos(parser, pos); |
1011 | parser.expression(parser, e); |
1013 | parser.expression(parser, e); |
1012 | check(parser.chkreturn(parser, e, t.base, pos), pos, 87) |
1014 | check(parser.chkreturn(parser, e, t.base, pos), pos, 87) |
1013 | END; |
1015 | END; |
1014 | 1016 | ||
1015 | IF ~codeProc THEN |
1017 | IF ~codeProc THEN |
1016 | proc.proc.leave := IL.Leave(t.base # NIL, (t.base # NIL) & (t.base.typ = PROG.tREAL), program.locsize, |
1018 | proc.proc.leave := IL.Leave(t.base # NIL, (t.base # NIL) & (t.base.typ = PROG.tREAL), program.locsize, |
1017 | t.parSize * ORD((t.call IN PROG.callee_clean_up) OR (t.call IN {PROG.systemv, PROG._systemv}))); |
1019 | t.parSize * ORD((t.call IN PROG.callee_clean_up) OR (t.call IN {PROG.systemv, PROG._systemv}))); |
1018 | enter.param2 := program.locsize; |
1020 | enter.param2 := program.locsize; |
1019 | checklex(parser, SCAN.lxEND) |
1021 | checklex(parser, SCAN.lxEND) |
1020 | ELSE |
1022 | ELSE |
1021 | proc.proc.leave := IL.LeaveC() |
1023 | proc.proc.leave := IL.LeaveC() |
1022 | END; |
1024 | END; |
1023 | 1025 | ||
1024 | IF program.target.sys = mConst.Target_iMSP430 THEN |
1026 | IF program.target.sys = mConst.Target_iMSP430 THEN |
1025 | check((enter.param2 * ORD(~codeProc) + proc.type.parSize) * 2 + 16 < program.target.options.ram, pos1, 63) |
1027 | check((enter.param2 * ORD(~codeProc) + proc.type.parSize) * 2 + 16 < program.target.options.ram, pos1, 63) |
1026 | END |
1028 | END |
1027 | END; |
1029 | END; |
1028 | 1030 | ||
1029 | IF parser.sym = SCAN.lxEND THEN |
1031 | IF parser.sym = SCAN.lxEND THEN |
1030 | ExpectSym(parser, SCAN.lxIDENT); |
1032 | ExpectSym(parser, SCAN.lxIDENT); |
1031 | getpos(parser, pos); |
1033 | getpos(parser, pos); |
1032 | endname := parser.lex.ident; |
1034 | endname := parser.lex.ident; |
1033 | IF ~codeProc & (import = NIL) THEN |
1035 | IF ~codeProc & (import = NIL) THEN |
1034 | check(endname = name, pos, 60); |
1036 | check(endname = name, pos, 60); |
1035 | ExpectSym(parser, SCAN.lxSEMI); |
1037 | ExpectSym(parser, SCAN.lxSEMI); |
1036 | Next(parser) |
1038 | Next(parser) |
1037 | ELSE |
1039 | ELSE |
1038 | IF endname = parser.unit.name THEN |
1040 | IF endname = parser.unit.name THEN |
1039 | ExpectSym(parser, SCAN.lxPOINT); |
1041 | ExpectSym(parser, SCAN.lxPOINT); |
1040 | Next(parser); |
1042 | Next(parser); |
1041 | endmod := TRUE |
1043 | endmod := TRUE |
1042 | ELSIF endname = name THEN |
1044 | ELSIF endname = name THEN |
1043 | ExpectSym(parser, SCAN.lxSEMI); |
1045 | ExpectSym(parser, SCAN.lxSEMI); |
1044 | Next(parser) |
1046 | Next(parser) |
1045 | ELSE |
1047 | ELSE |
1046 | error(pos, 60) |
1048 | error(pos, 60) |
1047 | END |
1049 | END |
1048 | END |
1050 | END |
1049 | END; |
1051 | END; |
1050 | 1052 | ||
1051 | IF ~codeProc & (import = NIL) THEN |
1053 | IF ~codeProc & (import = NIL) THEN |
1052 | variables := LISTS.create(NIL); |
1054 | variables := LISTS.create(NIL); |
1053 | ELSE |
1055 | ELSE |
1054 | variables := NIL |
1056 | variables := NIL |
1055 | END; |
1057 | END; |
1056 | 1058 | ||
1057 | PROG.closeScope(unit, variables); |
1059 | PROG.closeScope(unit, variables); |
1058 | 1060 | ||
1059 | IF ~codeProc & (import = NIL) THEN |
1061 | IF ~codeProc & (import = NIL) THEN |
1060 | enter.variables := variables |
1062 | enter.variables := variables |
1061 | END |
1063 | END |
1062 | 1064 | ||
1063 | RETURN endmod |
1065 | RETURN endmod |
1064 | END ProcDeclaration; |
1066 | END ProcDeclaration; |
1065 | 1067 | ||
1066 | 1068 | ||
1067 | BEGIN |
1069 | BEGIN |
1068 | IF parser.sym = SCAN.lxCONST THEN |
1070 | IF parser.sym = SCAN.lxCONST THEN |
1069 | Next(parser); |
1071 | Next(parser); |
1070 | WHILE parser.sym = SCAN.lxIDENT DO |
1072 | WHILE parser.sym = SCAN.lxIDENT DO |
1071 | ConstTypeDeclaration(parser, TRUE) |
1073 | ConstTypeDeclaration(parser, TRUE) |
1072 | END |
1074 | END |
1073 | END; |
1075 | END; |
1074 | 1076 | ||
1075 | IF parser.sym = SCAN.lxTYPE THEN |
1077 | IF parser.sym = SCAN.lxTYPE THEN |
1076 | Next(parser); |
1078 | Next(parser); |
1077 | WHILE parser.sym = SCAN.lxIDENT DO |
1079 | WHILE parser.sym = SCAN.lxIDENT DO |
1078 | ConstTypeDeclaration(parser, FALSE) |
1080 | ConstTypeDeclaration(parser, FALSE) |
1079 | END |
1081 | END |
1080 | END; |
1082 | END; |
1081 | 1083 | ||
1082 | ptr := PROG.linkPtr(parser.unit); |
1084 | ptr := PROG.linkPtr(parser.unit); |
1083 | IF ptr # NIL THEN |
1085 | IF ptr # NIL THEN |
1084 | pos.line := ptr.pos.line; |
1086 | pos.line := ptr.pos.line; |
1085 | pos.col := ptr.pos.col; |
1087 | pos.col := ptr.pos.col; |
1086 | pos.parser := parser; |
1088 | pos.parser := parser; |
1087 | IF ptr.notRecord THEN |
1089 | IF ptr.notRecord THEN |
1088 | error(pos, 58) |
1090 | error(pos, 58) |
1089 | ELSE |
1091 | ELSE |
1090 | error(pos, 48) |
1092 | error(pos, 48) |
1091 | END |
1093 | END |
1092 | END; |
1094 | END; |
1093 | 1095 | ||
1094 | IF parser.sym = SCAN.lxVAR THEN |
1096 | IF parser.sym = SCAN.lxVAR THEN |
1095 | Next(parser); |
1097 | Next(parser); |
1096 | IF parser.sym = SCAN.lxIDENT THEN |
1098 | IF parser.sym = SCAN.lxIDENT THEN |
1097 | VarDeclaration(parser) |
1099 | VarDeclaration(parser) |
1098 | END |
1100 | END |
1099 | END; |
1101 | END; |
1100 | 1102 | ||
1101 | endmod := FALSE; |
1103 | endmod := FALSE; |
1102 | WHILE ~endmod & (parser.sym = SCAN.lxPROCEDURE) DO |
1104 | WHILE ~endmod & (parser.sym = SCAN.lxPROCEDURE) DO |
1103 | Next(parser); |
1105 | Next(parser); |
1104 | endmod := ProcDeclaration(parser) |
1106 | endmod := ProcDeclaration(parser) |
1105 | END |
1107 | END |
1106 | 1108 | ||
1107 | RETURN endmod |
1109 | RETURN endmod |
1108 | END DeclarationSequence; |
1110 | END DeclarationSequence; |
1109 | 1111 | ||
1110 | 1112 | ||
1111 | PROCEDURE parse (parser: PARSER); |
1113 | PROCEDURE parse (parser: PARSER); |
1112 | VAR |
1114 | VAR |
1113 | unit: PROG.UNIT; |
1115 | unit: PROG.UNIT; |
1114 | label: INTEGER; |
1116 | label: INTEGER; |
1115 | name: INTEGER; |
1117 | name: INTEGER; |
1116 | endmod: BOOLEAN; |
1118 | endmod: BOOLEAN; |
1117 | errlabel: INTEGER; |
1119 | errlabel: INTEGER; |
1118 | errno: INTEGER; |
1120 | errno: INTEGER; |
1119 | 1121 | ||
1120 | BEGIN |
1122 | BEGIN |
1121 | ASSERT(parser # NIL); |
1123 | ASSERT(parser # NIL); |
1122 | ASSERT(parser.scanner # NIL); |
1124 | ASSERT(parser.scanner # NIL); |
1123 | 1125 | ||
1124 | ExpectSym(parser, SCAN.lxMODULE); |
1126 | ExpectSym(parser, SCAN.lxMODULE); |
1125 | ExpectSym(parser, SCAN.lxIDENT); |
1127 | ExpectSym(parser, SCAN.lxIDENT); |
1126 | 1128 | ||
1127 | IF ~parser.main THEN |
1129 | IF ~parser.main THEN |
1128 | check1(parser.lex.s = parser.modname, parser, 23) |
1130 | check1(parser.lex.s = parser.modname, parser, 23) |
1129 | END; |
1131 | END; |
1130 | 1132 | ||
1131 | unit := PROG.newUnit(program, parser.lex.ident); |
1133 | unit := PROG.newUnit(program, parser.lex.ident); |
1132 | 1134 | ||
1133 | parser.unit := unit; |
1135 | parser.unit := unit; |
1134 | 1136 | ||
1135 | ExpectSym(parser, SCAN.lxSEMI); |
1137 | ExpectSym(parser, SCAN.lxSEMI); |
1136 | 1138 | ||
1137 | Next(parser); |
1139 | Next(parser); |
1138 | IF parser.sym = SCAN.lxIMPORT THEN |
1140 | IF parser.sym = SCAN.lxIMPORT THEN |
1139 | ImportList(parser) |
1141 | ImportList(parser) |
1140 | END; |
1142 | END; |
1141 | 1143 | ||
1142 | CONSOLE.String("compiling "); CONSOLE.String(unit.name.s); |
1144 | CONSOLE.String("compiling "); CONSOLE.String(unit.name.s); |
1143 | IF parser.unit.sysimport THEN |
1145 | IF parser.unit.sysimport THEN |
1144 | CONSOLE.String(" (SYSTEM)") |
1146 | CONSOLE.String(" (SYSTEM)") |
1145 | END; |
1147 | END; |
1146 | CONSOLE.Ln; |
1148 | CONSOLE.Ln; |
1147 | 1149 | ||
1148 | label := IL.NewLabel(); |
1150 | label := IL.NewLabel(); |
1149 | IL.AddJmpCmd(IL.opJMP, label); |
1151 | IL.AddJmpCmd(IL.opJMP, label); |
1150 | 1152 | ||
1151 | name := IL.putstr(unit.name.s); |
1153 | name := IL.putstr(unit.name.s); |
1152 | 1154 | ||
1153 | errlabel := IL.NewLabel(); |
1155 | errlabel := IL.NewLabel(); |
1154 | IL.SetLabel(errlabel); |
1156 | IL.SetLabel(errlabel); |
1155 | IL.StrAdr(name); |
1157 | IL.StrAdr(name); |
1156 | IL.Param1; |
1158 | IL.Param1; |
1157 | IL.AddCmd0(IL.opERR); |
1159 | IL.AddCmd0(IL.opERR); |
1158 | 1160 | ||
1159 | FOR errno := 1 TO LEN(IL.codes.errlabels) - 1 DO |
1161 | FOR errno := 1 TO LEN(IL.codes.errlabels) - 1 DO |
1160 | IL.SetErrLabel(errno); |
1162 | IL.SetErrLabel(errno); |
1161 | IL.AddCmd(IL.opPUSHC, errno); |
1163 | IL.AddCmd(IL.opPUSHC, errno); |
1162 | IL.AddJmpCmd(IL.opJMP, errlabel) |
1164 | IL.AddJmpCmd(IL.opJMP, errlabel) |
1163 | END; |
1165 | END; |
1164 | 1166 | ||
1165 | endmod := DeclarationSequence(parser); |
1167 | endmod := DeclarationSequence(parser); |
1166 | 1168 | ||
1167 | IL.SetLabel(label); |
1169 | IL.SetLabel(label); |
1168 | 1170 | ||
1169 | IF ~endmod THEN |
1171 | IF ~endmod THEN |
1170 | 1172 | ||
1171 | IF parser.sym = SCAN.lxBEGIN THEN |
1173 | IF parser.sym = SCAN.lxBEGIN THEN |
1172 | Next(parser); |
1174 | Next(parser); |
1173 | parser.StatSeq(parser) |
1175 | parser.StatSeq(parser) |
1174 | END; |
1176 | END; |
1175 | 1177 | ||
1176 | checklex(parser, SCAN.lxEND); |
1178 | checklex(parser, SCAN.lxEND); |
1177 | 1179 | ||
1178 | ExpectSym(parser, SCAN.lxIDENT); |
1180 | ExpectSym(parser, SCAN.lxIDENT); |
1179 | check1(parser.lex.s = unit.name.s, parser, 25); |
1181 | check1(parser.lex.s = unit.name.s, parser, 25); |
1180 | ExpectSym(parser, SCAN.lxPOINT) |
1182 | ExpectSym(parser, SCAN.lxPOINT) |
1181 | - | ||
1182 | END; |
1183 | END; |
- | 1184 | ||
1183 | 1185 | INC(lines, parser.lex.pos.line); |
|
1184 | PROG.closeUnit(unit) |
1186 | PROG.closeUnit(unit) |
1185 | END parse; |
1187 | END parse; |
1186 | 1188 | ||
1187 | 1189 | ||
1188 | PROCEDURE open (parser: PARSER; modname: ARRAY OF CHAR): BOOLEAN; |
1190 | PROCEDURE open (parser: PARSER; modname: ARRAY OF CHAR): BOOLEAN; |
1189 | BEGIN |
1191 | BEGIN |
1190 | ASSERT(parser # NIL); |
1192 | ASSERT(parser # NIL); |
1191 | 1193 | ||
1192 | STRINGS.append(parser.fname, modname); |
1194 | STRINGS.append(parser.fname, modname); |
1193 | STRINGS.append(parser.fname, parser.ext); |
1195 | STRINGS.append(parser.fname, parser.ext); |
1194 | STRINGS.append(parser.modname, modname); |
1196 | STRINGS.append(parser.modname, modname); |
1195 | 1197 | ||
1196 | parser.scanner := SCAN.open(parser.fname) |
1198 | parser.scanner := SCAN.open(parser.fname) |
1197 | 1199 | ||
1198 | RETURN parser.scanner # NIL |
1200 | RETURN parser.scanner # NIL |
1199 | END open; |
1201 | END open; |
1200 | 1202 | ||
1201 | 1203 | ||
1202 | PROCEDURE NewParser (): PARSER; |
1204 | PROCEDURE NewParser (): PARSER; |
1203 | VAR |
1205 | VAR |
1204 | pars: PARSER; |
1206 | pars: PARSER; |
1205 | citem: C.ITEM; |
1207 | citem: C.ITEM; |
1206 | 1208 | ||
1207 | BEGIN |
1209 | BEGIN |
1208 | citem := C.pop(parsers); |
1210 | citem := C.pop(parsers); |
1209 | IF citem = NIL THEN |
1211 | IF citem = NIL THEN |
1210 | NEW(pars) |
1212 | NEW(pars) |
1211 | ELSE |
1213 | ELSE |
1212 | pars := citem(PARSER) |
1214 | pars := citem(PARSER) |
1213 | END |
1215 | END |
1214 | 1216 | ||
1215 | RETURN pars |
1217 | RETURN pars |
1216 | END NewParser; |
1218 | END NewParser; |
1217 | 1219 | ||
1218 | 1220 | ||
1219 | PROCEDURE create* (path, lib_path: PATH; StatSeq: STATPROC; expression, designator: EXPRPROC; chkreturn: RETPROC): PARSER; |
1221 | PROCEDURE create* (path, lib_path: PATH; StatSeq: STATPROC; expression, designator: EXPRPROC; chkreturn: RETPROC): PARSER; |
1220 | VAR |
1222 | VAR |
1221 | parser: PARSER; |
1223 | parser: PARSER; |
1222 | 1224 | ||
1223 | BEGIN |
1225 | BEGIN |
1224 | parser := NewParser(); |
1226 | parser := NewParser(); |
1225 | 1227 | ||
1226 | parser.path := path; |
1228 | parser.path := path; |
1227 | parser.lib_path := lib_path; |
1229 | parser.lib_path := lib_path; |
1228 | parser.ext := mConst.FILE_EXT; |
1230 | parser.ext := mConst.FILE_EXT; |
1229 | parser.fname := path; |
1231 | parser.fname := path; |
1230 | parser.modname := ""; |
1232 | parser.modname := ""; |
1231 | parser.scanner := NIL; |
1233 | parser.scanner := NIL; |
1232 | parser.unit := NIL; |
1234 | parser.unit := NIL; |
1233 | parser.constexp := FALSE; |
1235 | parser.constexp := FALSE; |
1234 | parser.main := FALSE; |
1236 | parser.main := FALSE; |
1235 | 1237 | ||
1236 | parser.open := open; |
1238 | parser.open := open; |
1237 | parser.parse := parse; |
1239 | parser.parse := parse; |
1238 | parser.StatSeq := StatSeq; |
1240 | parser.StatSeq := StatSeq; |
1239 | parser.expression := expression; |
1241 | parser.expression := expression; |
1240 | parser.designator := designator; |
1242 | parser.designator := designator; |
1241 | parser.chkreturn := chkreturn; |
1243 | parser.chkreturn := chkreturn; |
1242 | parser.create := create |
1244 | parser.create := create |
1243 | 1245 | ||
1244 | RETURN parser |
1246 | RETURN parser |
1245 | END create; |
1247 | END create; |
1246 | 1248 | ||
1247 | 1249 | ||
1248 | PROCEDURE init* (bit_depth, target: INTEGER; options: PROG.OPTIONS); |
1250 | PROCEDURE init* (bit_depth, target: INTEGER; options: PROG.OPTIONS); |
1249 | BEGIN |
1251 | BEGIN |
1250 | program := PROG.create(bit_depth, target, options); |
1252 | program := PROG.create(bit_depth, target, options); |
1251 | parsers := C.create() |
1253 | parsers := C.create(); |
- | 1254 | lines := 0 |
|
1252 | END init; |
1255 | END init; |
1253 | 1256 | ||
1254 | 1257 | ||
1255 | END PARS.>=>=>=>> |
1258 | END PARS.>=>=>=>> |