comparison tests/agcl/oldagsrc/xvmc.syn @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:13d2b8934445
1 {
2 /*
3 XVMC.SYN
4
5 Extensible Scripting Language
6 Copyright (c) 1998 Parsifal Software, All Rights Reserved.
7
8 The expression syntax is borrowed from C but with the
9 addition of the FORTRAN exponentiation operator (**).
10
11 The supported operations are:
12 Assignment operators: =, +=, -=, *=, /=, %=, , &=, |=, ^=>>=, <<=
13 Conditional expressions: ? :
14 Logical operators: !, &&, ||
15 Bitwise logical operators: &, |, ^, ~
16 Comparison operators: ==, !=, <, <=, >, >=
17 Shift operators: <<, >>
18 Binary arithmetic operators: +, -, *, /, %
19 Unary arithmetic operators: +, -
20 Exponentiation: **
21 Autoincrement operators: ++, --;
22 Cast operators (<type name>)
23 Parentheses
24 Function calls
25 Object method calls
26
27 Built in data types are int, double and String.
28
29 Statements may include variable declarations, expression statements,
30 blocks, if/else statements, while , do/while, or for statements,
31 following the rules of C.
32
33 The statement syntax has been written to avoid the conventional
34 if/else ambiguity.
35
36 Input strings may contain any number of statements. White space may be
37 used freely, including both C and C++ style comments.
38
39 xvmc.syn is compiled with the AnaGram parser generator
40 yielding xvm.h and xvm.cpp.
41
42 For information about AnaGram, visit http://www.parsifalsoft.com.
43 */
44
45 #include <math.h>
46 #include "xvm.h" // defines external interface
47 #include "integer.h"
48 #include "double.h"
49 #include "xstring.h"
50
51 static VirtualMachine *vm;
52
53 typedef VirtualMachine::CodeSeg Code; // For the sake of readability
54
55 }
56 // -- CONFIGURATION SECTION ----------------------------
57 [
58 default token type = Code
59 disregard white space
60 lexeme {real, name string, string literal, character constant}
61 distinguish lexemes
62 distinguish keywords {'a-z' + 'A-Z' + '0-9' + '_'}
63 pointer input
64 parser name = vmCompile
65 parser file name = "#.cpp"
66 line numbers
67 ~allow macros
68 escape backslashes // for Visual C++
69 ]
70
71 input string $ // specify grammar token
72 -> eof =Code();
73 -> statements:x, eof =x;
74 -> statements:x, error, ~(eof + ';' + '}' + space)?..., eof =x;
75
76 statement
77 -> executable statement
78 -> declaration, ';'
79 -> error, ~(eof + ';' + '}' + space)?..., ';' =errorLog.add("Continuing scan"), Code();
80
81 declaration
82 -> type name:t, name string:n =vm->declareVariable(t,n), Code();
83 -> type name:t, name string:n, '=', expression:x ={
84 int name = vm->declareVariable(t,n);
85 return Code(VirtualMachine::PUSHV) << name << x << VirtualMachine::ASSIGN << VirtualMachine::POP;
86 }
87 -> type name:t, name string:n, '[', expression:size, ']' =vm->declareArray(t,n, size);
88 -> type name:t, name string:n, '(', expression list:args, ')' =vm->declareObject(t,n,args);
89
90 expression list
91 -> =Code();
92 -> expressions:x =x;
93
94 expressions
95 -> expression:x =x.initList();
96 -> expressions:list, ',', expression:x =list.append(x);
97
98
99 executable statement
100 -> unconditional statement
101 -> conditional statement
102
103 statements
104 -> statement:x =x;
105 -> statements:x, statement:s =x << s;
106
107
108 /*
109 An unconditional statement is any statement that does not involve
110 an if statement
111 */
112
113 unconditional statement
114 -> expression:x, ';' =x << VirtualMachine::POP;
115 -> ';' =Code();
116 -> '{', '}' =Code();
117 -> '{', statements:s, '}' =s;
118 -> '{', statements:s, error, ~(eof + ';' + '}' + space)?..., '}' =errorLog.add("Continuing scan"), s;
119 -> "do", executable statement:s, while clause:x, ';' =vm->codeDoWhile(s,x);
120 -> while clause:x, unconditional statement:s =vm->codeWhile(x,s);
121 -> "for", '(', for exprs:init, ';', condition:cond, ';', for exprs:inc,
122 ')', unconditional statement:s =vm->codeFor(init, cond, inc, s);
123
124 for exprs
125 -> =Code();
126 -> for expr list
127
128 for expr list
129 -> expression:x =x << VirtualMachine::POP;
130 -> for expr list:list, ',', expression:x =list << x << VirtualMachine::POP;
131
132 while clause
133 -> "while", '(', condition:x, ')' =x;
134
135
136 /*
137 Any statement with an if in it is a conditional statement
138 */
139
140 conditional statement
141 -> while clause:x, conditional statement:s =vm->codeWhile(x,s);
142 -> "for", '(', for exprs:init, ';', condition:cond, ';', for exprs:inc,
143 ')', conditional statement:s =vm->codeFor(init, cond, inc, s);
144 -> if clause:x, executable statement:s =x << VirtualMachine::BRF << s.size() << s;
145 -> if clause:x, unconditional statement:s1,
146 "else", statement:s2 ={
147 s1 << VirtualMachine::BR << s2.size();
148 x << VirtualMachine::BRF << s1.size() << s1 << s2;
149 return x;
150 }
151
152 if clause
153 -> "if", '(', condition:x, ')' =x;
154
155 condition
156 -> expression:x =x.testOK();
157
158 expression
159 -> conditional expression
160 -> lvalue:k, '=', expression:x =k << x << VirtualMachine::ASSIGN;
161 -> lvalue:k, "+=", expression:x =k << x << VirtualMachine::ADD_EQ;
162 -> lvalue:k, "-=", expression:x =k << x << VirtualMachine::SUB_EQ;
163 -> lvalue:k, "*=", expression:x =k << x << VirtualMachine::MULT_EQ;
164 -> lvalue:k, "/=", expression:x =k << x << VirtualMachine::DIV_EQ;
165 -> lvalue:k, "%=", expression:x =k << x << VirtualMachine::MOD_EQ;
166 -> lvalue:k, "|=", expression:x =k << x << VirtualMachine::OR_EQ;
167 -> lvalue:k, "&=", expression:x =k << x << VirtualMachine::AND_EQ;
168 -> lvalue:k, "^=", expression:x =k << x << VirtualMachine::XOR_EQ;
169 -> lvalue:k, "<<=", expression:x =k << x << VirtualMachine::LS_EQ;
170 -> lvalue:k, ">>=", expression:x =k << x << VirtualMachine::RS_EQ;
171
172 lvalue
173 -> variable name:k =Code(VirtualMachine::PUSHV).setType(vm->symbolTable[k].type) << k;
174 -> lvalue:k, '[', expression:x, ']' =k.setType(k.type->element) << x << VirtualMachine::SUBSCRIPT;
175
176 conditional expression
177 -> logical or expression
178 -> logical or condition:c, '?',
179 expression:x, ':', conditional expression:y ={
180 //if (!c.type->isTruthDefined()) errorLog.add("True/False not defined");
181 x << VirtualMachine::BR << y.size();
182 c << VirtualMachine::BRF << x.size() << x << y;
183 return c;
184 }
185
186 logical or condition
187 -> logical or expression:x =x.testOK();
188
189 logical or expression
190 -> logical and expression
191 -> logical or condition:x, "||",logical and expression:y ={
192 //if (!x.type->isTruthDefined()) errorLog.add("True/False not defined");
193 return x << VirtualMachine::OR << y.size() << y;
194 }
195
196 logical and expression
197 -> bitwise or expression
198 -> logical and condition:x, "&&", bitwise or expression:y ={
199 //if (!x.type->isTruthDefined()) errorLog.add("True/False not defined");
200 return x << VirtualMachine::AND << y.size() << y;
201 }
202
203 logical and condition
204 -> logical and expression:x =x.testOK();
205
206
207
208 bitwise or expression
209 -> bitwise xor expression
210 -> bitwise or expression:x, '|',
211 bitwise xor expression:y =x.binop(VirtualMachine::BITOR,y);
212
213 bitwise xor expression
214 -> bitwise and expression
215 -> bitwise xor expression:x, '^',
216 bitwise and expression:y =x.binop(VirtualMachine::XOR,y);
217
218 bitwise and expression
219 -> equality expression
220 -> bitwise and expression:x, '&',
221 equality expression:y =x.binop(VirtualMachine::BITAND,y);
222
223 equality expression
224 -> relational expression
225 -> equality expression:x, "==", relational expression:y =x.binop(VirtualMachine::EQ,y);
226 -> equality expression:x, "!=", relational expression:y =x.binop(VirtualMachine::NE,y);
227
228 relational expression
229 -> shift expression
230 -> relational expression:x, '<', shift expression:y =x.binop(VirtualMachine::LT,y);
231 -> relational expression:x, "<=", shift expression:y =x.binop(VirtualMachine::LE,y);
232 -> relational expression:x, '>', shift expression:y =x.binop(VirtualMachine::GT,y);
233 -> relational expression:x, ">=", shift expression:y =x.binop(VirtualMachine::GE,y);
234
235 shift expression
236 -> additive expression
237 -> shift expression:x, "<<", additive expression:y =x.binop(VirtualMachine::LS,y);
238 -> shift expression:x, ">>", additive expression:y =x.binop(VirtualMachine::RS,y);
239
240 additive expression
241 -> multiplicative expression
242 -> additive expression:x, '+',
243 multiplicative expression:y =x.binop(VirtualMachine::ADD,y);
244 -> additive expression:x, '-',
245 multiplicative expression:y =x.binop(VirtualMachine::SUB,y);
246
247 multiplicative expression
248 -> cast expression
249 -> multiplicative expression:x, '*', cast expression:y =x.binop(VirtualMachine::MULT,y);
250 -> multiplicative expression:x, '/', cast expression:y =x.binop(VirtualMachine::DIV,y);
251 -> multiplicative expression:x, '%', cast expression:y =x.binop(VirtualMachine::MOD,y);
252
253 cast expression
254 -> unary expression
255 -> '(', type name:t, ')', cast expression:x =x.cast((VirtualMachine::Type::Id) t) << VirtualMachine::CAST << t;
256
257 unary expression
258 -> power expression
259 -> "++", unary expression:x =x << VirtualMachine::INCR;
260 -> "--", unary expression:x =x << VirtualMachine::INCR;
261 -> '-', unary expression:x =x << VirtualMachine::NEG;
262 -> '+', unary expression:x =x;
263 -> '!', unary expression:x =vm->list(stdout), x << VirtualMachine::NOT;
264 -> '~', unary expression:x =x << VirtualMachine::COMPL;
265
266
267
268 power expression
269 -> primary
270 -> primary:x, "**", unary expression:y =x.binop(VirtualMachine::POW,y);
271
272 primary
273 -> real:x =vm->doubleList.push(x), Code(VirtualMachine::PUSHD).setType(&DoubleType::doubleType) << (int)(vm->doubleList.size() - 1);
274 -> integer constant:x =Code(VirtualMachine::PUSHI).setType(&IntegerType::intType) << x;
275 -> string literal:k =Code(VirtualMachine::PUSHS).setType(&StringType::stringType) << k;
276 -> lvalue:k =k;
277 -> lvalue:k, "++" =k << VirtualMachine::PUSH << VirtualMachine::INCR << VirtualMachine::POP;
278 -> lvalue:k, "--" =k << VirtualMachine::PUSH << VirtualMachine::DECR << VirtualMachine::POP;
279 -> name string:n, '(', expression list:args, ')' =vm->invokeFunction(n, args);
280 -> lvalue:k, '.', name string:n, '(', expression list: args, ')' =vm->invokeMethod(k, n, args);
281 -> '(', expression:x, ')' =x;
282
283 // -- LEXICAL UNITS ------------------------------------------------
284 digit = '0-9'
285 eof = 0
286 letter = 'a-z' + 'A-Z' + '_'
287 space = ' ' + '\t' + '\f' + '\v' + '\r' + '\n'
288
289
290 (void) white space
291 -> space
292 -> "/*", ~eof?..., "*/" // C style comment
293 -> "//", ~(eof+'\n')?..., '\n' // C++ style comment
294
295 (double) real
296 -> simple real
297 -> simple real:x, 'e'+'E', '+'?,exponent:e =x*pow(10,e);
298 -> simple real:x, 'e'+'E', '-',exponent:e =x*pow(10,-e);
299
300 (double) simple real
301 -> integer:i, '.', fraction part:f = i+f;
302 -> integer:i, '.' =i;
303 -> '.', fraction part:f = f;
304
305 (int) integer constant
306 -> integer
307 -> character constant
308
309 (int) integer
310 -> digit:d = d-'0';
311 -> integer:x, digit:d = 10*x + d-'0';
312
313 (double) fraction part
314 -> digit:d =(d-'0')/10.;
315 -> digit:d, fraction part:f =(d-'0' + f)/10.;
316
317 (int) exponent
318 -> digit:d = d-'0';
319 -> exponent:x, digit:d = 10*x + d-'0';
320
321 (int) type name, variable name
322 -> name string:k ={
323 char *name = popString(k);
324 VirtualMachine::Type::Id id = VirtualMachine::Type::idType(name);
325 if (id != VirtualMachine::Type::UNDEFINED) return (int) id;
326 CHANGE_REDUCTION(variable_name);
327 return vm->locateVariable(name);
328 }
329
330 (int) name string
331 -> letter: c =pushChar(c), 1;
332 -> name string:k, letter+digit: c =pushChar(c), k+1;
333
334 not double quote = ~eof - ('"' + '\\' + '\n')
335 not single quote = ~eof - ('\'' + '\\' + '\n')
336
337 (int) character constant
338 -> '\'', char constant element:c, '\'' =c;
339
340 (int) char constant element
341 -> not single quote
342 -> escape sequence
343
344 (int) string literal
345 -> string chars:k, '"' =vm->stringList.push(CharString(popString(k))), vm->stringList.size() - 1;
346
347 (int) string chars
348 -> '"' =0;
349 -> string chars:k, string char:c =pushChar(c), k+1;
350
351 (int) string char
352 -> not double quote
353 -> escape sequence
354
355 (int) escape sequence
356 -> "\\a" ='\a';
357 -> "\\b" ='\b';
358 -> "\\f" ='\f';
359 -> "\\n" ='\n';
360 -> "\\r" ='\r';
361 -> "\\t" ='\t';
362 -> "\\v" ='\v';
363 -> "\\\\" ='\\';
364 -> "\\?" = '\?';
365 -> "\\'" ='\'';
366 -> "\\\"" ='"';
367 -> octal escape
368 -> hex escape
369
370 (int) octal escape
371 -> one octal | two octal | three octal
372
373 (int) one octal
374 -> '\\', '0-7':d =d-'0';
375
376 (int) two octal
377 -> one octal:n, '0-7':d =8*n + d-'0';
378
379 (int) three octal
380 -> two octal:n, '0-7':d =8*n + d-'0';
381
382 (int) hex escape
383 -> "\\x", hex digit:d =d;
384 -> hex escape:n, hex digit:d =16*n + d;
385
386 (int) hex digit
387 -> '0-9'
388 -> 'a-f' + 'A-F':d =(d&7) + 9;
389
390 [
391 sticky {one octal, two octal, hex escape}
392 ]
393
394
395
396 { // begin embedded C
397
398 #include <string.h>
399
400
401 ErrorRecord::ErrorRecord(char *msg) : message(msg), line(PCB.line), column(PCB.column)
402 {/* Initializers do it all */}
403
404 ErrorLog errorLog;
405
406 #define SYNTAX_ERROR errorLog.add(PCB.error_message)
407
408 int VirtualMachine::compile(char *text) {
409 vm = this;
410 resetCharStack();
411 vmCompile_pcb.pointer = (unsigned char *) text;
412 vmCompile();
413 {
414 Code program = vmCompile_value() << EXIT;
415 int n = program.size();
416 codeStore = new int[n];
417 while (n--) codeStore[n] = program[n];
418 }
419
420 return vmCompile_pcb.exit_flag != AG_SUCCESS_CODE;
421 }
422
423 Code VirtualMachine::codeWhile(Code x, Code s) {
424 Code branch(VirtualMachine::BR);
425 branch << 0;
426 //if (!x.type->isTruthDefined()) errorLog.add("True/False not defined");
427 x << VirtualMachine::BRF << (s.size() + branch.size());
428 int blockLength = s.size() + x.size() + branch.size();
429 x << s << VirtualMachine::BR << -blockLength;
430 return x;
431 }
432
433 Code VirtualMachine::codeDoWhile(Code s, Code x) {
434 Code branch(VirtualMachine::BR);
435 branch << 0;
436 int blockLength = s.size() + x.size() + branch.size();
437 //if (!x.type->isTruthDefined()) errorLog.add("True/False not defined");
438 s << x << VirtualMachine::BRT << -blockLength;
439 return s;
440 }
441
442 Code VirtualMachine::codeFor(Code init, Code cond, Code inc, Code s) {
443 s << inc; // append increment code to end of body of for loop
444 //if (!cond.type->isTruthDefined()) errorLog.add("True/False not defined");
445 init << codeWhile(cond, s);
446 return init;
447 }
448
449 } // end of embedded C
450 /********************* End of VM.SYN ************************/