diff --git a/bin/debugger.h b/bin/debugger.h index 2c82142..dea15ea 100644 --- a/bin/debugger.h +++ b/bin/debugger.h @@ -18,6 +18,14 @@ enum { cmdRun, }; +enum { + // subtypes + // ; commands + kHexdump = 1, + kInfo, + kList +}; + struct Command { bool valid; int action; diff --git a/bin/lexer.rl b/bin/lexer.rl index 5f9bb05..f7d0967 100644 --- a/bin/lexer.rl +++ b/bin/lexer.rl @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include #include @@ -37,9 +39,17 @@ void *ParseAlloc(void *(*mallocProc)(size_t)); void ParseFree(void *p, void (*freeProc)(void*)); - void Parse(void *yyp, int yymajor, uint32_t yyminor, Debug::Command *command); + void Parse(void *yyp, int yymajor, Debug::Token yyminor, Debug::Command *command); void ParseTrace(FILE *TraceFILE, char *zTracePrompt); + + // for the common case.... + void Parse(void *yyp, int yymajor, uint32_t yyminor, Debug::Command *command) + { + Parse(yyp, yymajor, Debug::Token::Make(yyminor), command); + } + + namespace { int tox(char c) @@ -268,10 +278,13 @@ namespace { # generic identifier - [_A-Za-z][_A-Za-z0-9]* { - // TODO -- pass into parser, parser can check environment value. - fprintf(stderr, "illegal identifier: `%.*s`\n", (int)(te - ts), ts); - fgoto error; + # since % is a valid character, should drop %/modulo operator. + [%_A-Za-z][%_.A-Za-z0-9]* { + + std::unique_ptr sp(new std::string(ts, te)); + + Parse(parser, tkIDENTIFIER, Token::Make(sp.get(), 0), command); + Strings.push_back(std::move(sp)); }; @@ -297,6 +310,10 @@ bool ParseLine(const char *iter, Command *command) void *parser; + // string table to avoid memory leaks in parser. + std::deque> Strings; + + parser = ParseAlloc(malloc); //ParseTrace(stdout, "--> "); diff --git a/bin/parser.lemon b/bin/parser.lemon index 79b3dfa..34d418b 100644 --- a/bin/parser.lemon +++ b/bin/parser.lemon @@ -2,7 +2,7 @@ %extra_argument { Debug::Command *command } %token_prefix tk -%token_type {uint32_t} +%token_type { Token } %include { #include #include @@ -11,6 +11,9 @@ #include "debugger.h" #include + +using Debug::Token; + #ifdef __cplusplus extern "C" { #endif @@ -55,7 +58,7 @@ uint32_t cpuGetDReg(unsigned); stmt ::= expr(a) EOL. { - Debug::Print(a); + Debug::Print(a.intValue); } stmt ::= STAR EOL. @@ -65,7 +68,7 @@ stmt ::= STAR EOL. stmt ::= PRINT expr(a) EOL. { - Debug::Print(a); + Debug::Print(a.intValue); } stmt ::= BREAK EOL. @@ -75,7 +78,7 @@ stmt ::= BREAK EOL. stmt ::= BREAK expr(a) EOL. { - Debug::Break(a); + Debug::Break(a.intValue); } stmt ::= CONTINUE EOL. @@ -91,7 +94,7 @@ stmt ::= TBREAK EOL. stmt ::= TBREAK expr(a) EOL. { - Debug::ToolBreak(a); + Debug::ToolBreak(a.intValue); } stmt ::= RBREAK EOL . @@ -101,7 +104,7 @@ stmt ::= RBREAK EOL . stmt ::= RBREAK expr(a) EOL. { - Debug::ReadBreak(a); + Debug::ReadBreak(a.intValue); } stmt ::= WBREAK EOL. @@ -111,13 +114,13 @@ stmt ::= WBREAK EOL. stmt ::= WBREAK expr(a) EOL. { - Debug::WriteBreak(a); + Debug::WriteBreak(a.intValue); } stmt ::= RWBREAK expr(a) EOL . { - Debug::ReadWriteBreak(a); + Debug::ReadWriteBreak(a.intValue); } @@ -131,82 +134,81 @@ stmt ::= NEXT expr(a) EOL. { command->action = Debug::cmdStep; command->argc = 1; - command->argv[0] = a; + command->argv[0] = a.intValue; } stmt ::= DUMP expr(a) EOL. { - Debug::Dump(a); + Debug::Dump(a.intValue); } stmt ::= DUMP expr(a) COLON expr(b) EOL. { - Debug::Dump(a, b - a); + Debug::Dump(a.intValue, b.intValue - a.intValue); } stmt ::= DUMP expr(a) AT expr(b) EOL. { - Debug::Dump(a, b); + Debug::Dump(a.intValue, b.intValue); } stmt ::= LIST expr(a) EOL. { - Debug::List(a); + Debug::List(a.intValue); } stmt ::= expr(a) SEMIH EOL. { - Debug::Dump(a); + Debug::Dump(a.intValue); } stmt ::= expr(a) COLON expr(b) SEMIH EOL. { - Debug::Dump(a, b - a); + Debug::Dump(a.intValue, b.intValue - a.intValue); } stmt ::= expr(a) AT expr(b) SEMIH EOL. { - Debug::Dump(a, b); + Debug::Dump(a.intValue, b.intValue); } stmt ::= expr(a) SEMII EOL. { - MM::Native::MemoryInfo(a); + MM::Native::MemoryInfo(a.intValue); } - stmt ::= expr(a) SEMIL EOL. { - Debug::List(a); + Debug::List(a.intValue); } stmt ::= expr(a) AT expr(b) SEMIL EOL. { - Debug::List(a, (int)b); + Debug::List(a.intValue, (int)b.intValue); } stmt ::= expr(a) COLON expr(b) SEMIL EOL. { - Debug::List(a, b); + Debug::List(a.intValue, b.intValue); } stmt ::= DREGISTER(a) EQ expr(b) EOL. { - Debug::SetDRegister(a, b); + Debug::SetDRegister(a.intValue, b.intValue); } stmt ::= AREGISTER(a) EQ expr(b) EOL. { - Debug::SetARegister(a, b); + Debug::SetARegister(a.intValue, b.intValue); } stmt ::= XREGISTER(a) EQ expr(b) EOL. { - Debug::SetXRegister(a, b); + Debug::SetXRegister(a.intValue, b.intValue); } stmt ::= HELP EOL. @@ -214,51 +216,62 @@ stmt ::= HELP EOL. Debug::Help(); } +stmt ::= IDENTIFIER(a) EQ expr(b) EOL. +{ + Debug::VariableSet(*a.stringValue, b.intValue); +} + expr(rhs) ::= unary(a). { rhs = a; } -expr(rhs) ::= expr(a) PLUS expr(b). { rhs = a + b; } -expr(rhs) ::= expr(a) MINUS expr(b). { rhs = a - b; } -expr(rhs) ::= expr(a) STAR expr(b). { rhs = a * b; } -expr(rhs) ::= expr(a) SLASH expr(b). { rhs = a / b; } -expr(rhs) ::= expr(a) PERCENT expr(b). { rhs = a % b; } -expr(rhs) ::= expr(a) LTLT expr(b). { rhs = a << b; } -expr(rhs) ::= expr(a) GTGT expr(b). { rhs = a >> b; } -expr(rhs) ::= expr(a) LT expr(b). { rhs = a < b; } -expr(rhs) ::= expr(a) LTEQ expr(b). { rhs = a <= b; } -expr(rhs) ::= expr(a) GT expr(b). { rhs = a > b; } -expr(rhs) ::= expr(a) GTEQ expr(b). { rhs = a >= b; } -expr(rhs) ::= expr(a) EQEQ expr(b). { rhs = a == b; } -expr(rhs) ::= expr(a) BANGEQ expr(b). { rhs = a != b; } -expr(rhs) ::= expr(a) AMP expr(b). { rhs = a & b; } -expr(rhs) ::= expr(a) CARET expr(b). { rhs = a ^ b; } -expr(rhs) ::= expr(a) PIPE expr(b). { rhs = a | b; } -expr(rhs) ::= expr(a) AMPAMP expr(b). { rhs = a && b; } -expr(rhs) ::= expr(a) PIPEPIPE expr(b). { rhs = a || b; } +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); } unary(rhs) ::= term(a). { rhs = a; } unary(rhs) ::= PLUS unary(a). [BANG] { rhs = a; } -unary(rhs) ::= MINUS unary(a). [BANG] { rhs = -a; } -unary(rhs) ::= TILDE unary(a). { rhs = ~a; } -unary(rhs) ::= BANG unary(a). { rhs = !a; } -unary(rhs) ::= STAR unary(a). [BANG] { rhs = Debug::ReadLong(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)); } term(rhs) ::= LPAREN expr(a) RPAREN. { rhs = a; } term(rhs) ::= INTEGER(a). { rhs = a; } -term(rhs) ::= DREGISTER(a). { rhs = cpuGetDReg(a); } -term(rhs) ::= AREGISTER(a). { rhs = cpuGetAReg(a); } +term(rhs) ::= DREGISTER(a). { rhs = Token::Make(cpuGetDReg(a)); } +term(rhs) ::= AREGISTER(a). { rhs = Token::Make(cpuGetAReg(a)); } term(rhs) ::= XREGISTER(a). { switch(a) { case 0: - rhs = cpuGetPC(); + rhs = Token::Make(cpuGetPC()); break; case 1: - rhs = cpuGetSR(); + rhs = Token::Make(cpuGetSR()); break; default: - rhs = 0; + rhs = Token::Make(0); } } + +term(rhs) ::= IDENTIFIER(a). +{ + // should throw/barf if undefined? + rhs = Token::Make(Debug::VariableGet(*a.stringValue)); +}