diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt index 9f2dd5b..5e1ffff 100644 --- a/bin/CMakeLists.txt +++ b/bin/CMakeLists.txt @@ -71,7 +71,8 @@ set_source_files_properties( add_executable(mpw loader.cpp debugger.cpp debugger_internal.cpp address_map.cpp lexer.cpp parser.cpp loadtrap.cpp commands.cpp - template_loader.cpp template_parser.cpp) + template_loader.cpp template_parser.cpp intern.cpp template.cpp) + target_link_libraries(mpw CPU_LIB) target_link_libraries(mpw TOOLBOX_LIB) diff --git a/bin/debugger.cpp b/bin/debugger.cpp index 6ff3cb6..0a5d243 100644 --- a/bin/debugger.cpp +++ b/bin/debugger.cpp @@ -1136,8 +1136,24 @@ void Info(uint32_t address) cp = nullptr; } } + } + void ApplyTemplate(int32_t address, const std::string &name) + { + // find the template.. + + auto iter = TemplateTable.find(name); + if (iter == TemplateTable.end()) { + fprintf(stderr, "Unknown template: %s\n", name.c_str()); + return; + } + + FieldEntry *e = iter->second; + ApplyTemplate(address, e); + } + + namespace { /* diff --git a/bin/debugger.h b/bin/debugger.h index 4666eab..1596896 100644 --- a/bin/debugger.h +++ b/bin/debugger.h @@ -144,6 +144,8 @@ void ReadWriteBreak(int32_t address); void PrintError(uint32_t value); void PrintDate(uint32_t value); +void ApplyTemplate(int32_t address, const std::string &name); + } #endif diff --git a/bin/lexer.rl b/bin/lexer.rl index e4c4a35..80a06da 100644 --- a/bin/lexer.rl +++ b/bin/lexer.rl @@ -105,6 +105,21 @@ namespace { # this exits with cs == lexer_en_error. error := any* ${ fbreak; }; + # identifiers. + ident := |* + + [ \t\r\n]+; + + [_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)); + }; + + *|; + # semi-colon commands. semi := |* @@ -130,7 +145,10 @@ namespace { Parse(parser, tkSEMIERROR, 0, command); }; - + 't'i { + Parse(parser, tkSEMIT, 0, command); + fgoto ident; + }; *|; diff --git a/bin/parser.lemon b/bin/parser.lemon index c27502c..3797f8b 100644 --- a/bin/parser.lemon +++ b/bin/parser.lemon @@ -200,7 +200,6 @@ stmt ::= expr(a) COLON expr(b) SEMI SEMIL EOL. Debug::List(a.intValue, b.intValue); } - stmt ::= expr(a) SEMI SEMIDATE EOL. { Debug::PrintDate(a.intValue); @@ -212,6 +211,11 @@ stmt ::= expr(a) SEMI SEMIERROR EOL. Debug::PrintError(a.intValue); } +stmt ::= expr(a) SEMI SEMIT IDENTIFIER(b) EOL. +{ + Debug::ApplyTemplate(a.intValue, *b.stringValue); +} + stmt ::= DREGISTER(a) EQ expr(b) EOL. { diff --git a/bin/template.cpp b/bin/template.cpp new file mode 100644 index 0000000..a17fab5 --- /dev/null +++ b/bin/template.cpp @@ -0,0 +1,224 @@ +#include "template.h" +#include "debugger.h" + +namespace Debug { + + namespace { + + + unsigned CalcOneSize(FieldEntry *e) + { + unsigned s = (e->type & 0x0f00) >> 8; + + if (!s) { + // struct or pointer... + if (e->type & 0x8000) s = 4; + else if (e->tmpl) s = e->tmpl->struct_size; + } + + if (e->count) s *= e->count; + + return s; + } + + unsigned CalcSize(FieldEntry *e) + { + unsigned size = 0; + + while (e) + { + size += CalcOneSize(e); + e = e->next; + } + return size; + } + + FieldEntry *Reverse(FieldEntry *e) + { + if (!e) return e; + + // reverse the order... + FieldEntry *prev; + FieldEntry *next; + + prev = nullptr; + for(;;) + { + next = e->next; + e->next = prev; + + prev = e; + e = next; + if (!e) return prev; + } + } + + + } + + void CreateTypedef(const std::string *name, int type, TemplateParseInfo *info) + { + // check if it's an existing typedef... + + auto &Templates = *info->templates; + auto &Types = *info->types; + + + auto iter = Types.find(*name); + if (iter != Types.end()) + { + if (iter->second == type) return; // ok, just a duplicate. + fprintf(stderr, "Template Error: line %d - redefining %s\n", + info->LineNumber, name->c_str()); + + return; + } + + if (Templates.find(*name) != Templates.end()) + { + fprintf(stderr, "Template Error: line %d - redefining %s\n", + info->LineNumber, name->c_str()); + + return; + } + + Types.emplace(std::make_pair(*name, type)); + } + + + void CreateTemplate(const std::string *name, FieldEntry *firstField, TemplateParseInfo *info) + { + auto &Templates = *info->templates; + auto &Types = *info->types; + + // check if it exists... + + if (Templates.find(*name) != Templates.end()) + { + fprintf(stderr, "Template Error: line %d - redefining %s\n", + info->LineNumber, name->c_str()); + return; + } + + if (Types.find(*name) != Types.end()) + { + fprintf(stderr, "Template Error: line %d - redefining %s\n", + info->LineNumber, name->c_str()); + return; + } + + firstField = Reverse(firstField); + firstField->struct_size = CalcSize(firstField); + + Templates.emplace(std::make_pair(*name, firstField)); + } + + + void PrettyPrint(uint32_t value, unsigned type) + { + + switch (type) + { + case kOSType: + // print 4-cc code + return; + case kOSErr: + // print value + short name + return; + + case kPStringPtr: + // read the string... + return; + + case kCStringPtr: + // read the string... + return; + + case kBoolean: + fputs(value ? "true" : "false", stdout); + return; + + case kHandle: + // print address, size, locked stats. + return; + + } + + // int/signed int - print base 10. + + } + + + void ApplyTemplate(uint32_t address, FieldEntry *e, unsigned indent) + { + unsigned offset = 0; + + for( ; e ; e = e->next) + { + + unsigned count = e->count; + unsigned type = e->type; + unsigned s = (type & 0x0f00) >> 8; + + if (!s) { + // struct or pointer... + if (e->type & 0x8000) s = 4; + else if (e->tmpl) s = e->tmpl->struct_size; + } + + + printf("%-20s", e->name->c_str()); + + // todo -- support arrays + // todo -- pretty print values (boolean, oserr, ostype, etc.) + switch(s) + { + case 1: + { + uint8_t value = ReadByte(address + offset); + printf(" %02x", value); + PrettyPrint(value, type); + break; + } + + case 2: + { + uint16_t value = ReadWord(address + offset); + printf(" %04x", value); + PrettyPrint(value, type); + break; + } + + case 4: + { + uint32_t value = ReadLong(address + offset); + printf("%08x", value); + PrettyPrint(value, type); + break; + } + + case 0: + // either a pointer or a struct + if (type & 0x8000) { + // pointer. + uint32_t value = ReadLong(address + offset); + printf("%08x", value); + PrettyPrint(value, type); + break; + } + if (type == 0) { + // struct ... recurse. + + break; + } + } + + printf("\n"); + offset += CalcOneSize(e); + + } + + + } + +} diff --git a/bin/template.h b/bin/template.h index aae9f80..d1e65b1 100644 --- a/bin/template.h +++ b/bin/template.h @@ -2,6 +2,7 @@ #define __debug_template_h__ #include +#include namespace Debug { @@ -128,6 +129,9 @@ namespace Debug { bool LoadTemplateFile(const std::string &filename, std::unordered_map &); + void ApplyTemplate(uint32_t address, FieldEntry *e, unsigned indent = 0); + + } #endif diff --git a/bin/template_loader.rl b/bin/template_loader.rl index 1e91e0e..931e252 100644 --- a/bin/template_loader.rl +++ b/bin/template_loader.rl @@ -50,7 +50,7 @@ void TemplateParse(void *yyp, int yymajor, void *yyminor, Debug::TemplateParseIn void TemplateParse(void *yyp, int yymajor, int yyminor, Debug::TemplateParseInfo *info) { - TemplateParse(yyp, yymajor, (void *)yyminor, info); + TemplateParse(yyp, yymajor, (void *)(ptrdiff_t)yyminor, info); } void TemplateParse(void *yyp, int yymajor, const std::string *yyminor, Debug::TemplateParseInfo *info) @@ -175,104 +175,7 @@ void TemplateParse(void *yyp, int yymajor, const std::string *yyminor, Debug::Te namespace Debug { -void CreateTypedef(const std::string *name, int type, TemplateParseInfo *info) -{ - // check if it's an existing typedef... - auto &Templates = *info->templates; - auto &Types = *info->types; - - - auto iter = Types.find(*name); - if (iter != Types.end()) - { - if (iter->second == type) return; // ok, just a duplicate. - fprintf(stderr, "Template Error: line %d - redefining %s\n", - info->LineNumber, name->c_str()); - - return; - } - - if (Templates.find(*name) != Templates.end()) - { - fprintf(stderr, "Template Error: line %d - redefining %s\n", - info->LineNumber, name->c_str()); - - return; - } - - Types.emplace(std::make_pair(*name, type)); -} - -unsigned CalcSize(FieldEntry *e) -{ - unsigned size = 0; - - while (e) - { - unsigned s = (e->type & 0x0f00) >> 8; - - if (!s) { - // struct or pointer... - if (e->type & 0x8000) s = 4; - else if (e->tmpl) s = e->tmpl->struct_size; - } - - if (e->count != 0) s *= e->count; - - size += s; - e = e->next; - } - return size; -} - -FieldEntry *Reverse(FieldEntry *e) -{ - if (!e) return e; - - // reverse the order... - FieldEntry *prev; - FieldEntry *next; - - prev = nullptr; - for(;;) - { - next = e->next; - e->next = prev; - - prev = e; - e = next; - if (!e) return prev; - } -} - - -void CreateTemplate(const std::string *name, FieldEntry *firstField, TemplateParseInfo *info) -{ - auto &Templates = *info->templates; - auto &Types = *info->types; - - // check if it exists... - - if (Templates.find(*name) != Templates.end()) - { - fprintf(stderr, "Template Error: line %d - redefining %s\n", - info->LineNumber, name->c_str()); - return; - } - - if (Types.find(*name) != Types.end()) - { - fprintf(stderr, "Template Error: line %d - redefining %s\n", - info->LineNumber, name->c_str()); - return; - } - - firstField = Reverse(firstField); - firstField->struct_size = CalcSize(firstField); - - Templates.emplace(std::make_pair(*name, firstField)); -} bool LoadTemplateFile(const std::string &filename, std::unordered_map &Templates)