diff options
author | Paul Gilbert | 2019-06-11 20:12:28 -0700 |
---|---|---|
committer | Paul Gilbert | 2019-06-12 21:30:41 -0700 |
commit | 9efb6d71e2ec91cbfa77b236406a9d680e8e44cf (patch) | |
tree | 97ceaf85b7a24b53dab82cad35ca7c152bdf836c /engines/glk | |
parent | 4e74751e7e40e0a3ddada4b4266c845004d2498d (diff) | |
download | scummvm-rg350-9efb6d71e2ec91cbfa77b236406a9d680e8e44cf.tar.gz scummvm-rg350-9efb6d71e2ec91cbfa77b236406a9d680e8e44cf.tar.bz2 scummvm-rg350-9efb6d71e2ec91cbfa77b236406a9d680e8e44cf.zip |
GLK: ADVSYS: In progress implementing input line parser
Diffstat (limited to 'engines/glk')
-rw-r--r-- | engines/glk/advsys/game.cpp | 12 | ||||
-rw-r--r-- | engines/glk/advsys/game.h | 23 | ||||
-rw-r--r-- | engines/glk/advsys/vm.cpp | 55 | ||||
-rw-r--r-- | engines/glk/advsys/vm.h | 29 |
4 files changed, 106 insertions, 13 deletions
diff --git a/engines/glk/advsys/game.cpp b/engines/glk/advsys/game.cpp index fe1221baf7..cd19623f5d 100644 --- a/engines/glk/advsys/game.cpp +++ b/engines/glk/advsys/game.cpp @@ -202,7 +202,7 @@ bool Game::match(int obj, int noun, int *adjectives) { return true; } -int Game::checkVerb(int *verbs) { +int Game::checkVerb(const Common::Array<int> &verbs) { // Iterate through the actions for (int idx = 1; idx <= _actionCount; ++idx) { if (hasVerb(idx, verbs)) @@ -212,7 +212,7 @@ int Game::checkVerb(int *verbs) { return NIL; } -int Game::findAction(int *verbs, int preposition, int flag) { +int Game::findAction(const Common::Array<int> &verbs, int preposition, int flag) { // Iterate through the actions for (int idx = 1; idx <= _actionCount; ++idx) { if ((preposition && !hasPreposition(idx, preposition)) || !hasVerb(idx, verbs)) @@ -301,23 +301,23 @@ bool Game::hasAdjective(int obj, int adjective) const { return false; } -bool Game::hasVerb(int act, int *verbs) const { +bool Game::hasVerb(int act, const Common::Array<int> &verbs) const { // Get the list of verbs int link = getActionField(act, A_VERBS); // Look for the verb for (; link; link = readWord(link + L_NEXT)) { - int *verb = verbs; + Common::Array<int>::const_iterator verb = verbs.begin(); int word = readWord(link + L_DATA); - for (; *verb && word; link = readWord(link + L_NEXT)) { + for (; verb < verbs.end() && word; link = readWord(link + L_NEXT)) { if (*verb != readWord(word + L_DATA)) break; ++verb; } - if (!*verb && !word) + if (verb == verbs.end() && !word) return true; } diff --git a/engines/glk/advsys/game.h b/engines/glk/advsys/game.h index 99cfe26068..1b7c6f95b0 100644 --- a/engines/glk/advsys/game.h +++ b/engines/glk/advsys/game.h @@ -46,6 +46,19 @@ enum Action { }; /** + * Word types + */ +enum WordType { + WT_UNKNOWN = 0, + WT_VERB = 1, + WT_NOUN = 2, + WT_ADJECTIVE = 3, + WT_PREPOSITION = 4, + WT_CONJUNCTION = 5, + WT_ARTICLE = 6 +}; + +/** * Object fields */ enum ObjectField { @@ -169,7 +182,7 @@ private: /** * Returns true if an action has a given verb */ - bool hasVerb(int act, int *verbs) const; + bool hasVerb(int act, const Common::Array<int> &verbs) const; /** * Returns true if an action is in a given list @@ -253,8 +266,8 @@ public: /** * Return a word's type */ - int getWordType(int word) const { - return _wordTypeTable[word]; + WordType getWordType(int word) const { + return (WordType)_wordTypeTable[word]; } /** @@ -265,12 +278,12 @@ public: /** * Check to see if this is a valid verb */ - int checkVerb(int *verbs); + int checkVerb(const Common::Array<int> &verbs); /** * Find an action matching a given description */ - int findAction(int *verbs, int preposition, int flag); + int findAction(const Common::Array<int> &verbs, int preposition, int flag); /** * Get an object property diff --git a/engines/glk/advsys/vm.cpp b/engines/glk/advsys/vm.cpp index 21f79d596b..54ab84c9c6 100644 --- a/engines/glk/advsys/vm.cpp +++ b/engines/glk/advsys/vm.cpp @@ -85,7 +85,7 @@ OpcodeMethod VM::_METHODS[0x34] = { VM::VM(OSystem *syst, const GlkGameDescription &gameDesc) : GlkInterface(syst, gameDesc), Game(), _fp(_stack), _pc(0), _status(IN_PROGRESS), _actor(-1), _action(-1), _dObject(-1), - _ndObjects(-1), _iObject(-1) { + _ndObjects(-1), _iObject(-1), _wordPtr(nullptr) { Common::fill(&_nouns[0], &_nouns[20], 0); Common::fill(&_nounWords[0], &_nounWords[20], -1); Common::fill(&_adjectives[0], &_adjectives[20], (int *)nullptr); @@ -452,6 +452,14 @@ bool VM::parseInput() { if (!getLine()) return false; + // Check for actor + WordType wordType = getWordType(_words.front()); + if (wordType == WT_ADJECTIVE || wordType == WT_NOUN) { + if (!(_actor = getNoun())) + return false; + flag |= A_ACTOR; + } + // TODO: stub return false; } @@ -475,6 +483,7 @@ bool VM::getLine() { return false; } + _wordPtr = _words.begin(); return true; } @@ -505,6 +514,50 @@ bool VM::getWord(Common::String &line) { } } +bool VM::getNoun() { + // TODO: Stub + return false; +} + +bool VM::getVerb() { + _verbs.clear(); + + if (_words.front() == NIL || getWordType(_words.front()) != WT_VERB) { + parseError(); + return false; + } + + _verbs.push_back(*_wordPtr++); + + // Check for a word following the verb + if (!_words.empty()) { + _verbs.push_back(_words.front()); + + if (checkVerb(_verbs)) { + ++_wordPtr; + } else { + _verbs.push_back(_words.back()); + + if (checkVerb(_verbs)) { + _words.pop_back(); + } else { + _verbs.pop_back(); + + if (!checkVerb(_verbs)) { + parseError(); + return false; + } + } + } + } + + return true; +} + +void VM::parseError() { + // TODO +} + bool VM::isWhitespace(char c) { return c == ' ' || c == ',' || c == '.'; } diff --git a/engines/glk/advsys/vm.h b/engines/glk/advsys/vm.h index d235bd878d..d3b7bfc8f6 100644 --- a/engines/glk/advsys/vm.h +++ b/engines/glk/advsys/vm.h @@ -113,6 +113,16 @@ enum FPOffset { FP_ARGS = 3 }; +/** + * Action flags + */ +enum ActionFlag { + A_ACTOR = 1, ///< Actor + A_DOBJECT = 2, ///< Direct object + A_IOBJECT = 4 ///< Indirect object +}; + + class VM; typedef void (VM::*OpcodeMethod)(); @@ -192,6 +202,7 @@ class VM : public GlkInterface, public Game { int _number; InputWord() : _number(0) {} + operator int() const { return _number; } }; private: // Execution fields @@ -213,7 +224,8 @@ private: int _ndObjects; int _iObject; Common::Array<InputWord> _words; - InputWord *_wordPtr; + Common::Array<InputWord>::iterator _wordPtr; + Common::Array<int> _verbs; private: /** * Execute a single opcode within the script @@ -252,6 +264,21 @@ private: bool getWord(Common::String &line); /** + * Get a noun phrase and return the object it refers to + */ + bool getNoun(); + + /** + * Get a verb phrase and return the action it refers to + */ + bool getVerb(); + + /** + * Called when a parsing error occurs + */ + void parseError(); + + /** * Returns true if a passed character is a skippable whitespace */ static bool isWhitespace(char c); |