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 ************************/