Mercurial > ~dholland > hg > ag > index.cgi
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/agcl/oldagsrc/xvmc.syn Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,450 @@ +{ +/* + XVMC.SYN + + Extensible Scripting Language + Copyright (c) 1998 Parsifal Software, All Rights Reserved. + + The expression syntax is borrowed from C but with the + addition of the FORTRAN exponentiation operator (**). + + The supported operations are: + Assignment operators: =, +=, -=, *=, /=, %=, , &=, |=, ^=>>=, <<= + Conditional expressions: ? : + Logical operators: !, &&, || + Bitwise logical operators: &, |, ^, ~ + Comparison operators: ==, !=, <, <=, >, >= + Shift operators: <<, >> + Binary arithmetic operators: +, -, *, /, % + Unary arithmetic operators: +, - + Exponentiation: ** + Autoincrement operators: ++, --; + Cast operators (<type name>) + Parentheses + Function calls + Object method calls + + Built in data types are int, double and String. + + Statements may include variable declarations, expression statements, + blocks, if/else statements, while , do/while, or for statements, + following the rules of C. + + The statement syntax has been written to avoid the conventional + if/else ambiguity. + + Input strings may contain any number of statements. White space may be + used freely, including both C and C++ style comments. + + xvmc.syn is compiled with the AnaGram parser generator + yielding xvm.h and xvm.cpp. + + For information about AnaGram, visit http://www.parsifalsoft.com. +*/ + +#include <math.h> +#include "xvm.h" // defines external interface +#include "integer.h" +#include "double.h" +#include "xstring.h" + +static VirtualMachine *vm; + +typedef VirtualMachine::CodeSeg Code; // For the sake of readability + +} +// -- CONFIGURATION SECTION ---------------------------- +[ + default token type = Code + disregard white space + lexeme {real, name string, string literal, character constant} + distinguish lexemes + distinguish keywords {'a-z' + 'A-Z' + '0-9' + '_'} + pointer input + parser name = vmCompile + parser file name = "#.cpp" + line numbers + ~allow macros + escape backslashes // for Visual C++ +] + +input string $ // specify grammar token + -> eof =Code(); + -> statements:x, eof =x; + -> statements:x, error, ~(eof + ';' + '}' + space)?..., eof =x; + +statement + -> executable statement + -> declaration, ';' + -> error, ~(eof + ';' + '}' + space)?..., ';' =errorLog.add("Continuing scan"), Code(); + +declaration + -> type name:t, name string:n =vm->declareVariable(t,n), Code(); + -> type name:t, name string:n, '=', expression:x ={ + int name = vm->declareVariable(t,n); + return Code(VirtualMachine::PUSHV) << name << x << VirtualMachine::ASSIGN << VirtualMachine::POP; + } + -> type name:t, name string:n, '[', expression:size, ']' =vm->declareArray(t,n, size); + -> type name:t, name string:n, '(', expression list:args, ')' =vm->declareObject(t,n,args); + +expression list + -> =Code(); + -> expressions:x =x; + +expressions + -> expression:x =x.initList(); + -> expressions:list, ',', expression:x =list.append(x); + + +executable statement + -> unconditional statement + -> conditional statement + +statements + -> statement:x =x; + -> statements:x, statement:s =x << s; + + +/* + An unconditional statement is any statement that does not involve + an if statement +*/ + +unconditional statement + -> expression:x, ';' =x << VirtualMachine::POP; + -> ';' =Code(); + -> '{', '}' =Code(); + -> '{', statements:s, '}' =s; + -> '{', statements:s, error, ~(eof + ';' + '}' + space)?..., '}' =errorLog.add("Continuing scan"), s; + -> "do", executable statement:s, while clause:x, ';' =vm->codeDoWhile(s,x); + -> while clause:x, unconditional statement:s =vm->codeWhile(x,s); + -> "for", '(', for exprs:init, ';', condition:cond, ';', for exprs:inc, + ')', unconditional statement:s =vm->codeFor(init, cond, inc, s); + +for exprs + -> =Code(); + -> for expr list + +for expr list + -> expression:x =x << VirtualMachine::POP; + -> for expr list:list, ',', expression:x =list << x << VirtualMachine::POP; + +while clause + -> "while", '(', condition:x, ')' =x; + + +/* + Any statement with an if in it is a conditional statement +*/ + +conditional statement + -> while clause:x, conditional statement:s =vm->codeWhile(x,s); + -> "for", '(', for exprs:init, ';', condition:cond, ';', for exprs:inc, + ')', conditional statement:s =vm->codeFor(init, cond, inc, s); + -> if clause:x, executable statement:s =x << VirtualMachine::BRF << s.size() << s; + -> if clause:x, unconditional statement:s1, + "else", statement:s2 ={ + s1 << VirtualMachine::BR << s2.size(); + x << VirtualMachine::BRF << s1.size() << s1 << s2; + return x; + } + +if clause + -> "if", '(', condition:x, ')' =x; + +condition + -> expression:x =x.testOK(); + +expression + -> conditional expression + -> lvalue:k, '=', expression:x =k << x << VirtualMachine::ASSIGN; + -> lvalue:k, "+=", expression:x =k << x << VirtualMachine::ADD_EQ; + -> lvalue:k, "-=", expression:x =k << x << VirtualMachine::SUB_EQ; + -> lvalue:k, "*=", expression:x =k << x << VirtualMachine::MULT_EQ; + -> lvalue:k, "/=", expression:x =k << x << VirtualMachine::DIV_EQ; + -> lvalue:k, "%=", expression:x =k << x << VirtualMachine::MOD_EQ; + -> lvalue:k, "|=", expression:x =k << x << VirtualMachine::OR_EQ; + -> lvalue:k, "&=", expression:x =k << x << VirtualMachine::AND_EQ; + -> lvalue:k, "^=", expression:x =k << x << VirtualMachine::XOR_EQ; + -> lvalue:k, "<<=", expression:x =k << x << VirtualMachine::LS_EQ; + -> lvalue:k, ">>=", expression:x =k << x << VirtualMachine::RS_EQ; + +lvalue + -> variable name:k =Code(VirtualMachine::PUSHV).setType(vm->symbolTable[k].type) << k; + -> lvalue:k, '[', expression:x, ']' =k.setType(k.type->element) << x << VirtualMachine::SUBSCRIPT; + +conditional expression + -> logical or expression + -> logical or condition:c, '?', + expression:x, ':', conditional expression:y ={ + //if (!c.type->isTruthDefined()) errorLog.add("True/False not defined"); + x << VirtualMachine::BR << y.size(); + c << VirtualMachine::BRF << x.size() << x << y; + return c; + } + +logical or condition + -> logical or expression:x =x.testOK(); + +logical or expression + -> logical and expression + -> logical or condition:x, "||",logical and expression:y ={ + //if (!x.type->isTruthDefined()) errorLog.add("True/False not defined"); + return x << VirtualMachine::OR << y.size() << y; + } + +logical and expression + -> bitwise or expression + -> logical and condition:x, "&&", bitwise or expression:y ={ + //if (!x.type->isTruthDefined()) errorLog.add("True/False not defined"); + return x << VirtualMachine::AND << y.size() << y; + } + +logical and condition + -> logical and expression:x =x.testOK(); + + + +bitwise or expression + -> bitwise xor expression + -> bitwise or expression:x, '|', + bitwise xor expression:y =x.binop(VirtualMachine::BITOR,y); + +bitwise xor expression + -> bitwise and expression + -> bitwise xor expression:x, '^', + bitwise and expression:y =x.binop(VirtualMachine::XOR,y); + +bitwise and expression + -> equality expression + -> bitwise and expression:x, '&', + equality expression:y =x.binop(VirtualMachine::BITAND,y); + +equality expression + -> relational expression + -> equality expression:x, "==", relational expression:y =x.binop(VirtualMachine::EQ,y); + -> equality expression:x, "!=", relational expression:y =x.binop(VirtualMachine::NE,y); + +relational expression + -> shift expression + -> relational expression:x, '<', shift expression:y =x.binop(VirtualMachine::LT,y); + -> relational expression:x, "<=", shift expression:y =x.binop(VirtualMachine::LE,y); + -> relational expression:x, '>', shift expression:y =x.binop(VirtualMachine::GT,y); + -> relational expression:x, ">=", shift expression:y =x.binop(VirtualMachine::GE,y); + +shift expression + -> additive expression + -> shift expression:x, "<<", additive expression:y =x.binop(VirtualMachine::LS,y); + -> shift expression:x, ">>", additive expression:y =x.binop(VirtualMachine::RS,y); + +additive expression + -> multiplicative expression + -> additive expression:x, '+', + multiplicative expression:y =x.binop(VirtualMachine::ADD,y); + -> additive expression:x, '-', + multiplicative expression:y =x.binop(VirtualMachine::SUB,y); + +multiplicative expression + -> cast expression + -> multiplicative expression:x, '*', cast expression:y =x.binop(VirtualMachine::MULT,y); + -> multiplicative expression:x, '/', cast expression:y =x.binop(VirtualMachine::DIV,y); + -> multiplicative expression:x, '%', cast expression:y =x.binop(VirtualMachine::MOD,y); + +cast expression + -> unary expression + -> '(', type name:t, ')', cast expression:x =x.cast((VirtualMachine::Type::Id) t) << VirtualMachine::CAST << t; + +unary expression + -> power expression + -> "++", unary expression:x =x << VirtualMachine::INCR; + -> "--", unary expression:x =x << VirtualMachine::INCR; + -> '-', unary expression:x =x << VirtualMachine::NEG; + -> '+', unary expression:x =x; + -> '!', unary expression:x =vm->list(stdout), x << VirtualMachine::NOT; + -> '~', unary expression:x =x << VirtualMachine::COMPL; + + + +power expression + -> primary + -> primary:x, "**", unary expression:y =x.binop(VirtualMachine::POW,y); + +primary + -> real:x =vm->doubleList.push(x), Code(VirtualMachine::PUSHD).setType(&DoubleType::doubleType) << (int)(vm->doubleList.size() - 1); + -> integer constant:x =Code(VirtualMachine::PUSHI).setType(&IntegerType::intType) << x; + -> string literal:k =Code(VirtualMachine::PUSHS).setType(&StringType::stringType) << k; + -> lvalue:k =k; + -> lvalue:k, "++" =k << VirtualMachine::PUSH << VirtualMachine::INCR << VirtualMachine::POP; + -> lvalue:k, "--" =k << VirtualMachine::PUSH << VirtualMachine::DECR << VirtualMachine::POP; + -> name string:n, '(', expression list:args, ')' =vm->invokeFunction(n, args); + -> lvalue:k, '.', name string:n, '(', expression list: args, ')' =vm->invokeMethod(k, n, args); + -> '(', expression:x, ')' =x; + +// -- LEXICAL UNITS ------------------------------------------------ +digit = '0-9' +eof = 0 +letter = 'a-z' + 'A-Z' + '_' +space = ' ' + '\t' + '\f' + '\v' + '\r' + '\n' + + +(void) white space + -> space + -> "/*", ~eof?..., "*/" // C style comment + -> "//", ~(eof+'\n')?..., '\n' // C++ style comment + +(double) real + -> simple real + -> simple real:x, 'e'+'E', '+'?,exponent:e =x*pow(10,e); + -> simple real:x, 'e'+'E', '-',exponent:e =x*pow(10,-e); + +(double) simple real + -> integer:i, '.', fraction part:f = i+f; + -> integer:i, '.' =i; + -> '.', fraction part:f = f; + +(int) integer constant + -> integer + -> character constant + +(int) integer + -> digit:d = d-'0'; + -> integer:x, digit:d = 10*x + d-'0'; + +(double) fraction part + -> digit:d =(d-'0')/10.; + -> digit:d, fraction part:f =(d-'0' + f)/10.; + +(int) exponent + -> digit:d = d-'0'; + -> exponent:x, digit:d = 10*x + d-'0'; + +(int) type name, variable name + -> name string:k ={ + char *name = popString(k); + VirtualMachine::Type::Id id = VirtualMachine::Type::idType(name); + if (id != VirtualMachine::Type::UNDEFINED) return (int) id; + CHANGE_REDUCTION(variable_name); + return vm->locateVariable(name); + } + +(int) name string + -> letter: c =pushChar(c), 1; + -> name string:k, letter+digit: c =pushChar(c), k+1; + +not double quote = ~eof - ('"' + '\\' + '\n') +not single quote = ~eof - ('\'' + '\\' + '\n') + +(int) character constant + -> '\'', char constant element:c, '\'' =c; + +(int) char constant element + -> not single quote + -> escape sequence + +(int) string literal + -> string chars:k, '"' =vm->stringList.push(CharString(popString(k))), vm->stringList.size() - 1; + +(int) string chars + -> '"' =0; + -> string chars:k, string char:c =pushChar(c), k+1; + +(int) string char + -> not double quote + -> escape sequence + +(int) escape sequence + -> "\\a" ='\a'; + -> "\\b" ='\b'; + -> "\\f" ='\f'; + -> "\\n" ='\n'; + -> "\\r" ='\r'; + -> "\\t" ='\t'; + -> "\\v" ='\v'; + -> "\\\\" ='\\'; + -> "\\?" = '\?'; + -> "\\'" ='\''; + -> "\\\"" ='"'; + -> octal escape + -> hex escape + +(int) octal escape + -> one octal | two octal | three octal + +(int) one octal + -> '\\', '0-7':d =d-'0'; + +(int) two octal + -> one octal:n, '0-7':d =8*n + d-'0'; + +(int) three octal + -> two octal:n, '0-7':d =8*n + d-'0'; + +(int) hex escape + -> "\\x", hex digit:d =d; + -> hex escape:n, hex digit:d =16*n + d; + +(int) hex digit + -> '0-9' + -> 'a-f' + 'A-F':d =(d&7) + 9; + +[ + sticky {one octal, two octal, hex escape} +] + + + +{ // begin embedded C + +#include <string.h> + + +ErrorRecord::ErrorRecord(char *msg) : message(msg), line(PCB.line), column(PCB.column) +{/* Initializers do it all */} + +ErrorLog errorLog; + +#define SYNTAX_ERROR errorLog.add(PCB.error_message) + +int VirtualMachine::compile(char *text) { + vm = this; + resetCharStack(); + vmCompile_pcb.pointer = (unsigned char *) text; + vmCompile(); + { + Code program = vmCompile_value() << EXIT; + int n = program.size(); + codeStore = new int[n]; + while (n--) codeStore[n] = program[n]; + } + + return vmCompile_pcb.exit_flag != AG_SUCCESS_CODE; +} + +Code VirtualMachine::codeWhile(Code x, Code s) { + Code branch(VirtualMachine::BR); + branch << 0; + //if (!x.type->isTruthDefined()) errorLog.add("True/False not defined"); + x << VirtualMachine::BRF << (s.size() + branch.size()); + int blockLength = s.size() + x.size() + branch.size(); + x << s << VirtualMachine::BR << -blockLength; + return x; +} + +Code VirtualMachine::codeDoWhile(Code s, Code x) { + Code branch(VirtualMachine::BR); + branch << 0; + int blockLength = s.size() + x.size() + branch.size(); + //if (!x.type->isTruthDefined()) errorLog.add("True/False not defined"); + s << x << VirtualMachine::BRT << -blockLength; + return s; +} + +Code VirtualMachine::codeFor(Code init, Code cond, Code inc, Code s) { + s << inc; // append increment code to end of body of for loop + //if (!cond.type->isTruthDefined()) errorLog.add("True/False not defined"); + init << codeWhile(cond, s); + return init; +} + +} // end of embedded C +/********************* End of VM.SYN ************************/