GLK: ADVSYS: In progress implementing input line parser
This commit is contained in:
parent
4e74751e7e
commit
9efb6d71e2
4 changed files with 106 additions and 13 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,19 @@ enum Action {
|
|||
A_SIZE = 8
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
@ -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
|
||||
|
|
|
@ -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 == '.';
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -251,6 +263,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
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue