macross/macross_6502.y

1258 lines
22 KiB
Plaintext
Raw Normal View History

2016-01-14 15:23:33 +00:00
/*
* Copyright (c) 1987 Fujitsu
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
macross.y -- Grammar and semantic rules for Macross parser
Chip Morningstar -- Lucasfilm Ltd.
1-November-1984
*/
%{
#include "macrossTypes.h"
#include "macrossGlobals.h"
#include "buildStuff.h"
#include "errorStuff.h"
#include "lexer.h"
#include "lookups.h"
#include "operandStuff.h"
#include "parserMisc.h"
#include "semanticMisc.h"
#include "statementSemantics.h"
%}
/* Token list is target system dependent */
%token A ALIGN ASSERT BLOCK BYTE CONSTRAIN DBYTE DEFINE DO ELSE ELSEIF
%token ENDFILE EOL EXTERN FRETURN FUNCTION HERE IF INCLUDE LONG MACRO MCASE
%token MDEFAULT MDEFINE MDO MELSE MELSEIF MFOR MIF MSWITCH MUNTIL MVARIABLE
%token MWHILE ORG REL START STRING STRUCT TARGET UNDEFINE UNTIL VARIABLE
%token WHILE WORD X Y
%token ConditionCode Identifier MacroName Number Opcode TextString
/* funny characters used literally:
: , @ ( ) { } [ ]
*/
%right ASSIGN /* = += *= -= /= %= <<= >>= &= |=
^= */
%left LOGICAL_OR /* || */
%left LOGICAL_XOR /* ^^ */
%left LOGICAL_AND /* && */
%left BITWISE_OR /* | */
%left BITWISE_XOR /* ^ */
%left BITWISE_AND /* & */
%nonassoc EQUAL_TO NOT_EQUAL_TO /* == != */
%nonassoc LESS_THAN LESS_THAN_OR_EQUAL_TO GREATER_THAN GREATER_THAN_OR_EQUAL_TO
/* < <= > >= */
%nonassoc '['
%left LEFT_SHIFT RIGHT_SHIFT /* << >> */
%left ADD SUB /* + - */
%left MUL DIV MOD /* * / % */
%right UNARY_MINUS LOGICAL_NOT BITWISE_NOT HI_BYTE LO_BYTE
/* - ! ~ ? / */
%left SELECT /* . */
%token INCREMENT DECREMENT /* ++ -- */
%%
/*
In what follows, the comment "da" indicates that we are taking the default
action:
$$ = $1;
If this comment is not present, then then we intend there to be no action
even though yacc will give us the default. (The author's stylistic
tendencies being what they are, the default would have been entered
wherever it was intended, but this was found to clutter up the listing
excessively.
*/
program: beginProgram statementList EOL ENDFILE
{
$$ = $2;
}
| ENDFILE
{
$$ = 0;
}
;
beginProgram: /* null string */
{
statementListNestingDepth = 0;
errorFlag = FALSE;
}
;
/* "_" represents an optional newline (i.e., a whitespace newline as opposed
to an end-of-statement newline */
_: eolList
| /* null string */
;
eolList: EOL
{
if (amListing())
saveEOLForListing();
}
| eolList EOL
{
if (amListing())
saveEOLForListing();
}
;
statementList: statement
{
if (statementListNestingDepth == 0) {
eatStatement($1);
$$ = NULL;
} else {
$$ = buildStatementList($1, NULL);
}
}
| statementList EOL statement
{
if (statementListNestingDepth == 0) {
eatStatement($3);
$$ = NULL;
} else {
$$ = buildStatementList($3, $1);
}
}
;
statement: labeledStatement /* da */
| unlabeledStatement /* da */
| error ENDFILE
{
$$ = NULL;
YYACCEPT;
}
| error
{
yyerrok;
yyclearin;
resynchronizeInput();
$$ = NULL;
}
;
labeledStatement:
labelList labelableStatement
{
$$ = addLabelToStatement($1, $2);
}
;
unlabeledStatement:
labelableStatement /* da */
;
labelList: label
{
$$ = buildLabelList($1, NULL);
}
| labelList label
{
$$ = buildLabelList($2, $1);
}
;
label: Identifier ':'
{
$$ = lookupOrEnterSymbol($1, LABEL_SYMBOL);
}
| Identifier ':' ':'
{
$$ = lookupOrEnterSymbol($1, LABEL_SYMBOL);
addAttributeToSymbol($$, TENTATIVE_GLOBAL_ATT);
}
;
labelableStatement:
ifStatement /* da */
| whileStatement /* da */
| doStatement /* da */
| wordStatement /* da */
| dbyteStatement /* da */
| byteStatement /* da */
| blockStatement /* da */
| stringStatement /* da */
| nullStatement /* da */
| structStatement /* da */
| performStatement /* da */
| instructionStatement /* da */
| groupStatement /* da */
| defineStatement /* da */
| macroDefineStatement /* da */
| variableStatement /* da */
| macroVariableStatement /* da */
| macroStatement /* da */
| functionStatement /* da */
| functionReturnStatement /* da */
| undefineStatement /* da */
| macroIfStatement /* da */
| macroWhileStatement /* da */
| macroDoStatement /* da */
| macroForStatement /* da */
| macroSwitchStatement /* da */
| includeStatement /* da */
| externStatement /* da */
| startStatement /* da */
| alignStatement /* da */
| orgStatement /* da */
| relStatement /* da */
| constrainStatement /* da */
| assertStatement /* da */
| longStatement /* da */
| targetStatement /* da */
;
ifStatement: IF _ ifHead
{
ifContinuationType noCont;
noCont.blockUnion=NULL;
$$ = buildIfStatement($3, noCont, NO_CONTINUATION);
}
| IF _ ifHead elsePart
{
ifContinuationType cont;
cont.blockUnion=$4;
$$ = buildIfStatement($3, cont, ELSE_CONTINUATION);
}
| IF _ ifHead elseIf
{
ifContinuationType cont;
cont.blockUnion=$4;
$$ = buildIfStatement($3, cont, ELSEIF_CONTINUATION);
}
;
ifHead: condition _ block
{
$$ = buildIfHead($1, $3);
}
;
condition: '(' _ conditionExpression _ ')'
{
$$ = $3;
}
;
conditionExpression:
ConditionCode /* da */
| LOGICAL_NOT conditionExpression
{
$$ = invertConditionCode($2);
}
| '(' _ conditionExpression _ ')'
{
$$ = $3;
}
;
elsePart: ELSE _ block
{
$$ = $3;
}
;
elseIf: ELSE _ ifStatement
{
$$ = extractIfBody($3);
}
| ELSEIF _ ifHead
{
ifContinuationType noCont;
noCont.blockUnion = NULL;
$$ = extractIfBody(buildIfStatement($3, noCont, NO_CONTINUATION));
}
| ELSEIF _ ifHead elsePart
{
ifContinuationType cont;
cont.blockUnion = $4;
$$ = extractIfBody(buildIfStatement($3, cont, ELSE_CONTINUATION));
}
| ELSEIF _ ifHead elseIf
{
ifContinuationType cont;
cont.blockUnion = $4;
$$ = extractIfBody(buildIfStatement($3, cont, ELSEIF_CONTINUATION));
}
;
whileStatement: WHILE _ condition _ block
{
$$ = buildWhileStatement($3, $5);
}
;
doStatement: DO _ block _ doEnd
{
$$ = buildDoStatement($3, $5);
}
;
doEnd: WHILE _ condition
{
$$ = buildDoEnd($3, WHILE_END);
}
| UNTIL _ condition
{
$$ = buildDoEnd($3, UNTIL_END);
}
;
wordStatement: WORD _ expressionList
{
$$ = buildWordStatement($3);
}
;
longStatement: LONG _ expressionList
{
$$ = buildLongStatement($3);
}
;
expressionList: expression
{
$$ = buildExpressionList($1, NULL);
}
| expressionList ',' _ expression
{
$$ = buildExpressionList($4, $1);
}
;
constrainStatement:
CONSTRAIN _ '(' _ expression _ ')' _ block
{
$$ = buildConstrainStatement($5, $9);
}
;
assertStatement:
ASSERT _ '(' _ expression _ ')' expression
{
$$ = buildAssertStatement($5, $8);
}
| ASSERT _ '(' _ expression _ ')'
{
$$ = buildAssertStatement($5, NULL);
}
;
dbyteStatement: DBYTE _ expressionList
{
$$ = buildDbyteStatement($3);
}
;
byteStatement: BYTE _ expressionList
{
$$ = buildByteStatement($3);
}
;
blockStatement: BLOCK _ expressionList
{
$$ = buildBlockStatement($3);
}
;
stringStatement:
STRING _ expressionList
{
$$ = buildStringStatement($3);
}
;
structStatement:
STRUCT _ structName
{
$$ = buildStructStatement($3, NULL);
}
| STRUCT _ structBody _ structName
{
$$ = buildStructStatement($5, $3);
}
;
structName: Identifier
{
$$ = lookupOrEnterSymbol($1, STRUCT_NAME_SYMBOL);
}
;
structBody: '{' structBodyStatementList '}'
{
$$ = $2;
}
;
structBodyStatementList:
structBodyStatement
{
$$ = buildStatementList($1, NULL);
}
| structBodyStatementList EOL structBodyStatement
{
$$ = buildStatementList($3, $1);
}
;
structBodyStatement:
basicStructBodyStatement /* da */
| labelList basicStructBodyStatement
{
$$ = addLabelToStatement($1, $2);
}
;
basicStructBodyStatement:
wordStatement /* da */
| dbyteStatement /* da */
| byteStatement /* da */
| blockStatement /* da */
| stringStatement /* da */
| alignStatement /* da */
| nullStatement /* da */
| structStatement /* da */
| longStatement /* da */
;
nullStatement: /* null string */
{
$$ = buildNullStatement();
}
;
instructionStatement:
Opcode
{
$$ = buildInstructionStatement($1, NULL);
}
| Opcode operandList
{
$$ = buildInstructionStatement($1, $2);
}
| MacroName
{
$$ = buildMacroInstructionStatement($1, NULL);
}
| MacroName operandList
{
$$ = buildMacroInstructionStatement($1, $2);
}
;
groupStatement: block
{
$$ = buildGroupStatement($1);
}
defineStatement:
DEFINE _ defineTail
{
$$ = $3;
}
;
defineTail:
Identifier
{
$$ = buildDefineStatement($1, UNASSIGNED);
}
| Identifier ASSIGN /* must be '=' */ _ expression
{
checkDefineAssignmentOperator($2);
$$ = buildDefineStatement($1, $4);
}
;
mdefineTail:
Identifier
{
$$ = buildMdefineStatement($1, UNASSIGNED);
}
| Identifier ASSIGN /* must be '=' */ _ expression
{
checkDefineAssignmentOperator($2);
$$ = buildMdefineStatement($1, $4);
}
;
macroStatement:
MACRO enter _ Identifier macroArguments _ block
{
$$ = buildMacroStatement(createMacro($4), $5, $7);
popMacroOrFunctionNestingDepth();
}
| MACRO enter _ Identifier _ block
{
$$ = buildMacroStatement(createMacro($4), NULL, $6);
popMacroOrFunctionNestingDepth();
}
| MACRO enter _ MacroName macroArguments _ block
{
$$ = buildMacroStatement($4, $5, $7);
popMacroOrFunctionNestingDepth();
}
| MACRO enter _ MacroName _ block
{
$$ = buildMacroStatement($4, NULL, $6);
popMacroOrFunctionNestingDepth();
}
;
enter: /* null string */
{
pushMacroOrFunctionNestingDepth();
}
macroArguments: argumentList; /* da */
functionStatement:
FUNCTION enter _ Identifier _ functionArguments _ block
{
$$ = buildFunctionStatement($4, $6, $8);
popMacroOrFunctionNestingDepth();
}
;
undefineStatement:
UNDEFINE _ identifierList
{
$$ = buildUndefineStatement($3);
}
;
identifierList: Identifier
{
$$ = buildIdentifierList($1, NULL, unknownSymbolTag);
}
| identifierList ',' _ Identifier
{
$$ = buildIdentifierList($4, $1, unknownSymbolTag);
}
;
functionArguments: '(' ')'
{
$$ = NULL;
}
| '(' argumentList ')'
{
$$ = $2;
}
;
argumentList: basicArgumentList
{
$$ = $1;
}
| basicArgumentList ',' _ variableArg
{
$$ = buildArgumentList($4, $1, TRUE);
}
| variableArg
{
$$ = buildArgumentList($1, NULL, TRUE);
}
;
basicArgumentList:
argument
{
$$ = buildArgumentList($1, NULL, FALSE);
}
| basicArgumentList ',' _ argument
{
$$ = buildArgumentList($4, $1, FALSE);
}
;
variableArg: Identifier '[' _ ']' /* da */
;
argument: Identifier /* da */
;
variableStatement:
VARIABLE _ variableTail
{
$$ = $3;
}
;
variableTail:
Identifier
{
$$ = buildVariableStatement($1, UNASSIGNED, NULL);
}
| Identifier ASSIGN /* must be '=' */ _ expressionList
{
checkDefineAssignmentOperator($2);
$$ = buildVariableStatement($1, $4, NULL);
}
| Identifier '[' _ expression _ ']'
{
$$ = buildVariableStatement($1, UNASSIGNED, $4);
}
| Identifier '[' _ expression _ ']' ASSIGN _ expressionList
{
checkDefineAssignmentOperator($2);
$$ = buildVariableStatement($1, $9, $4);
}
| Identifier '[' ']' ASSIGN _ expressionList
{
checkDefineAssignmentOperator($2);
$$ = buildVariableStatement($1, $6, -1);
}
;
macroVariableStatement:
MVARIABLE _ mvariableTail
{
$$ = $3;
}
;
mvariableTail:
Identifier
{
$$ = buildMvariableStatement($1, UNASSIGNED, NULL);
}
| Identifier ASSIGN /* must be '=' */ _ expressionList
{
checkDefineAssignmentOperator($2);
$$ = buildMvariableStatement($1, $4, NULL);
}
| Identifier '[' _ expression _ ']'
{
$$ = buildMvariableStatement($1, UNASSIGNED, $4);
}
| Identifier '[' _ expression _ ']' ASSIGN _ expressionList
{
checkDefineAssignmentOperator($2);
$$ = buildMvariableStatement($1, $9, $4);
}
| Identifier '[' ']' ASSIGN _ expressionList
{
checkDefineAssignmentOperator($2);
$$ = buildMvariableStatement($1, $6, -1);
}
;
macroDefineStatement:
MDEFINE _ mdefineTail
{
$$ = $3;
}
;
macroIfStatement:
MIF _ mIfHead
{
mifContinuationType noCont;
noCont.mifBlockUnion = NULL;
$$ = buildMifStatement($3, noCont, NO_CONTINUATION);
}
| MIF _ mIfHead mElsePart
{
mifContinuationType cont;
cont.mifBlockUnion = $4;
$$ = buildMifStatement($3, cont, ELSE_CONTINUATION);
}
| MIF _ mIfHead mElseIf
{
mifContinuationType cont;
cont.mifBlockUnion = $4;
$$ = buildMifStatement($3, cont, ELSEIF_CONTINUATION);
}
;
mIfHead: macroCondition _ block
{
$$ = buildMifHead($1, $3);
}
;
macroCondition: '(' _ expression _ ')'
{
$$ = $3;
}
;
mElsePart: MELSE _ block
{
$$ = $3;
}
;
mElseIf: MELSE _ macroIfStatement
{
$$ = extractMifBody($3);
}
| MELSEIF _ mIfHead
{
mifContinuationType noCont;
noCont.mifBlockUnion = NULL;
$$ = extractMifBody(buildMifStatement($3, noCont, NO_CONTINUATION));
}
| MELSEIF _ mIfHead mElsePart
{
mifContinuationType cont;
cont.mifBlockUnion = $4;
$$ = extractMifBody(buildMifStatement($3, cont, ELSE_CONTINUATION));
}
| MELSEIF _ mIfHead mElseIf
{
mifContinuationType cont;
cont.mifBlockUnion = $4;
$$ = extractMifBody(buildMifStatement($3, cont, ELSEIF_CONTINUATION));
}
;
macroSwitchStatement:
MSWITCH _ switch _ cases
{
$$ = buildMswitchStatement($3, $5);
}
;
switch: '(' _ expression _ ')'
{
$$ = $3;
}
;
cases: '{' _ caseList _ '}'
{
$$ = $3;
}
|
'{' _ '}'
{
$$ = NULL;
}
;
caseList: case
{
$$ = buildCaseList($1, NULL);
}
| caseList _ case
{
$$ = buildCaseList($3, $1);
}
;
case: caseTag _ block
{
$$ = buildCase($1, $3);
}
;
caseTag: MCASE _ '(' _ expressionList _ ')'
{
$$ = $5;
}
| MDEFAULT
{
$$ = NULL;
}
;
macroWhileStatement:
MWHILE _ macroCondition _ block
{
$$ = buildMwhileStatement($3, $5);
}
;
macroDoStatement:
MDO _ block _ macroDoEnd
{
$$ = buildMdoStatement($3, $5);
}
;
macroDoEnd: WHILE _ macroCondition
{
$$ = buildMdoEnd($3, WHILE_END);
}
| MWHILE _ macroCondition
{
$$ = buildMdoEnd($3, WHILE_END);
}
| UNTIL _ macroCondition
{
$$ = buildMdoEnd($3, UNTIL_END);
}
| MUNTIL _ macroCondition
{
$$ = buildMdoEnd($3, UNTIL_END);
}
;
functionReturnStatement:
FRETURN
{
$$ = buildFreturnStatement(NULL);
}
| FRETURN thingToReturn
{
$$ = buildFreturnStatement($2);
}
;
thingToReturn: expression /* da */
;
macroForStatement:
MFOR _ '(' _ forExpressions _ ')' _ block
{
$$ = buildMforStatement($5, $9);
}
;
forExpressions:
expression ',' _ expression ',' _ expression
{
$$ = buildForExpressions($1, $4, $7);
}
;
includeStatement:
INCLUDE _ expression
{
$$ = buildIncludeStatement($3);
}
;
externStatement:
EXTERN _ identifierList
{
$$ = buildExternStatement($3);
}
;
startStatement: START _ expression
{
$$ = buildStartStatement($3);
}
;
alignStatement: ALIGN _ expression
{
$$ = buildAlignStatement($3);
}
;
orgStatement: ORG _ expression
{
$$ = buildOrgStatement($3);
}
;
targetStatement:
TARGET _ expression
{
$$ = buildTargetStatement($3);
}
;
relStatement: REL
{
$$ = buildRelStatement();
}
;
performStatement:
expression
{
$$ = buildPerformStatement($1);
}
;
operandList: blockEndingOperandList /* da */
| nonBlockEndingOperandList /* da */
;
blockEndingOperandList:
blockOperand
{
$$ = buildOperandList($1, NULL);
}
| blockEndingOperandList blockOperand
{
$$ = buildOperandList($2, $1);
}
| blockEndingOperandList ',' _ blockOperand
{
$$ = buildOperandList($4, $1);
}
| nonBlockEndingOperandList blockOperand
{
$$ = buildOperandList($2, $1);
}
| nonBlockEndingOperandList ',' _ blockOperand
{
$$ = buildOperandList($4, $1);
}
;
nonBlockEndingOperandList:
nonBlockOperand
{
$$ = buildOperandList($1, NULL);
}
| nonBlockEndingOperandList ',' _ nonBlockOperand
{
$$ = buildOperandList($4, $1);
}
| blockEndingOperandList nonBlockOperand
{
$$ = buildOperandList($2, $1);
}
| blockEndingOperandList ',' _ nonBlockOperand
{
$$ = buildOperandList($4, $1);
}
;
blockOperand: block
{
$$ = buildOperand(BLOCK_OPND, $1);
}
;
block: '{' nestDeeper statementList '}'
{
$$ = $3;
statementListNestingDepth--;
}
;
nestDeeper: /* null string */
{
statementListNestingDepth++;
}
selectionList: SELECT _ Identifier
{
$$ = buildSelectionList($3, NULL);
}
| selectionList SELECT _ Identifier
{
$$ = buildSelectionList($4, $1);
}
;
array: variable '[' _ expression _ ']'
{
$$ = buildExpressionTerm(ARRAY_EXPR, $1, $4, NULL);
}
| array '[' _ expression _ ']'
{
$$ = buildExpressionTerm(ARRAY_EXPR, $1, $4, NULL);
}
;
variable: Identifier
{
$$ = buildExpressionTerm(IDENTIFIER_EXPR, lookupOrEnterSymbol($1,
unknownSymbolTag), NULL, NULL);
}
;
lvalue: array /* da */
| variable /* da */
;
expression: lvalue
{
$$ = $1;
}
| functionCall
{
$$ = buildExpressionTerm(FUNCTION_CALL_EXPR, $1, NULL, NULL);
}
| Number
{
$$ = buildExpressionTerm(NUMBER_EXPR, $1, NULL, NULL);
}
| ConditionCode
{
$$ = buildExpressionTerm(CONDITION_CODE_EXPR, $1, NULL, NULL);
}
| HERE
{
$$ = buildExpressionTerm(HERE_EXPR, NULL, NULL, NULL);
}
| TextString
{
$$ = buildExpressionTerm(STRING_EXPR, $1, NULL, NULL);
}
| '(' _ expression _ ')'
{
$$ = buildExpressionTerm(SUBEXPRESSION_EXPR, $3, NULL, NULL);
}
| SUB _ expression %prec UNARY_MINUS
{
$$ = buildExpressionTerm(UNOP_EXPR, UNARY_MINUS, $3, NULL);
}
| LOGICAL_NOT _ expression
{
$$ = buildExpressionTerm(UNOP_EXPR, LOGICAL_NOT, $3, NULL);
}
| BITWISE_NOT _ expression
{
$$ = buildExpressionTerm(UNOP_EXPR, BITWISE_NOT, $3, NULL);
}
| DIV _ expression %prec LO_BYTE
{
$$ = buildExpressionTerm(UNOP_EXPR, LO_BYTE, $3, NULL);
}
| HI_BYTE _ expression
{
$$ = buildExpressionTerm(UNOP_EXPR, HI_BYTE, $3, NULL);
}
| expression MUL _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, MUL, $1, $4);
}
| expression DIV _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, DIV, $1, $4);
}
| expression MOD _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, MOD, $1, $4);
}
| expression SUB _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, SUB, $1, $4);
}
| expression ADD _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, ADD, $1, $4);
}
| expression LEFT_SHIFT _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, LEFT_SHIFT, $1, $4);
}
| expression RIGHT_SHIFT _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, RIGHT_SHIFT, $1, $4);
}
| expression LESS_THAN _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, LESS_THAN, $1, $4);
}
| expression GREATER_THAN _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, GREATER_THAN, $1, $4);
}
| expression LESS_THAN_OR_EQUAL_TO _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, LESS_THAN_OR_EQUAL_TO, $1, $4);
}
| expression GREATER_THAN_OR_EQUAL_TO _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, GREATER_THAN_OR_EQUAL_TO, $1, $4);
}
| expression EQUAL_TO _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, EQUAL_TO, $1, $4);
}
| expression NOT_EQUAL_TO _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, NOT_EQUAL_TO, $1, $4);
}
| expression BITWISE_AND _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, BITWISE_AND, $1, $4);
}
| expression BITWISE_OR _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, BITWISE_OR, $1, $4);
}
| expression BITWISE_XOR _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, BITWISE_XOR, $1, $4);
}
| expression LOGICAL_AND _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, LOGICAL_AND, $1, $4);
}
| expression LOGICAL_OR _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, LOGICAL_OR, $1, $4);
}
| expression LOGICAL_XOR _ expression
{
$$ = buildExpressionTerm(BINOP_EXPR, LOGICAL_XOR, $1, $4);
}
| expression SELECT _ Identifier
{
$$ = buildExpressionTerm(BINOP_EXPR, SELECT, $1,
lookupOrEnterSymbol($4, STRUCT_FIELD_SYMBOL));
}
| lvalue ASSIGN _ expression
{
$$ = buildExpressionTerm(ASSIGN_EXPR, $2, $1, $4);
}
| lvalue INCREMENT
{
$$ = buildExpressionTerm(POSTOP_EXPR, INCREMENT, $1, NULL);
}
| lvalue DECREMENT
{
$$ = buildExpressionTerm(POSTOP_EXPR, DECREMENT, $1, NULL);
}
| INCREMENT _ lvalue
{
$$ = buildExpressionTerm(PREOP_EXPR, INCREMENT, $3, NULL);
}
| DECREMENT _ lvalue
{
$$ = buildExpressionTerm(PREOP_EXPR, DECREMENT, $3, NULL);
}
;
functionCall:
functionName '(' _ ')'
{
$$ = buildFunctionCall($1, NULL);
}
| functionName '(' _ functionArgumentList _ ')'
{
$$ = buildFunctionCall($1, $4);
}
;
functionName: Identifier /* da */
;
functionArgumentList:
operandList /* da */
;
/* Stuff above this point is target independent (except for token list), stuff
below this points is target dependent (operand syntax) */
nonBlockOperand:
directExpression /* da */
| indirectExpression /* da */
| immediateExpression /* da */
| registerExpression /* da */
| indexedExpression /* da */
| preIndexedXExpression /* da */
| postIndexedYExpression /* da */
;
directExpression: expression
{
$$ = buildOperand(EXPRESSION_OPND, $1);
}
;
indirectExpression: '@' _ expression
{
$$ = buildOperand(INDIRECT_OPND, $3);
}
;
immediateExpression: '#' _ expression
{
$$ = buildOperand(IMMEDIATE_OPND, $3);
}
;
registerExpression:
A
{
$$ = buildOperand(A_REGISTER_OPND, NULL);
}
| X
{
$$ = buildOperand(X_REGISTER_OPND, NULL);
}
| Y
{
$$ = buildOperand(Y_REGISTER_OPND, NULL);
}
;
indexedExpression:
X '[' _ expression _ ']'
{
$$ = buildOperand(X_INDEXED_OPND, $4);
}
| Y '[' _ expression _ ']'
{
$$ = buildOperand(Y_INDEXED_OPND, $4);
}
| X selectionList
{
$$ = buildOperand(X_SELECTED_OPND, $2);
}
| Y selectionList
{
$$ = buildOperand(Y_SELECTED_OPND, $2);
}
| '@' _ X
{
$$ = buildOperand(X_INDEXED_OPND, NULL);
}
| '@' _ Y
{
$$ = buildOperand(Y_INDEXED_OPND, NULL);
}
;
preIndexedXExpression:
'@' _ X '[' _ expression _ ']'
{
$$ = buildOperand(PRE_INDEXED_X_OPND, $6);
}
| '@' _ X selectionList
{
$$ = buildOperand(PRE_SELECTED_X_OPND, $4);
}
;
postIndexedYExpression:
Y '[' _ '@' _ expression _ ']'
{
$$ = buildOperand(POST_INDEXED_Y_OPND, $6);
}
;