Mercurial > ~dholland > hg > ag > index.cgi
view tests/agcl/oldagsrc/xvmc.syn @ 6:607e3be6bad8
Adjust to the moving target called the C++ standard.
Apparently nowadays it's not allowed to define an explicit copy
constructor but not an assignment operator. Consequently, defining the
explicit copy constructor in terms of the implicit/automatic
assignment operator for general convenience no longer works.
Add assignment operators.
Caution: not tested with the IBM compiler, but there's no particular
reason it shouldn't work.
author | David A. Holland |
---|---|
date | Mon, 30 May 2022 23:46:22 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
{ /* 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 ************************/