2005-07-01 04:29:18 +00:00
|
|
|
%{
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2014-12-13 21:00:33 +00:00
|
|
|
Expression* lastExp = nullptr;
|
2005-07-18 02:03:41 +00:00
|
|
|
|
2005-07-01 04:29:18 +00:00
|
|
|
#define YYERROR_VERBOSE 1
|
|
|
|
|
2005-09-20 15:17:16 +00:00
|
|
|
/* dump Expression stack during parsing? */
|
2010-04-03 17:11:23 +00:00
|
|
|
#define DEBUG_EXP 0
|
2005-09-20 15:17:16 +00:00
|
|
|
|
2005-07-01 04:29:18 +00:00
|
|
|
int yylex();
|
|
|
|
char *yytext;
|
|
|
|
|
2007-10-08 01:59:20 +00:00
|
|
|
void yyerror(const char *e) {
|
2005-09-20 15:17:16 +00:00
|
|
|
//if(DEBUG_EXP) fprintf(stderr, "%s at token \"%s\"\n", e, yytext);
|
|
|
|
if(DEBUG_EXP) fprintf(stderr, "%s\n", e);
|
OK, we no longer segfault on parse error.
However, we do leak memory: yyparse() happily allocates Expressions as
it parses, but when it hits a parse error, it doesn't return a valid
pointer to the top of the Expression tree. From what I can tell, the
so-called Expression* result is the int value of the last lexer token
cast to an Expression* (due to yacc's use of a union).
I know how to avoid the leak: we need to keep a vector of Expression
pointers in YaccParser. If there's a parse error, yyerror() can delete
all the Expressions using the vector. If not, we clear the vector (er,
calling .clear() on a vector doesn't delete all its elements, too,
does it?). Every time yacc says "$$ = new WhateverExpression", it also
should vector.push_back($$).
Will implement this tomorrow; am getting tired & flaky.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@655 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-07-15 03:47:26 +00:00
|
|
|
errMsg = e;
|
2005-07-23 21:16:57 +00:00
|
|
|
|
|
|
|
// be extra paranoid about deletion
|
2015-09-14 21:33:50 +00:00
|
|
|
if(lastExp && reinterpret_cast<Expression*>(lastExp))
|
2005-07-18 02:03:41 +00:00
|
|
|
delete lastExp;
|
2005-07-23 21:16:57 +00:00
|
|
|
|
2014-12-13 21:00:33 +00:00
|
|
|
lastExp = nullptr;
|
2005-07-01 04:29:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
%}
|
|
|
|
|
2005-07-13 02:54:13 +00:00
|
|
|
%union {
|
|
|
|
int val;
|
2014-11-17 01:36:44 +00:00
|
|
|
char* Equate;
|
|
|
|
CartMethod cartMethod;
|
|
|
|
CpuMethod cpuMethod;
|
|
|
|
TiaMethod tiaMethod;
|
|
|
|
Expression* exp;
|
|
|
|
char* DefinedFunction;
|
2005-07-13 02:54:13 +00:00
|
|
|
}
|
|
|
|
|
2005-07-14 15:13:58 +00:00
|
|
|
/* Terminals */
|
2005-07-13 02:54:13 +00:00
|
|
|
%token <val> NUMBER
|
2005-07-16 23:46:37 +00:00
|
|
|
%token <val> ERR
|
2014-11-17 01:36:44 +00:00
|
|
|
%token <Equate> EQUATE
|
OK, this is the first pass at a huge reorganization of the debugger
classes. First off, the distella code has been integrated into a
DiStella class. This code isn't yet tied to the debugger, but it does
at least compile and generate valid output.
The RamDebug class has been replaced by a CartDebug class, which
takes responsibility for the previous RamDebug stuff as well as
things related to Cart address space (read from write ports,
disassembly, etc).
Fixed E7 bankswitching when reading from the write port in the upper
256byte area.
Fixed 'read from write port functionality' in general for all carts
that supported it previously. Basically, if _rwport is enabled, the
address is checked to be an actual read (vs. one that's part of a
normal write cycle), *and* it's actually an illegal access (each
cart/bankswitch type now provides a hint to indicate this condition).
Still TODO is clean up the rework, properly integrate DiStella, and
fix labels and defines (which seem to be completely broken).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1922 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2010-01-17 16:48:45 +00:00
|
|
|
%token <cartMethod> CART_METHOD
|
|
|
|
%token <cpuMethod> CPU_METHOD
|
|
|
|
%token <tiaMethod> TIA_METHOD
|
2014-11-17 01:36:44 +00:00
|
|
|
%token <DefinedFunction> FUNCTION
|
2005-07-14 15:13:58 +00:00
|
|
|
|
|
|
|
/* Non-terminals */
|
|
|
|
%type <exp> expression
|
|
|
|
|
|
|
|
/* Operator associativity and precedence */
|
2005-07-01 04:29:18 +00:00
|
|
|
%left '-' '+'
|
|
|
|
%left '*' '/' '%'
|
|
|
|
%left LOG_OR
|
|
|
|
%left LOG_AND
|
2005-07-13 04:49:19 +00:00
|
|
|
%left LOG_NOT
|
2005-07-01 04:29:18 +00:00
|
|
|
%left '|' '^'
|
|
|
|
%left '&'
|
|
|
|
%left SHR SHL
|
2005-07-12 21:50:43 +00:00
|
|
|
%nonassoc '<' '>' GTE LTE NE EQ
|
2005-07-15 01:20:11 +00:00
|
|
|
%nonassoc DEREF
|
2005-07-12 21:50:43 +00:00
|
|
|
%nonassoc UMINUS
|
2005-07-19 01:31:37 +00:00
|
|
|
%nonassoc '['
|
2005-07-01 04:29:18 +00:00
|
|
|
|
2005-07-13 02:54:13 +00:00
|
|
|
|
2005-07-01 04:29:18 +00:00
|
|
|
%%
|
2005-09-20 15:17:16 +00:00
|
|
|
statement: expression { if(DEBUG_EXP) fprintf(stderr, "\ndone\n"); result.exp = $1; }
|
2005-07-01 04:29:18 +00:00
|
|
|
;
|
|
|
|
|
2005-09-20 15:17:16 +00:00
|
|
|
expression: expression '+' expression { if(DEBUG_EXP) fprintf(stderr, " +"); $$ = new PlusExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression '-' expression { if(DEBUG_EXP) fprintf(stderr, " -"); $$ = new MinusExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression '*' expression { if(DEBUG_EXP) fprintf(stderr, " *"); $$ = new MultExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression '/' expression { if(DEBUG_EXP) fprintf(stderr, " /"); $$ = new DivExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression '%' expression { if(DEBUG_EXP) fprintf(stderr, " %%"); $$ = new ModExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression '&' expression { if(DEBUG_EXP) fprintf(stderr, " &"); $$ = new BinAndExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression '|' expression { if(DEBUG_EXP) fprintf(stderr, " |"); $$ = new BinOrExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression '^' expression { if(DEBUG_EXP) fprintf(stderr, " ^"); $$ = new BinXorExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression '<' expression { if(DEBUG_EXP) fprintf(stderr, " <"); $$ = new LessExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression '>' expression { if(DEBUG_EXP) fprintf(stderr, " >"); $$ = new GreaterExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression GTE expression { if(DEBUG_EXP) fprintf(stderr, " >="); $$ = new GreaterEqualsExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression LTE expression { if(DEBUG_EXP) fprintf(stderr, " <="); $$ = new LessEqualsExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression NE expression { if(DEBUG_EXP) fprintf(stderr, " !="); $$ = new NotEqualsExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression EQ expression { if(DEBUG_EXP) fprintf(stderr, " =="); $$ = new EqualsExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression SHR expression { if(DEBUG_EXP) fprintf(stderr, " >>"); $$ = new ShiftRightExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression SHL expression { if(DEBUG_EXP) fprintf(stderr, " <<"); $$ = new ShiftLeftExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression LOG_OR expression { if(DEBUG_EXP) fprintf(stderr, " ||"); $$ = new LogOrExpression($1, $3); lastExp = $$; }
|
|
|
|
| expression LOG_AND expression { if(DEBUG_EXP) fprintf(stderr, " &&"); $$ = new LogAndExpression($1, $3); lastExp = $$; }
|
|
|
|
| '-' expression %prec UMINUS { if(DEBUG_EXP) fprintf(stderr, " U-"); $$ = new UnaryMinusExpression($2); lastExp = $$; }
|
|
|
|
| '~' expression %prec UMINUS { if(DEBUG_EXP) fprintf(stderr, " ~"); $$ = new BinNotExpression($2); lastExp = $$; }
|
|
|
|
| '!' expression %prec UMINUS { if(DEBUG_EXP) fprintf(stderr, " !"); $$ = new LogNotExpression($2); lastExp = $$; }
|
|
|
|
| '*' expression %prec DEREF { if(DEBUG_EXP) fprintf(stderr, " U*"); $$ = new ByteDerefExpression($2); lastExp = $$; }
|
|
|
|
| '@' expression %prec DEREF { if(DEBUG_EXP) fprintf(stderr, " U@"); $$ = new WordDerefExpression($2); lastExp = $$; }
|
|
|
|
| '<' expression { if(DEBUG_EXP) fprintf(stderr, " U<"); $$ = new LoByteExpression($2); lastExp = $$; }
|
|
|
|
| '>' expression { if(DEBUG_EXP) fprintf(stderr, " U>"); $$ = new HiByteExpression($2); lastExp = $$; }
|
|
|
|
| '(' expression ')' { if(DEBUG_EXP) fprintf(stderr, " ()"); $$ = $2; lastExp = $$; }
|
|
|
|
| expression '[' expression ']' { if(DEBUG_EXP) fprintf(stderr, " []"); $$ = new ByteDerefOffsetExpression($1, $3); lastExp = $$; }
|
2017-04-15 21:30:50 +00:00
|
|
|
| NUMBER { if(DEBUG_EXP) fprintf(stderr, "const %d", $1); $$ = new ConstExpression($1); lastExp = $$; }
|
|
|
|
| EQUATE { if(DEBUG_EXP) fprintf(stderr, "equate %s", $1); $$ = new EquateExpression($1); lastExp = $$; }
|
2005-09-20 15:17:16 +00:00
|
|
|
| CPU_METHOD { if(DEBUG_EXP) fprintf(stderr, " (CpuMethod)"); $$ = new CpuMethodExpression($1); lastExp = $$; }
|
OK, this is the first pass at a huge reorganization of the debugger
classes. First off, the distella code has been integrated into a
DiStella class. This code isn't yet tied to the debugger, but it does
at least compile and generate valid output.
The RamDebug class has been replaced by a CartDebug class, which
takes responsibility for the previous RamDebug stuff as well as
things related to Cart address space (read from write ports,
disassembly, etc).
Fixed E7 bankswitching when reading from the write port in the upper
256byte area.
Fixed 'read from write port functionality' in general for all carts
that supported it previously. Basically, if _rwport is enabled, the
address is checked to be an actual read (vs. one that's part of a
normal write cycle), *and* it's actually an illegal access (each
cart/bankswitch type now provides a hint to indicate this condition).
Still TODO is clean up the rework, properly integrate DiStella, and
fix labels and defines (which seem to be completely broken).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1922 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2010-01-17 16:48:45 +00:00
|
|
|
| CART_METHOD { if(DEBUG_EXP) fprintf(stderr, " (CartMethod)"); $$ = new CartMethodExpression($1); lastExp = $$; }
|
2005-09-20 15:17:16 +00:00
|
|
|
| TIA_METHOD { if(DEBUG_EXP) fprintf(stderr, " (TiaMethod)"); $$ = new TiaMethodExpression($1); lastExp = $$; }
|
2014-11-17 01:36:44 +00:00
|
|
|
| FUNCTION { if(DEBUG_EXP) fprintf(stderr, " (DefinedFunction)"); $$ = new FunctionExpression($1); lastExp = $$; }
|
2017-10-11 14:53:54 +00:00
|
|
|
| ERR { if(DEBUG_EXP) fprintf(stderr, " ERR: "); yyerror((const char*)"Invalid label or constant"); return 1; }
|
2005-07-01 04:29:18 +00:00
|
|
|
;
|
|
|
|
%%
|