mirror of
https://github.com/ksherlock/mpw.git
synced 2025-02-23 00:28:57 +00:00
use new token type, support for identifiers
This commit is contained in:
parent
b7b6d8656b
commit
e414163ec9
@ -18,6 +18,14 @@ enum {
|
||||
cmdRun,
|
||||
};
|
||||
|
||||
enum {
|
||||
// subtypes
|
||||
// ; commands
|
||||
kHexdump = 1,
|
||||
kInfo,
|
||||
kList
|
||||
};
|
||||
|
||||
struct Command {
|
||||
bool valid;
|
||||
int action;
|
||||
|
27
bin/lexer.rl
27
bin/lexer.rl
@ -27,6 +27,8 @@
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <memory>
|
||||
#include <deque>
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdlib.h>
|
||||
@ -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<std::string> 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<std::unique_ptr<std::string>> Strings;
|
||||
|
||||
|
||||
parser = ParseAlloc(malloc);
|
||||
|
||||
//ParseTrace(stdout, "--> ");
|
||||
|
115
bin/parser.lemon
115
bin/parser.lemon
@ -2,7 +2,7 @@
|
||||
%extra_argument { Debug::Command *command }
|
||||
%token_prefix tk
|
||||
|
||||
%token_type {uint32_t}
|
||||
%token_type { Token }
|
||||
%include {
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
@ -11,6 +11,9 @@
|
||||
#include "debugger.h"
|
||||
|
||||
#include <toolbox/MM.h>
|
||||
|
||||
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));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user