apply template

This commit is contained in:
Kelvin Sherlock 2014-12-29 16:58:01 -05:00
parent d400bfb4da
commit 8e434d39f8
8 changed files with 273 additions and 101 deletions

View File

@ -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)

View File

@ -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 {
/*

View File

@ -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

View File

@ -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<std::string> 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;
};
*|;

View File

@ -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.
{

224
bin/template.cpp Normal file
View File

@ -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);
}
}
}

View File

@ -2,6 +2,7 @@
#define __debug_template_h__
#include <unordered_map>
#include <string>
namespace Debug {
@ -128,6 +129,9 @@ namespace Debug {
bool LoadTemplateFile(const std::string &filename, std::unordered_map<std::string, Template> &);
void ApplyTemplate(uint32_t address, FieldEntry *e, unsigned indent = 0);
}
#endif

View File

@ -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<std::string, Template> &Templates)