From 42953929067c30dcb7a72c1d4c7b26d85d626384 Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Sun, 4 May 2008 15:09:23 +0000 Subject: Added new Parser class, which will gradually grow to include all parsing code from the engine class. svn-id: r31865 --- engines/parallaction/parallaction.cpp | 30 +----------------- engines/parallaction/parallaction.h | 40 ++---------------------- engines/parallaction/parser.cpp | 43 ++++++++++++++++++++++++++ engines/parallaction/parser.h | 58 +++++++++++++++++++++++++++++++++++ engines/parallaction/parser_br.cpp | 28 ++++++++--------- engines/parallaction/parser_ns.cpp | 47 ++++++++++++++-------------- 6 files changed, 140 insertions(+), 106 deletions(-) diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index a7993412b3..17b2c70687 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -89,6 +89,7 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam Parallaction::~Parallaction() { delete _debugger; + delete _locationParser; delete _globalTable; delete _callableNames; @@ -588,35 +589,6 @@ void Parallaction::resumeJobs() { return; } - -void Parallaction::pushParserTables(OpcodeSet *opcodes, Table *statements) { - _opcodes.push(_currentOpcodes); - _statements.push(_currentStatements); - - _currentOpcodes = opcodes; - _currentStatements = statements; -} - -void Parallaction::popParserTables() { - assert(_opcodes.size() > 0); - - _currentOpcodes = _opcodes.pop(); - _currentStatements = _statements.pop(); -} - -void Parallaction::parseStatement() { - assert(_currentOpcodes != 0); - - _lookup = _currentStatements->lookup(_tokens[0]); - - debugC(9, kDebugParser, "parseStatement: %s (lookup = %i)", _tokens[0], _lookup); - - (*(*_currentOpcodes)[_lookup])(); -} - - - - AnimationPtr Parallaction::findAnimation(const char *name) { for (AnimationList::iterator it = _animations.begin(); it != _animations.end(); it++) diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 5b350c2195..4300a12f86 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -237,35 +237,6 @@ public: - -class Opcode { - -public: - virtual void operator()() const = 0; - virtual ~Opcode() { } -}; - -template -class OpcodeImpl : public Opcode { - - typedef void (T::*Fn)(); - - T* _instance; - Fn _fn; - -public: - OpcodeImpl(T* instance, const Fn &fn) : _instance(instance), _fn(fn) { } - - void operator()() const { - (_instance->*_fn)(); - } - -}; - -typedef Common::Array OpcodeSet; - - - #define DECLARE_UNQUALIFIED_ZONE_PARSER(sig) void locZoneParse_##sig() #define DECLARE_UNQUALIFIED_ANIM_PARSER(sig) void locAnimParse_##sig() #define DECLARE_UNQUALIFIED_COMMAND_PARSER(sig) void cmdParse_##sig() @@ -306,15 +277,6 @@ public: void updateGameInput(); void updateCommentInput(); - uint _lookup; - Common::Stack _opcodes; - Common::Stack _statements; - OpcodeSet *_currentOpcodes; - Table *_currentStatements; - void pushParserTables(OpcodeSet *opcodes, Table* statements); - void popParserTables(); - void parseStatement(); - OpcodeSet _commandOpcodes; struct ParallactionStruct1 { @@ -364,6 +326,8 @@ public: Table *_callableNames; Table *_localFlagNames; + Parser *_locationParser; + public: int getGameType() const; uint32 getFeatures() const; diff --git a/engines/parallaction/parser.cpp b/engines/parallaction/parser.cpp index cc0a772b45..665da16636 100644 --- a/engines/parallaction/parser.cpp +++ b/engines/parallaction/parser.cpp @@ -209,4 +209,47 @@ uint16 Script::readLineToken(bool errorOnEOF) { return fillTokens(line); } + +void Parser::reset() { + _currentOpcodes = 0; + _currentStatements = 0; + _script = 0; +} + +void Parser::pushTables(OpcodeSet *opcodes, Table *statements) { + _opcodes.push(_currentOpcodes); + _statements.push(_currentStatements); + + _currentOpcodes = opcodes; + _currentStatements = statements; +} + +void Parser::popTables() { + assert(_opcodes.size() > 0); + + _currentOpcodes = _opcodes.pop(); + _currentStatements = _statements.pop(); +} + +void Parser::parseStatement() { + assert(_currentOpcodes != 0); + + _script->readLineToken(true); + _lookup = _currentStatements->lookup(_tokens[0]); + + debugC(9, kDebugParser, "parseStatement: %s (lookup = %i)", _tokens[0], _lookup); + + (*(*_currentOpcodes)[_lookup])(); +} + +void Parser::bind(Script *script) { + reset(); + _script = script; +} + +void Parser::unbind() { + reset(); +} + + } // namespace Parallaction diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h index f2a2a0c4b6..d29a6c7e73 100644 --- a/engines/parallaction/parser.h +++ b/engines/parallaction/parser.h @@ -27,6 +27,7 @@ #define PARALLACTION_PARSER_H #include "common/stream.h" +#include "parallaction/objects.h" namespace Parallaction { @@ -58,6 +59,63 @@ public: +class Opcode { + +public: + virtual void operator()() const = 0; + virtual ~Opcode() { } +}; + +template +class OpcodeImpl : public Opcode { + + typedef void (T::*Fn)(); + + T* _instance; + Fn _fn; + +public: + OpcodeImpl(T* instance, const Fn &fn) : _instance(instance), _fn(fn) { } + + void operator()() const { + (_instance->*_fn)(); + } + +}; + +typedef Common::Array OpcodeSet; + + +class Parser { + +public: + Parser() { reset(); } + ~Parser() {} + + uint _lookup; + + Common::Stack _opcodes; + Common::Stack _statements; + + OpcodeSet *_currentOpcodes; + Table *_currentStatements; + + void bind(Script *script); + void unbind(); + void pushTables(OpcodeSet *opcodes, Table* statements); + void popTables(); + void parseStatement(); + +protected: + void reset(); + + Script *_script; +}; + + + + + } // namespace Parallaction #endif diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index 1968b008eb..8b36f54ea7 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -316,7 +316,7 @@ DECLARE_COMMAND_PARSER(endif) { DECLARE_COMMAND_PARSER(location) { debugC(7, kDebugParser, "COMMAND_PARSER(location) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._string = strdup(_tokens[1]); _locParseCtxt.nextToken++; @@ -345,7 +345,7 @@ DECLARE_COMMAND_PARSER(location) { DECLARE_COMMAND_PARSER(string) { debugC(7, kDebugParser, "COMMAND_PARSER(string) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._string = strdup(_tokens[1]); _locParseCtxt.nextToken++; @@ -357,7 +357,7 @@ DECLARE_COMMAND_PARSER(string) { DECLARE_COMMAND_PARSER(math) { debugC(7, kDebugParser, "COMMAND_PARSER(math) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._lvalue = _countersNames->lookup(_tokens[1]); _locParseCtxt.nextToken++; @@ -372,7 +372,7 @@ DECLARE_COMMAND_PARSER(math) { DECLARE_COMMAND_PARSER(test) { debugC(7, kDebugParser, "COMMAND_PARSER(test) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); uint counter = _countersNames->lookup(_tokens[1]); _locParseCtxt.nextToken++; @@ -405,7 +405,7 @@ DECLARE_COMMAND_PARSER(test) { DECLARE_COMMAND_PARSER(music) { debugC(7, kDebugParser, "COMMAND_PARSER(music) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._musicCommand = _audioCommandsNames->lookup(_tokens[1]); _locParseCtxt.nextToken++; @@ -423,7 +423,7 @@ DECLARE_COMMAND_PARSER(music) { DECLARE_COMMAND_PARSER(zeta) { debugC(7, kDebugParser, "COMMAND_PARSER(zeta) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._zeta0 = atoi(_tokens[1]); _locParseCtxt.nextToken++; @@ -445,7 +445,7 @@ DECLARE_COMMAND_PARSER(zeta) { DECLARE_COMMAND_PARSER(give) { debugC(7, kDebugParser, "COMMAND_PARSER(give) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._object = 4 + atoi(_tokens[1]); _locParseCtxt.nextToken++; @@ -471,7 +471,7 @@ DECLARE_COMMAND_PARSER(give) { DECLARE_COMMAND_PARSER(text) { debugC(7, kDebugParser, "COMMAND_PARSER(text) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); if (isdigit(_tokens[1][1])) { _locParseCtxt.cmd->u._zeta0 = atoi(_tokens[1]); @@ -497,7 +497,7 @@ DECLARE_COMMAND_PARSER(text) { DECLARE_COMMAND_PARSER(unary) { debugC(7, kDebugParser, "COMMAND_PARSER(unary) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._rvalue = atoi(_tokens[1]); _locParseCtxt.nextToken++; @@ -548,7 +548,7 @@ DECLARE_ZONE_PARSER(type) { // } } - popParserTables(); + _locationParser->popTables(); } @@ -592,7 +592,7 @@ DECLARE_ANIM_PARSER(endanimation) { _locParseCtxt.a->_flags |= 0x1000000; - popParserTables(); + _locationParser->popTables(); } @@ -760,6 +760,8 @@ typedef OpcodeImpl OpcodeV2; void Parallaction_br::initParsers() { + _locationParser = new Parser; + static const OpcodeV2 op0[] = { INSTRUCTION_PARSER(defLocal), // invalid opcode -> local definition INSTRUCTION_PARSER(zone), // on @@ -908,10 +910,6 @@ void Parallaction_br::initParsers() { for (i = 0; i < ARRAYSIZE(op6); i++) _locationAnimParsers.push_back(&op6[i]); - - _currentOpcodes = 0; - _currentStatements = 0; - } void Parallaction_br::parseLocation(const char* filename) { diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp index 5e4bdf25cf..f955f44c8c 100644 --- a/engines/parallaction/parser_ns.cpp +++ b/engines/parallaction/parser_ns.cpp @@ -112,7 +112,7 @@ DECLARE_ANIM_PARSER(type) { _locParseCtxt.a->_flags |= 0x1000000; - popParserTables(); + _locationParser->popTables(); } @@ -176,7 +176,7 @@ DECLARE_ANIM_PARSER(endanimation) { _locParseCtxt.a->_flags |= 0x1000000; - popParserTables(); + _locationParser->popTables(); } void Parallaction_ns::parseAnimation(Script& script, AnimationList &list, char *name) { @@ -191,7 +191,7 @@ void Parallaction_ns::parseAnimation(Script& script, AnimationList &list, char * _locParseCtxt.a = a; _locParseCtxt.script = &script; - pushParserTables(&_locationAnimParsers, _locationAnimStmt); + _locationParser->pushTables(&_locationAnimParsers, _locationAnimStmt); } void Parallaction_ns::parseInstruction(ProgramPtr program) { @@ -469,7 +469,7 @@ void Parallaction_ns::parseLValue(ScriptVar &v, const char *str) { DECLARE_COMMAND_PARSER(flags) { debugC(7, kDebugParser, "COMMAND_PARSER(flags) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); if (_globalTable->lookup(_tokens[1]) == Table::notFound) { do { @@ -496,7 +496,7 @@ DECLARE_COMMAND_PARSER(flags) { DECLARE_COMMAND_PARSER(zone) { debugC(7, kDebugParser, "COMMAND_PARSER(zone) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._zone = findZone(_tokens[_locParseCtxt.nextToken]); if (!_locParseCtxt.cmd->u._zone) { @@ -512,7 +512,7 @@ DECLARE_COMMAND_PARSER(zone) { DECLARE_COMMAND_PARSER(location) { debugC(7, kDebugParser, "COMMAND_PARSER(location) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._string = strdup(_tokens[_locParseCtxt.nextToken]); _locParseCtxt.nextToken++; @@ -525,7 +525,7 @@ DECLARE_COMMAND_PARSER(location) { DECLARE_COMMAND_PARSER(drop) { debugC(7, kDebugParser, "COMMAND_PARSER(drop) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._object = 4 + _objectsNames->lookup(_tokens[_locParseCtxt.nextToken]); _locParseCtxt.nextToken++; @@ -538,7 +538,7 @@ DECLARE_COMMAND_PARSER(drop) { DECLARE_COMMAND_PARSER(call) { debugC(7, kDebugParser, "COMMAND_PARSER(call) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._callable = _callableNames->lookup(_tokens[_locParseCtxt.nextToken]) - 1; _locParseCtxt.nextToken++; @@ -551,7 +551,7 @@ DECLARE_COMMAND_PARSER(call) { DECLARE_COMMAND_PARSER(simple) { debugC(7, kDebugParser, "COMMAND_PARSER(simple) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); addCommand(); } @@ -559,7 +559,7 @@ DECLARE_COMMAND_PARSER(simple) { DECLARE_COMMAND_PARSER(move) { debugC(7, kDebugParser, "COMMAND_PARSER(move) "); - createCommand(_lookup); + createCommand(_locationParser->_lookup); _locParseCtxt.cmd->u._move.x = atoi(_tokens[_locParseCtxt.nextToken]); _locParseCtxt.nextToken++; @@ -573,7 +573,7 @@ DECLARE_COMMAND_PARSER(move) { DECLARE_COMMAND_PARSER(endcommands) { debugC(7, kDebugParser, "COMMAND_PARSER(endcommands) "); - popParserTables(); + _locationParser->popTables(); // temporary trick to handle dialogue commands _locParseCtxt.endcommands = true; @@ -679,7 +679,7 @@ void Parallaction_ns::parseCommands(Script &script, CommandList& list) { _locParseCtxt.endcommands = false; _locParseCtxt.script = &script; - pushParserTables(&_commandParsers, _commandsNames); + _locationParser->pushTables(&_commandParsers, _commandsNames); } Dialogue *Parallaction_ns::parseDialogue(Script &script) { @@ -779,8 +779,7 @@ Answer *Parallaction_ns::parseAnswer(Script &script) { parseCommands(script, answer->_commands); _locParseCtxt.endcommands = false; do { - script.readLineToken(true); - parseStatement(); + _locationParser->parseStatement(); } while (!_locParseCtxt.endcommands); script.readLineToken(true); @@ -980,6 +979,7 @@ void Parallaction_ns::parseLocation(const char *filename) { _numForwardedCommands = 0; Script *script = _disk->loadLocation(filename); + _locationParser->bind(script); // TODO: the following two lines are specific to Nippon Safes // and should be moved into something like 'initializeParsing()' @@ -989,12 +989,12 @@ void Parallaction_ns::parseLocation(const char *filename) { _locParseCtxt.script = script; _locParseCtxt.filename = filename; - pushParserTables(&_locationParsers, _locationStmt); + _locationParser->pushTables(&_locationParsers, _locationStmt); do { - script->readLineToken(true); - parseStatement(); + _locationParser->parseStatement(); } while (!_locParseCtxt.end); - popParserTables(); + _locationParser->popTables(); + _locationParser->unbind(); delete script; @@ -1048,6 +1048,8 @@ typedef OpcodeImpl OpcodeV1; void Parallaction_ns::initParsers() { + _locationParser = new Parser; + static const OpcodeV1 op0[] = { INSTRUCTION_PARSER(defLocal), // invalid opcode -> local definition INSTRUCTION_PARSER(animation), // on @@ -1153,9 +1155,6 @@ void Parallaction_ns::initParsers() { for (i = 0; i < ARRAYSIZE(op6); i++) _locationAnimParsers.push_back(&op6[i]); - _currentOpcodes = 0; - _currentStatements = 0; - } // @@ -1193,7 +1192,7 @@ DECLARE_ZONE_PARSER(null) { DECLARE_ZONE_PARSER(endzone) { debugC(7, kDebugParser, "ZONE_PARSER(endzone) "); - popParserTables(); + _locationParser->popTables(); } DECLARE_ZONE_PARSER(limits) { @@ -1226,7 +1225,7 @@ DECLARE_ZONE_PARSER(type) { parseZoneTypeBlock(*_locParseCtxt.script, _locParseCtxt.z); } - popParserTables(); + _locationParser->popTables(); } @@ -1274,7 +1273,7 @@ void Parallaction_ns::parseZone(Script &script, ZoneList &list, char *name) { list.push_front(z); - pushParserTables(&_locationZoneParsers, _locationZoneStmt); + _locationParser->pushTables(&_locationZoneParsers, _locationZoneStmt); return; } -- cgit v1.2.3