mpw/bin/parser.lemon

331 lines
6.2 KiB
Plaintext
Raw Normal View History

2013-07-03 21:05:00 +00:00
%extra_argument { Debug::Command *command }
2013-07-03 21:05:00 +00:00
%token_prefix tk
%token_type { Token }
2013-07-03 22:03:46 +00:00
%include {
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
2013-08-16 03:52:03 +00:00
#include <cassert>
2015-02-17 00:23:12 +00:00
#include <cstddef>
#include "debugger.h"
2013-07-03 22:03:46 +00:00
2018-01-01 19:15:17 +00:00
#include <toolbox/mm.h>
using Debug::Token;
2013-07-03 23:55:09 +00:00
#ifdef __cplusplus
extern "C" {
#endif
2013-07-03 22:03:46 +00:00
uint32_t cpuGetSR();
uint32_t cpuGetPC();
uint32_t cpuGetAReg(unsigned);
uint32_t cpuGetDReg(unsigned);
2013-07-03 23:55:09 +00:00
#ifdef __cplusplus
}
#endif
#undef NDEBUG
2013-07-03 22:03:46 +00:00
}
2013-07-03 21:05:00 +00:00
%parse_failure {
2013-07-04 04:29:09 +00:00
//fprintf(stderr,"I don't understand.\n");
2013-07-03 21:05:00 +00:00
command->valid = false;
}
%parse_accept {
command->valid = true;
}
2013-07-03 22:03:46 +00:00
2013-07-03 21:05:00 +00:00
%left PIPEPIPE.
%left AMPAMP.
%left PIPE.
%left CARET.
%left AMP.
%left EQEQ BANGEQ.
%left LT LTEQ GT GTEQ.
%left LTLT GTGT.
%left PLUS MINUS.
%left STAR SLASH PERCENT.
%right BANG TILDE.
2013-07-03 23:55:09 +00:00
stmt ::= expr(a) EOL.
2013-07-03 21:05:00 +00:00
{
Debug::Print(a.intValue);
2013-07-03 23:55:09 +00:00
}
2013-07-03 21:05:00 +00:00
2013-07-04 04:29:09 +00:00
stmt ::= STAR EOL.
{
Debug::PrintRegisters();
2013-07-04 04:29:09 +00:00
}
2013-07-03 23:55:09 +00:00
stmt ::= PRINT expr(a) EOL.
{
Debug::Print(a.intValue);
2013-07-03 22:03:46 +00:00
}
2013-07-03 21:05:00 +00:00
2013-07-08 03:39:53 +00:00
stmt ::= BREAK EOL.
{
Debug::Break();
}
2013-07-03 23:55:09 +00:00
stmt ::= BREAK expr(a) EOL.
2013-07-03 22:03:46 +00:00
{
Debug::Break(a.intValue);
2013-07-03 21:05:00 +00:00
}
stmt ::= BACKTRACE EOL.
{
Debug::PrintBackTrace();
}
2013-07-03 23:55:09 +00:00
stmt ::= CONTINUE EOL.
2013-07-03 21:05:00 +00:00
{
command->action = Debug::cmdContinue;
2013-07-03 22:03:46 +00:00
command->argc = 0;
2013-07-03 21:05:00 +00:00
}
2013-07-08 03:39:53 +00:00
stmt ::= TBREAK EOL.
{
Debug::ToolBreak();
}
2013-07-03 23:55:09 +00:00
stmt ::= TBREAK expr(a) EOL.
2013-07-03 21:05:00 +00:00
{
Debug::ToolBreak(a.intValue);
2013-07-03 21:05:00 +00:00
}
2013-07-13 17:42:19 +00:00
stmt ::= RBREAK EOL .
{
Debug::ReadBreak();
}
stmt ::= RBREAK expr(a) EOL.
{
Debug::ReadBreak(a.intValue);
2013-07-13 17:42:19 +00:00
}
stmt ::= WBREAK EOL.
{
Debug::WriteBreak();
}
stmt ::= WBREAK expr(a) EOL.
{
Debug::WriteBreak(a.intValue);
2013-07-13 17:42:19 +00:00
}
stmt ::= RWBREAK expr(a) EOL .
{
Debug::ReadWriteBreak(a.intValue);
2013-07-13 17:42:19 +00:00
}
2013-07-03 23:55:09 +00:00
stmt ::= NEXT EOL.
2013-07-03 21:05:00 +00:00
{
command->action = Debug::cmdStep;
2013-07-03 22:03:46 +00:00
command->argc = 0;
2013-07-03 21:05:00 +00:00
}
2013-07-03 23:55:09 +00:00
stmt ::= NEXT expr(a) EOL.
2013-07-03 21:05:00 +00:00
{
command->action = Debug::cmdStep;
2013-07-03 22:03:46 +00:00
command->argc = 1;
command->argv[0] = a.intValue;
2013-07-03 21:05:00 +00:00
}
2013-07-03 23:55:09 +00:00
stmt ::= DUMP expr(a) EOL.
2013-07-03 21:05:00 +00:00
{
Debug::Dump(a.intValue);
2013-07-03 21:05:00 +00:00
}
2013-07-05 17:56:24 +00:00
stmt ::= DUMP expr(a) COLON expr(b) EOL.
{
Debug::Dump(a.intValue, b.intValue - a.intValue);
2013-07-05 17:56:24 +00:00
}
stmt ::= DUMP expr(a) AT expr(b) EOL.
{
Debug::Dump(a.intValue, b.intValue);
2013-07-05 17:56:24 +00:00
}
2013-07-03 23:55:09 +00:00
stmt ::= LIST expr(a) EOL.
2013-07-03 21:05:00 +00:00
{
Debug::List(a.intValue);
2013-07-03 21:05:00 +00:00
}
2015-01-06 01:28:56 +00:00
stmt ::= STACKCRAWL EOL.
{
Debug::StackCrawl();
}
2013-07-05 17:56:24 +00:00
stmt ::= expr(a) SEMI SEMIH EOL.
2013-07-03 21:05:00 +00:00
{
Debug::Dump(a.intValue);
2013-07-03 21:05:00 +00:00
}
stmt ::= expr(a) COLON expr(b) SEMI SEMIH EOL.
2013-07-03 22:03:46 +00:00
{
Debug::Dump(a.intValue, b.intValue - a.intValue);
}
stmt ::= expr(a) AT expr(b) SEMI SEMIH EOL.
{
Debug::Dump(a.intValue, b.intValue);
}
2013-07-05 17:56:24 +00:00
stmt ::= expr(a) SEMI SEMII EOL.
{
2013-08-22 02:40:53 +00:00
Debug::Info(a.intValue);
2013-07-05 17:56:24 +00:00
}
stmt ::= expr(a) SEMI SEMIL EOL.
2013-07-05 17:56:24 +00:00
{
Debug::List(a.intValue);
2013-07-03 22:03:46 +00:00
}
2013-07-03 21:05:00 +00:00
stmt ::= expr(a) AT expr(b) SEMI SEMIL EOL.
2013-07-13 17:46:41 +00:00
{
Debug::List(a.intValue, (int)b.intValue);
2013-07-13 17:46:41 +00:00
}
stmt ::= expr(a) COLON expr(b) SEMI SEMIL EOL.
2013-07-13 17:46:41 +00:00
{
Debug::List(a.intValue, b.intValue);
2013-07-13 17:46:41 +00:00
}
2014-12-30 19:09:07 +00:00
stmt ::= expr(a) SEMI SEMIDATE EOL.
{
Debug::PrintDate(a.intValue);
}
stmt ::= expr(a) SEMI SEMIERROR EOL.
{
Debug::PrintError(a.intValue);
}
2015-01-06 01:28:56 +00:00
stmt ::= expr(a) SEMI SEMIT IDENTIFIER(b) EOL.
{
Debug::ApplyTemplate(a.intValue, *b.stringValue);
}
stmt ::= expr SEMI SEMIT error EOL.
{
fprintf(stderr, "usage: expression ; t TemplateName\n");
}
2013-07-03 23:55:09 +00:00
stmt ::= DREGISTER(a) EQ expr(b) EOL.
2013-07-03 22:03:46 +00:00
{
Debug::SetDRegister(a.intValue, b.intValue);
2013-07-03 22:03:46 +00:00
}
2013-07-03 23:55:09 +00:00
stmt ::= AREGISTER(a) EQ expr(b) EOL.
2013-07-03 22:03:46 +00:00
{
Debug::SetARegister(a.intValue, b.intValue);
2013-07-03 22:03:46 +00:00
}
2013-07-03 23:55:09 +00:00
stmt ::= XREGISTER(a) EQ expr(b) EOL.
2013-07-03 22:03:46 +00:00
{
Debug::SetXRegister(a.intValue, b.intValue);
2013-07-03 22:03:46 +00:00
}
2013-07-03 23:55:09 +00:00
stmt ::= HELP EOL.
2013-07-03 22:03:46 +00:00
{
Debug::Help();
2013-07-03 21:05:00 +00:00
}
stmt ::= IDENTIFIER(a) EQ expr(b) EOL.
{
Debug::VariableSet(*a.stringValue, b.intValue);
}
2013-07-03 21:05:00 +00:00
expr(rhs) ::= unary(a). { rhs = a; }
expr(rhs) ::= expr(a) PLUS expr(b). { rhs = Token::Make(a.intValue + b.intValue); }
expr(rhs) ::= expr(a) MINUS expr(b). { rhs = Token::Make(a.intValue - b.intValue); }
expr(rhs) ::= expr(a) STAR expr(b). { rhs = Token::Make(a.intValue * b.intValue); }
expr(rhs) ::= expr(a) SLASH expr(b). { rhs = Token::Make(a.intValue / b.intValue); }
expr(rhs) ::= expr(a) PERCENT expr(b). { rhs = Token::Make(a.intValue % b.intValue); }
expr(rhs) ::= expr(a) LTLT expr(b). { rhs = Token::Make(a.intValue << b.intValue); }
expr(rhs) ::= expr(a) GTGT expr(b). { rhs = Token::Make(a.intValue >> b.intValue); }
expr(rhs) ::= expr(a) LT expr(b). { rhs = Token::Make(a.intValue < b.intValue); }
expr(rhs) ::= expr(a) LTEQ expr(b). { rhs = Token::Make(a.intValue <= b.intValue); }
expr(rhs) ::= expr(a) GT expr(b). { rhs = Token::Make(a.intValue > b.intValue); }
expr(rhs) ::= expr(a) GTEQ expr(b). { rhs = Token::Make(a.intValue >= b.intValue); }
expr(rhs) ::= expr(a) EQEQ expr(b). { rhs = Token::Make(a.intValue == b.intValue); }
expr(rhs) ::= expr(a) BANGEQ expr(b). { rhs = Token::Make(a.intValue != b.intValue); }
expr(rhs) ::= expr(a) AMP expr(b). { rhs = Token::Make(a.intValue & b.intValue); }
expr(rhs) ::= expr(a) CARET expr(b). { rhs = Token::Make(a.intValue ^ b.intValue); }
expr(rhs) ::= expr(a) PIPE expr(b). { rhs = Token::Make(a.intValue | b.intValue); }
expr(rhs) ::= expr(a) AMPAMP expr(b). { rhs = Token::Make(a.intValue && b.intValue); }
expr(rhs) ::= expr(a) PIPEPIPE expr(b). { rhs = Token::Make(a.intValue || b.intValue); }
2013-07-03 21:05:00 +00:00
// 68k assembly - offset(register)
// offset is a 16-bit quantity... this will
// handle 32-bit values or 16-bit.
expr(rhs) ::= unary(a) LPAREN register(b) RPAREN.
{
uint32_t offset = a.intValue;
uint32_t value = b.intValue;
// offset is 16-bits.
if (offset <= 0xffff)
{
if (offset & 0x8000)
offset |= 0xffff0000;
}
rhs = Token::Make(value + offset);
}
2013-07-03 21:05:00 +00:00
unary(rhs) ::= term(a). { rhs = a; }
unary(rhs) ::= PLUS unary(a). [BANG] { rhs = a; }
unary(rhs) ::= MINUS unary(a). [BANG] { rhs = Token::Make(-a.intValue); }
unary(rhs) ::= TILDE unary(a). { rhs = Token::Make(~a.intValue); }
unary(rhs) ::= BANG unary(a). { rhs = Token::Make(!a.intValue); }
unary(rhs) ::= STAR unary(a). [BANG] { rhs = Token::Make(Debug::ReadLong(a)); }
2013-07-03 21:05:00 +00:00
term(rhs) ::= LPAREN expr(a) RPAREN. { rhs = a; }
term(rhs) ::= INTEGER(a). { rhs = a; }
term(rhs) ::= register(a). { rhs = a; }
term(rhs) ::= IDENTIFIER(a).
{
// should throw/barf if undefined?
rhs = Token::Make(Debug::VariableGet(*a.stringValue));
}
register(rhs) ::= DREGISTER(a). { rhs = Token::Make(cpuGetDReg(a)); }
register(rhs) ::= AREGISTER(a). { rhs = Token::Make(cpuGetAReg(a)); }
register(rhs) ::= XREGISTER(a).
2013-07-03 21:05:00 +00:00
{
switch(a)
{
case 0:
rhs = Token::Make(cpuGetPC());
2013-07-03 21:05:00 +00:00
break;
case 1:
rhs = Token::Make(cpuGetSR());
2013-07-03 21:05:00 +00:00
break;
default:
rhs = Token::Make(0);
2013-07-03 21:05:00 +00:00
}
}