diff options
Diffstat (limited to 'engines/glk/alan3/parse.cpp')
-rw-r--r-- | engines/glk/alan3/parse.cpp | 1684 |
1 files changed, 853 insertions, 831 deletions
diff --git a/engines/glk/alan3/parse.cpp b/engines/glk/alan3/parse.cpp index a1967e6a60..f04b91040c 100644 --- a/engines/glk/alan3/parse.cpp +++ b/engines/glk/alan3/parse.cpp @@ -52,13 +52,13 @@ namespace Alan3 { /* PRIVATE TYPES */ /* To remember parameter/pronoun relations */ struct Pronoun { - int pronoun; - int instance; + int pronoun; + int instance; }; /*----------------------------------------------------------------------*/ static void clearPronounList(Pronoun list[]) { - implementationOfSetEndOfArray((Aword *)list); + implementationOfSetEndOfArray((Aword *)list); } @@ -82,284 +82,284 @@ static Parameter *previousMultipleParameters; /* Previous multiple list */ /*----------------------------------------------------------------------*/ static void addParameterForWord(Parameter *parameters, int wordIndex) { - Parameter *parameter = findEndOfParameterArray(parameters); + Parameter *parameter = findEndOfParameterArray(parameters); - createStringLiteral((char *)pointerTo(dictionary[playerWords[wordIndex].code].string)); - parameter->instance = instanceFromLiteral(litCount); /* A faked literal */ - parameter->useWords = TRUE; - parameter->firstWord = parameter->lastWord = wordIndex; - setEndOfArray(parameter+1); + createStringLiteral((char *)pointerTo(dictionary[playerWords[wordIndex].code].string)); + parameter->instance = instanceFromLiteral(litCount); /* A faked literal */ + parameter->useWords = TRUE; + parameter->firstWord = parameter->lastWord = wordIndex; + setEndOfArray(parameter + 1); } /*----------------------------------------------------------------------*/ static Pronoun *allocatePronounArray(Pronoun *currentList) { - if (currentList == NULL) - currentList = (Pronoun *)allocate(sizeof(Pronoun)*(MAXPARAMS+1)); - clearPronounList(currentList); - return currentList; + if (currentList == NULL) + currentList = (Pronoun *)allocate(sizeof(Pronoun) * (MAXPARAMS + 1)); + clearPronounList(currentList); + return currentList; } /*----------------------------------------------------------------------*/ static bool endOfWords(int wordIndex) { - return isEndOfArray(&playerWords[wordIndex]); + return isEndOfArray(&playerWords[wordIndex]); } /*----------------------------------------------------------------------*/ static void handleDirectionalCommand() { - currentWordIndex++; - if (!endOfWords(currentWordIndex) && !isConjunctionWord(currentWordIndex)) - error(M_WHAT); - else - go(current.location, dictionary[playerWords[currentWordIndex-1].code].code); - if (!endOfWords(currentWordIndex)) - currentWordIndex++; + currentWordIndex++; + if (!endOfWords(currentWordIndex) && !isConjunctionWord(currentWordIndex)) + error(M_WHAT); + else + go(current.location, dictionary[playerWords[currentWordIndex - 1].code].code); + if (!endOfWords(currentWordIndex)) + currentWordIndex++; } /*----------------------------------------------------------------------*/ static void errorWhichOne(Parameter alternative[]) { - int p; /* Index into the list of alternatives */ - ParameterArray parameters = newParameterArray(); - - parameters[0] = alternative[0]; - setEndOfArray(¶meters[1]); - printMessageWithParameters(M_WHICH_ONE_START, parameters); - for (p = 1; !isEndOfArray(&alternative[p+1]); p++) { - clearParameterArray(parameters); - addParameterToParameterArray(parameters, &alternative[p]); - printMessageWithParameters(M_WHICH_ONE_COMMA, parameters); - } - clearParameterArray(parameters); - addParameterToParameterArray(parameters, &alternative[p]); - printMessageWithParameters(M_WHICH_ONE_OR, parameters); - freeParameterArray(parameters); - abortPlayerCommand(); /* Return with empty error message */ + int p; /* Index into the list of alternatives */ + ParameterArray parameters = newParameterArray(); + + parameters[0] = alternative[0]; + setEndOfArray(¶meters[1]); + printMessageWithParameters(M_WHICH_ONE_START, parameters); + for (p = 1; !isEndOfArray(&alternative[p + 1]); p++) { + clearParameterArray(parameters); + addParameterToParameterArray(parameters, &alternative[p]); + printMessageWithParameters(M_WHICH_ONE_COMMA, parameters); + } + clearParameterArray(parameters); + addParameterToParameterArray(parameters, &alternative[p]); + printMessageWithParameters(M_WHICH_ONE_OR, parameters); + freeParameterArray(parameters); + abortPlayerCommand(); /* Return with empty error message */ } /*----------------------------------------------------------------------*/ static void errorWhichPronoun(int pronounWordIndex, Parameter alternatives[]) { - int p; /* Index into the list of alternatives */ - Parameter *messageParameters = newParameterArray(); + int p; /* Index into the list of alternatives */ + Parameter *messageParameters = newParameterArray(); - addParameterForWord(messageParameters, pronounWordIndex); - printMessageWithParameters(M_WHICH_PRONOUN_START, messageParameters); + addParameterForWord(messageParameters, pronounWordIndex); + printMessageWithParameters(M_WHICH_PRONOUN_START, messageParameters); - clearParameterArray(messageParameters); - addParameterToParameterArray(messageParameters, &alternatives[0]); + clearParameterArray(messageParameters); + addParameterToParameterArray(messageParameters, &alternatives[0]); - printMessageWithParameters(M_WHICH_PRONOUN_FIRST, messageParameters); + printMessageWithParameters(M_WHICH_PRONOUN_FIRST, messageParameters); - for (p = 1; !isEndOfArray(&alternatives[p+1]); p++) { - clearParameterArray(messageParameters); - addParameterToParameterArray(messageParameters, &alternatives[p]); - printMessageWithParameters(M_WHICH_ONE_COMMA, messageParameters); - } - clearParameterArray(messageParameters); - addParameterToParameterArray(messageParameters, &alternatives[p]); - printMessageWithParameters(M_WHICH_ONE_OR, messageParameters); - freeParameterArray(messageParameters); - abortPlayerCommand(); + for (p = 1; !isEndOfArray(&alternatives[p + 1]); p++) { + clearParameterArray(messageParameters); + addParameterToParameterArray(messageParameters, &alternatives[p]); + printMessageWithParameters(M_WHICH_ONE_COMMA, messageParameters); + } + clearParameterArray(messageParameters); + addParameterToParameterArray(messageParameters, &alternatives[p]); + printMessageWithParameters(M_WHICH_ONE_OR, messageParameters); + freeParameterArray(messageParameters); + abortPlayerCommand(); } /*----------------------------------------------------------------------*/ static void errorWhat(int playerWordIndex) { - Parameter *messageParameters = newParameterArray(); + Parameter *messageParameters = newParameterArray(); - addParameterForWord(messageParameters, playerWordIndex); - printMessageWithParameters(M_WHAT_WORD, messageParameters); - freeParameterArray(messageParameters); - abortPlayerCommand(); + addParameterForWord(messageParameters, playerWordIndex); + printMessageWithParameters(M_WHAT_WORD, messageParameters); + freeParameterArray(messageParameters); + abortPlayerCommand(); } /*----------------------------------------------------------------------*/ static void errorAfterExcept(int butWordIndex) { - Parameter *messageParameters = newParameterArray(); - addParameterForWord(messageParameters, butWordIndex); - printMessageWithParameters(M_AFTER_BUT, messageParameters); - freeParameterArray(messageParameters); - abortPlayerCommand(); + Parameter *messageParameters = newParameterArray(); + addParameterForWord(messageParameters, butWordIndex); + printMessageWithParameters(M_AFTER_BUT, messageParameters); + freeParameterArray(messageParameters); + abortPlayerCommand(); } /*----------------------------------------------------------------------*/ static int fakePlayerWordForAll() { - /* Look through the dictionary and find any ALL_WORD, then add a - player word so that it can be used in the message */ - int p, d; + /* Look through the dictionary and find any ALL_WORD, then add a + player word so that it can be used in the message */ + int p, d; - for (p = 0; !isEndOfArray(&playerWords[p]); p++) - ; - setEndOfArray(&playerWords[p+1]); /* Make room for one more word */ - for (d = 0; d < dictionarySize; d++) - if (isAll(d)) { - playerWords[p].code = d; - return p; - } - syserr("No ALLWORD found"); - return 0; + for (p = 0; !isEndOfArray(&playerWords[p]); p++) + ; + setEndOfArray(&playerWords[p + 1]); /* Make room for one more word */ + for (d = 0; d < dictionarySize; d++) + if (isAll(d)) { + playerWords[p].code = d; + return p; + } + syserr("No ALLWORD found"); + return 0; } /*----------------------------------------------------------------------*/ static void errorButAfterAll(int butWordIndex) { - Parameter *messageParameters = newParameterArray(); - addParameterForWord(messageParameters, butWordIndex); - addParameterForWord(messageParameters, fakePlayerWordForAll()); - printMessageWithParameters(M_BUT_ALL, messageParameters); - freeParameterArray(messageParameters); - abortPlayerCommand(); + Parameter *messageParameters = newParameterArray(); + addParameterForWord(messageParameters, butWordIndex); + addParameterForWord(messageParameters, fakePlayerWordForAll()); + printMessageWithParameters(M_BUT_ALL, messageParameters); + freeParameterArray(messageParameters); + abortPlayerCommand(); } /*----------------------------------------------------------------------*/ static Aint findInstanceForNoun(int wordIndex) { - DictionaryEntry *d = &dictionary[wordIndex]; - if (d->nounRefs == 0 || d->nounRefs == EOD) - syserr("No references for noun"); - return *(Aint*) pointerTo(d->nounRefs); + DictionaryEntry *d = &dictionary[wordIndex]; + if (d->nounRefs == 0 || d->nounRefs == EOD) + syserr("No references for noun"); + return *(Aint *) pointerTo(d->nounRefs); } /*----------------------------------------------------------------------*/ static void errorNoSuch(Parameter parameter) { - /* If there was no instance, assume the last word used is the noun, - * then find any instance with the noun he used */ - if (parameter.instance == (Aid)-1) - parameter.instance = 0; - if (parameter.instance == 0) - parameter.instance = findInstanceForNoun(playerWords[parameter.lastWord].code); - parameter.useWords = TRUE; /* Indicate to use words and not names */ + /* If there was no instance, assume the last word used is the noun, + * then find any instance with the noun he used */ + if (parameter.instance == (Aid) - 1) + parameter.instance = 0; + if (parameter.instance == 0) + parameter.instance = findInstanceForNoun(playerWords[parameter.lastWord].code); + parameter.useWords = TRUE; /* Indicate to use words and not names */ - clearParameterArray(globalParameters); - addParameterToParameterArray(globalParameters, ¶meter); - error(M_NO_SUCH); + clearParameterArray(globalParameters); + addParameterToParameterArray(globalParameters, ¶meter); + error(M_NO_SUCH); } /*----------------------------------------------------------------------*/ static void buildAllHere(Parameter list[]) { - uint instance; - bool found = FALSE; - int word = list[0].firstWord; + uint instance; + bool found = FALSE; + int word = list[0].firstWord; - for (instance = 1; instance <= header->instanceMax; instance++) - if (isHere(instance, /*FALSE*/ TRANSITIVE)) { - Parameter *parameter = newParameter(instance); - addParameterToParameterArray(list, parameter); - deallocate(parameter); - found = TRUE; - } - if (!found) - errorWhat(word); + for (instance = 1; instance <= header->instanceMax; instance++) + if (isHere(instance, /*FALSE*/ TRANSITIVE)) { + Parameter *parameter = newParameter(instance); + addParameterToParameterArray(list, parameter); + deallocate(parameter); + found = TRUE; + } + if (!found) + errorWhat(word); } /*----------------------------------------------------------------------*/ static bool endOfPronouns(int pronounIndex) { - return isEndOfArray(&pronouns[pronounIndex]); + return isEndOfArray(&pronouns[pronounIndex]); } /*----------------------------------------------------------------------*/ static int getPronounInstances(int word, Parameter instanceParameters[]) { - /* Find the instance that the pronoun word could refer to, return 0 - if none or multiple */ - int p; - int instanceCount = 0; - - clearParameterArray(instanceParameters); - for (p = 0; !endOfPronouns(p); p++) - if (pronouns[p].instance != 0 && dictionary[word].code == (Aword)pronouns[p].pronoun) { - instanceParameters[instanceCount].instance = pronouns[p].instance; - instanceParameters[instanceCount].useWords = FALSE; /* Can't use words since they are gone, pronouns + /* Find the instance that the pronoun word could refer to, return 0 + if none or multiple */ + int p; + int instanceCount = 0; + + clearParameterArray(instanceParameters); + for (p = 0; !endOfPronouns(p); p++) + if (pronouns[p].instance != 0 && dictionary[word].code == (Aword)pronouns[p].pronoun) { + instanceParameters[instanceCount].instance = pronouns[p].instance; + instanceParameters[instanceCount].useWords = FALSE; /* Can't use words since they are gone, pronouns refer to parameters in previous command */ - setEndOfArray(&instanceParameters[++instanceCount]); - } - return instanceCount; + setEndOfArray(&instanceParameters[++instanceCount]); + } + return instanceCount; } /*----------------------------------------------------------------------*/ static bool inOpaqueContainer(int originalInstance) { - int instance = admin[originalInstance].location; + int instance = admin[originalInstance].location; - while (isAContainer(instance)) { - // TODO : isOpaque() - if (getInstanceAttribute(instance, OPAQUEATTRIBUTE)) - return TRUE; - instance = admin[instance].location; - } - return FALSE; + while (isAContainer(instance)) { + // TODO : isOpaque() + if (getInstanceAttribute(instance, OPAQUEATTRIBUTE)) + return TRUE; + instance = admin[instance].location; + } + return FALSE; } /*----------------------------------------------------------------------*/ static bool reachable(int instance) { - if (isA(instance, THING) || isA(instance, LOCATION)) - return isHere(instance, TRANSITIVE) && !inOpaqueContainer(instance); - else - return TRUE; + if (isA(instance, THING) || isA(instance, LOCATION)) + return isHere(instance, TRANSITIVE) && !inOpaqueContainer(instance); + else + return TRUE; } /*----------------------------------------------------------------------*/ static Aint *nounReferencesForWord(int wordIndex) { - return (Aint *) pointerTo(dictionary[playerWords[wordIndex].code].nounRefs); + return (Aint *) pointerTo(dictionary[playerWords[wordIndex].code].nounRefs); } /*----------------------------------------------------------------------*/ static Aint *adjectiveReferencesForWord(int wordIndex) { - return (Aint *) pointerTo(dictionary[playerWords[wordIndex].code].adjectiveRefs); + return (Aint *) pointerTo(dictionary[playerWords[wordIndex].code].adjectiveRefs); } /*----------------------------------------------------------------------*/ static void parseLiteral(Parameter parameters[]) { - parameters[0].firstWord = parameters[0].lastWord = currentWordIndex++; - parameters[0].instance = 0; - parameters[0].isLiteral = TRUE; - setEndOfArray(¶meters[1]); + parameters[0].firstWord = parameters[0].lastWord = currentWordIndex++; + parameters[0].instance = 0; + parameters[0].isLiteral = TRUE; + setEndOfArray(¶meters[1]); } /*----------------------------------------------------------------------*/ static void parsePronoun(Parameter parameters[]) { - parameters[0].firstWord = parameters[0].lastWord = currentWordIndex++; - parameters[0].instance = 0; - parameters[0].isPronoun = TRUE; - setEndOfArray(¶meters[1]); + parameters[0].firstWord = parameters[0].lastWord = currentWordIndex++; + parameters[0].instance = 0; + parameters[0].isPronoun = TRUE; + setEndOfArray(¶meters[1]); } /*----------------------------------------------------------------------*/ static bool anotherAdjective(int wordIndex) { - return !endOfWords(wordIndex) && isAdjectiveWord(wordIndex); + return !endOfWords(wordIndex) && isAdjectiveWord(wordIndex); } /*----------------------------------------------------------------------*/ static bool lastPossibleNoun(int wordIndex) { - return isNounWord(wordIndex) && (endOfWords(wordIndex+1) || !isNounWord(wordIndex+1)); + return isNounWord(wordIndex) && (endOfWords(wordIndex + 1) || !isNounWord(wordIndex + 1)); } /*----------------------------------------------------------------------*/ -static void updateWithReferences(Parameter result[], int wordIndex, Aint *(*referenceFinder)(int wordIndex)) { - static Parameter *references = NULL; /* Instances referenced by a word */ - references = ensureParameterArrayAllocated(references); +static void updateWithReferences(Parameter result[], int wordIndex, Aint * (*referenceFinder)(int wordIndex)) { + static Parameter *references = NULL; /* Instances referenced by a word */ + references = ensureParameterArrayAllocated(references); - copyReferencesToParameterArray(referenceFinder(wordIndex), references); - if (lengthOfParameterArray(result) == 0) - copyParameterArray(result, references); - else - intersectParameterArrays(result, references); + copyReferencesToParameterArray(referenceFinder(wordIndex), references); + if (lengthOfParameterArray(result) == 0) + copyParameterArray(result, references); + else + intersectParameterArrays(result, references); } /*----------------------------------------------------------------------*/ static void filterOutNonReachable(Parameter filteredCandidates[], bool (*reachable)(int)) { - int i; - for (i = 0; !isEndOfArray(&filteredCandidates[i]); i++) - if (!reachable(filteredCandidates[i].instance)) - filteredCandidates[i].instance = 0; - compressParameterArray(filteredCandidates); + int i; + for (i = 0; !isEndOfArray(&filteredCandidates[i]); i++) + if (!reachable(filteredCandidates[i].instance)) + filteredCandidates[i].instance = 0; + compressParameterArray(filteredCandidates); } @@ -376,33 +376,33 @@ static void filterOutNonReachable(Parameter filteredCandidates[], bool (*reachab /*----------------------------------------------------------------------*/ static void disambiguateCandidatesForPosition(ParameterPosition parameterPositions[], int position, Parameter candidates[]) { - int i; - Parameter *parameters = newParameterArray(); - - convertPositionsToParameters(parameterPositions, parameters); - for (i = 0; !isEndOfArray(&candidates[i]); i++) { - if (candidates[i].instance != 0) { /* Already empty? */ - copyParameter(¶meters[position], &candidates[i]); - // DISAMBIGUATION!! - if (!reachable(candidates[i].instance) || !possible(current.verb, parameters, parameterPositions)) - candidates[i].instance = 0; /* Then remove this candidate from list */ - } - } - compressParameterArray(candidates); - freeParameterArray(parameters); + int i; + Parameter *parameters = newParameterArray(); + + convertPositionsToParameters(parameterPositions, parameters); + for (i = 0; !isEndOfArray(&candidates[i]); i++) { + if (candidates[i].instance != 0) { /* Already empty? */ + copyParameter(¶meters[position], &candidates[i]); + // DISAMBIGUATION!! + if (!reachable(candidates[i].instance) || !possible(current.verb, parameters, parameterPositions)) + candidates[i].instance = 0; /* Then remove this candidate from list */ + } + } + compressParameterArray(candidates); + freeParameterArray(parameters); } /*----------------------------------------------------------------------*/ static bool parseAnyAdjectives(Parameter parameters[]) { - bool adjectiveOrNounFound = FALSE; - while (anotherAdjective(currentWordIndex)) { - if (lastPossibleNoun(currentWordIndex)) - break; - adjectiveOrNounFound = TRUE; - currentWordIndex++; - } - return adjectiveOrNounFound; + bool adjectiveOrNounFound = FALSE; + while (anotherAdjective(currentWordIndex)) { + if (lastPossibleNoun(currentWordIndex)) + break; + adjectiveOrNounFound = TRUE; + currentWordIndex++; + } + return adjectiveOrNounFound; } @@ -410,102 +410,102 @@ static bool parseAnyAdjectives(Parameter parameters[]) { /* Parse the input and note the word indices in the parameters, matching will be done by the match* functions */ static void parseAdjectivesAndNoun(Parameter parameters[]) { - int wordFirst, wordLast; - bool adjectiveOrNounFound = FALSE; - - wordFirst = currentWordIndex; - - adjectiveOrNounFound = parseAnyAdjectives(parameters); - - if (!endOfWords(currentWordIndex)) { - if (isNounWord(currentWordIndex)) { - adjectiveOrNounFound = TRUE; - currentWordIndex++; - } else - error(M_NOUN); - } else if (adjectiveOrNounFound) { - /* Perhaps the last word could also be interpreted as a noun? */ - if (isNounWord(currentWordIndex - 1)) { - // TODO When does this get executed? Maybe if conjunctions can be nouns? Or nouns be adjectives? - printf("DEBUG: When does this get executed? Found adjective or Noun and the previous word could also be a noun...\n"); - } else - error(M_NOUN); - } - - if (adjectiveOrNounFound) { + int wordFirst, wordLast; + bool adjectiveOrNounFound = FALSE; + + wordFirst = currentWordIndex; + + adjectiveOrNounFound = parseAnyAdjectives(parameters); + + if (!endOfWords(currentWordIndex)) { + if (isNounWord(currentWordIndex)) { + adjectiveOrNounFound = TRUE; + currentWordIndex++; + } else + error(M_NOUN); + } else if (adjectiveOrNounFound) { + /* Perhaps the last word could also be interpreted as a noun? */ + if (isNounWord(currentWordIndex - 1)) { + // TODO When does this get executed? Maybe if conjunctions can be nouns? Or nouns be adjectives? + printf("DEBUG: When does this get executed? Found adjective or Noun and the previous word could also be a noun...\n"); + } else + error(M_NOUN); + } + + if (adjectiveOrNounFound) { wordLast = currentWordIndex - 1; - parameters[0].firstWord = wordFirst; - parameters[0].lastWord = wordLast; - parameters[0].instance = 0; /* No instance yet! */ - setEndOfArray(¶meters[1]); - } else - setEndOfArray(¶meters[0]); + parameters[0].firstWord = wordFirst; + parameters[0].lastWord = wordLast; + parameters[0].instance = 0; /* No instance yet! */ + setEndOfArray(¶meters[1]); + } else + setEndOfArray(¶meters[0]); } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ static void parseReference(Parameter parameters[]) { - clearParameterArray(parameters); + clearParameterArray(parameters); - if (isLiteralWord(currentWordIndex)) { - parseLiteral(parameters); - } else if (isPronounWord(currentWordIndex)) { - parsePronoun(parameters); - } else { - parseAdjectivesAndNoun(parameters); - } + if (isLiteralWord(currentWordIndex)) { + parseLiteral(parameters); + } else if (isPronounWord(currentWordIndex)) { + parsePronoun(parameters); + } else { + parseAdjectivesAndNoun(parameters); + } } /*----------------------------------------------------------------------*/ static void getPreviousMultipleParameters(Parameter parameters[]) { - int i; - for (i = 0; !isEndOfArray(&previousMultipleParameters[i]); i++) { - parameters[i].candidates = ensureParameterArrayAllocated(parameters[i].candidates); - setEndOfArray(¶meters[i].candidates[0]); /* No candidates */ - if (!reachable(previousMultipleParameters[i].instance)) - parameters[i].instance = 0; - else - parameters[i].instance = previousMultipleParameters[i].instance; - } - setEndOfArray(¶meters[i]); - compressParameterArray(parameters); + int i; + for (i = 0; !isEndOfArray(&previousMultipleParameters[i]); i++) { + parameters[i].candidates = ensureParameterArrayAllocated(parameters[i].candidates); + setEndOfArray(¶meters[i].candidates[0]); /* No candidates */ + if (!reachable(previousMultipleParameters[i].instance)) + parameters[i].instance = 0; + else + parameters[i].instance = previousMultipleParameters[i].instance; + } + setEndOfArray(¶meters[i]); + compressParameterArray(parameters); } /*----------------------------------------------------------------------*/ static void parseReferenceToPreviousMultipleParameters(Parameter parameters[]) { - parameters[0].firstWord = parameters[0].lastWord = currentWordIndex++; - parameters[0].instance = 0; - parameters[0].isThem = TRUE; - setEndOfArray(¶meters[1]); + parameters[0].firstWord = parameters[0].lastWord = currentWordIndex++; + parameters[0].instance = 0; + parameters[0].isThem = TRUE; + setEndOfArray(¶meters[1]); } /*----------------------------------------------------------------------*/ static bool parseOneParameter(Parameter parameters[], int parameterIndex) { - Parameter *parameter = newParameterArray(); - - // TODO Maybe this should go in the complex()? - if (isThemWord(currentWordIndex) && (!isPronounWord(currentWordIndex) || - (isPronounWord(currentWordIndex) && lengthOfParameterArray(previousMultipleParameters) > 0))) { - // "them" is also a common pronoun for some instances, but if there - // are previous multiple parameters we give precedence to those - parseReferenceToPreviousMultipleParameters(parameter); - } else { - parseReference(parameter); - if (lengthOfParameterArray(parameter) == 0) { /* Failed to find any exceptions! */ - freeParameterArray(parameter); - return FALSE; - } - } - - /* Add the one we found to the parameters */ - parameters[parameterIndex] = parameter[0]; - setEndOfArray(¶meters[parameterIndex+1]); - freeParameterArray(parameter); - return TRUE; + Parameter *parameter = newParameterArray(); + + // TODO Maybe this should go in the complex()? + if (isThemWord(currentWordIndex) && (!isPronounWord(currentWordIndex) || + (isPronounWord(currentWordIndex) && lengthOfParameterArray(previousMultipleParameters) > 0))) { + // "them" is also a common pronoun for some instances, but if there + // are previous multiple parameters we give precedence to those + parseReferenceToPreviousMultipleParameters(parameter); + } else { + parseReference(parameter); + if (lengthOfParameterArray(parameter) == 0) { /* Failed to find any exceptions! */ + freeParameterArray(parameter); + return FALSE; + } + } + + /* Add the one we found to the parameters */ + parameters[parameterIndex] = parameter[0]; + setEndOfArray(¶meters[parameterIndex + 1]); + freeParameterArray(parameter); + return TRUE; } @@ -530,34 +530,34 @@ static bool parseOneParameter(Parameter parameters[], int parameterIndex) { /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ static void simpleParameterParser(Parameter parameters[]) { - /* This will loop until all references are collected (typically "a and b and c") */ - int parameterIndex; - for (parameterIndex = 0;; parameterIndex++) { - - if(!parseOneParameter(parameters, parameterIndex)) - return; - - if (!endOfWords(currentWordIndex) - && (isConjunctionWord(currentWordIndex) && (isAdjectiveWord(currentWordIndex+1) - || isNounWord(currentWordIndex+1)))) { - /* Since this is a conjunction and the next seems to be another instance reference, - let's continue with that by eating the conjunction */ - currentWordIndex++; - } else { - return; - } - } + /* This will loop until all references are collected (typically "a and b and c") */ + int parameterIndex; + for (parameterIndex = 0;; parameterIndex++) { + + if (!parseOneParameter(parameters, parameterIndex)) + return; + + if (!endOfWords(currentWordIndex) + && (isConjunctionWord(currentWordIndex) && (isAdjectiveWord(currentWordIndex + 1) + || isNounWord(currentWordIndex + 1)))) { + /* Since this is a conjunction and the next seems to be another instance reference, + let's continue with that by eating the conjunction */ + currentWordIndex++; + } else { + return; + } + } } /*----------------------------------------------------------------------*/ static void parseExceptions(ParameterPosition *parameterPosition, ParameterParser simpleParameterParser) { - int exceptWordIndex = currentWordIndex; - currentWordIndex++; - parameterPosition->exceptions = ensureParameterArrayAllocated(parameterPosition->exceptions); - simpleParameterParser(parameterPosition->exceptions); - if (lengthOfParameterArray(parameterPosition->exceptions) == 0) - errorAfterExcept(exceptWordIndex); + int exceptWordIndex = currentWordIndex; + currentWordIndex++; + parameterPosition->exceptions = ensureParameterArrayAllocated(parameterPosition->exceptions); + simpleParameterParser(parameterPosition->exceptions); + if (lengthOfParameterArray(parameterPosition->exceptions) == 0) + errorAfterExcept(exceptWordIndex); } @@ -573,130 +573,130 @@ static void parseExceptions(ParameterPosition *parameterPosition, ParameterParse /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ static void complexParameterParserDelegate(ParameterPosition *parameterPosition, ParameterParser simpleParameterParser) { - parameterPosition->parameters = ensureParameterArrayAllocated(parameterPosition->parameters); - - parameterPosition->all = FALSE; - parameterPosition->them = FALSE; - parameterPosition->explicitMultiple = FALSE; - - if (isAllWord(currentWordIndex)) { - parameterPosition->all = TRUE; - parameterPosition->explicitMultiple = TRUE; - parameterPosition->parameters[0].firstWord = currentWordIndex; - parameterPosition->parameters[0].lastWord = currentWordIndex; - currentWordIndex++; - parameterPosition->parameters[0].instance = 0; - setEndOfArray(¶meterPosition->parameters[1]); - if (!endOfWords(currentWordIndex) && isExceptWord(currentWordIndex)) - parseExceptions(parameterPosition, simpleParameterParser); - } else { - simpleParameterParser(parameterPosition->parameters); - if (lengthOfParameterArray(parameterPosition->parameters) > 1) - parameterPosition->explicitMultiple = TRUE; - } + parameterPosition->parameters = ensureParameterArrayAllocated(parameterPosition->parameters); + + parameterPosition->all = FALSE; + parameterPosition->them = FALSE; + parameterPosition->explicitMultiple = FALSE; + + if (isAllWord(currentWordIndex)) { + parameterPosition->all = TRUE; + parameterPosition->explicitMultiple = TRUE; + parameterPosition->parameters[0].firstWord = currentWordIndex; + parameterPosition->parameters[0].lastWord = currentWordIndex; + currentWordIndex++; + parameterPosition->parameters[0].instance = 0; + setEndOfArray(¶meterPosition->parameters[1]); + if (!endOfWords(currentWordIndex) && isExceptWord(currentWordIndex)) + parseExceptions(parameterPosition, simpleParameterParser); + } else { + simpleParameterParser(parameterPosition->parameters); + if (lengthOfParameterArray(parameterPosition->parameters) > 1) + parameterPosition->explicitMultiple = TRUE; + } } /*----------------------------------------------------------------------*/ static void complexReferencesParser(ParameterPosition *parameterPosition) { - complexParameterParserDelegate(parameterPosition, simpleParameterParser); + complexParameterParserDelegate(parameterPosition, simpleParameterParser); } /*----------------------------------------------------------------------*/ static char *classNameAndId(int classId) { - static char buffer[1000] = ""; + static char buffer[1000] = ""; - if (classId != -1) - sprintf(buffer, "%s[%d]", idOfClass(classId), classId); - else - sprintf(buffer, "Container"); - return buffer; + if (classId != -1) + sprintf(buffer, "%s[%d]", idOfClass(classId), classId); + else + sprintf(buffer, "Container"); + return buffer; } /*----------------------------------------------------------------------*/ static char *parameterNumberAndName(int parameterNumber) { - static char buffer[1000] = ""; - /* HERE SHOULD BE current.syntax */ + static char buffer[1000] = ""; + /* HERE SHOULD BE current.syntax */ char *parameterName = parameterNameInSyntax(current.syntax, parameterNumber); - if (parameterName != NULL) - sprintf(buffer, "%s(#%d)", parameterName, parameterNumber); - else - sprintf(buffer, "#%d", parameterNumber); - return buffer; + if (parameterName != NULL) + sprintf(buffer, "%s(#%d)", parameterName, parameterNumber); + else + sprintf(buffer, "#%d", parameterNumber); + return buffer; } /*----------------------------------------------------------------------*/ static void traceRestriction(RestrictionEntry *restriction, int classId, bool condition) { - printf("\n<SYNTAX RESTRICTION WHERE parameter %s Isa %s, %s>\n", - parameterNumberAndName(restriction->parameterNumber), - classNameAndId(classId), condition?"PASSED":"FAILED:"); + printf("\n<SYNTAX RESTRICTION WHERE parameter %s Isa %s, %s>\n", + parameterNumberAndName(restriction->parameterNumber), + classNameAndId(classId), condition ? "PASSED" : "FAILED:"); } /*----------------------------------------------------------------------*/ static bool restrictionCheck(RestrictionEntry *restriction, int instance) { - if (restriction->_class == RESTRICTIONCLASS_CONTAINER) { - if (traceSectionOption) - traceRestriction(restriction, -1, isAContainer(instance)); - return isAContainer(instance); - } else { - if (traceSectionOption) - traceRestriction(restriction, restriction->_class, isA(instance, restriction->_class)); - return isA(instance, restriction->_class); - } + if (restriction->_class == RESTRICTIONCLASS_CONTAINER) { + if (traceSectionOption) + traceRestriction(restriction, -1, isAContainer(instance)); + return isAContainer(instance); + } else { + if (traceSectionOption) + traceRestriction(restriction, restriction->_class, isA(instance, restriction->_class)); + return isA(instance, restriction->_class); + } } /*----------------------------------------------------------------------*/ static void runRestriction(RestrictionEntry *restriction, Parameter parameters[]) { - if (restriction->stms) { - setGlobalParameters(parameters); - interpret(restriction->stms); - } else - error(M_CANT0); + if (restriction->stms) { + setGlobalParameters(parameters); + interpret(restriction->stms); + } else + error(M_CANT0); } /*----------------------------------------------------------------------*/ static int remapParameterOrder(int syntaxNumber, ParameterPosition parameterPositions[]) { - /* Find the syntax map, use the verb code from it and remap the parameters */ - ParameterMapEntry *parameterMapTable; - Aword *parameterMap; - Aint parameterNumber; + /* Find the syntax map, use the verb code from it and remap the parameters */ + ParameterMapEntry *parameterMapTable; + Aword *parameterMap; + Aint parameterNumber; Common::Array<ParameterPosition> savedParameterPositions; savedParameterPositions.resize(MAXPARAMS + 1); - for (parameterMapTable = (ParameterMapEntry *)pointerTo(header->parameterMapAddress); !isEndOfArray(parameterMapTable); parameterMapTable++) - if (parameterMapTable->syntaxNumber == syntaxNumber) - break; - if (isEndOfArray(parameterMapTable)) - syserr("Could not find syntax in mapping table."); + for (parameterMapTable = (ParameterMapEntry *)pointerTo(header->parameterMapAddress); !isEndOfArray(parameterMapTable); parameterMapTable++) + if (parameterMapTable->syntaxNumber == syntaxNumber) + break; + if (isEndOfArray(parameterMapTable)) + syserr("Could not find syntax in mapping table."); - parameterMap = (Aword *)pointerTo(parameterMapTable->parameterMapping); + parameterMap = (Aword *)pointerTo(parameterMapTable->parameterMapping); - copyParameterPositions(parameterPositions, &savedParameterPositions[0]); + copyParameterPositions(parameterPositions, &savedParameterPositions[0]); - for (parameterNumber = 1; !savedParameterPositions[parameterNumber-1].endOfList; parameterNumber++) { - parameterPositions[parameterNumber-1] = savedParameterPositions[parameterMap[parameterNumber-1]-1]; - } + for (parameterNumber = 1; !savedParameterPositions[parameterNumber - 1].endOfList; parameterNumber++) { + parameterPositions[parameterNumber - 1] = savedParameterPositions[parameterMap[parameterNumber - 1] - 1]; + } - return parameterMapTable->verbCode; + return parameterMapTable->verbCode; } /*----------------------------------------------------------------------*/ static bool hasBit(Aword flags, Aint bit) { - return (flags & bit) != 0; + return (flags & bit) != 0; } /*----------------------------------------------------------------------*/ static bool multipleAllowed(Aword flags) { - return hasBit(flags, MULTIPLEBIT); + return hasBit(flags, MULTIPLEBIT); } @@ -723,179 +723,179 @@ static bool multipleAllowed(Aword flags) { /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ static void parseParameterPosition(ParameterPosition *parameterPosition, Aword flags, void (*complexReferencesParser)(ParameterPosition *parameterPosition)) { - parameterPosition->parameters = ensureParameterArrayAllocated(parameterPosition->parameters); + parameterPosition->parameters = ensureParameterArrayAllocated(parameterPosition->parameters); - complexReferencesParser(parameterPosition); - if (lengthOfParameterArray(parameterPosition->parameters) == 0) /* No object!? */ - error(M_WHAT); + complexReferencesParser(parameterPosition); + if (lengthOfParameterArray(parameterPosition->parameters) == 0) /* No object!? */ + error(M_WHAT); - if (parameterPosition->explicitMultiple && !multipleAllowed(flags)) - error(M_MULTIPLE); + if (parameterPosition->explicitMultiple && !multipleAllowed(flags)) + error(M_MULTIPLE); } /*----------------------------------------------------------------------*/ static ElementEntry *elementForParameter(ElementEntry *elms) { - /* Require a parameter if elms->code == 0! */ - while (!isEndOfArray(elms) && elms->code != 0) - elms++; - if (isEndOfArray(elms)) - return NULL; - return elms; + /* Require a parameter if elms->code == 0! */ + while (!isEndOfArray(elms) && elms->code != 0) + elms++; + if (isEndOfArray(elms)) + return NULL; + return elms; } /*----------------------------------------------------------------------*/ static ElementEntry *elementForEndOfSyntax(ElementEntry *elms) { - while (!isEndOfArray(elms) && (Aword)elms->code != EOS) - elms++; - if (isEndOfArray(elms)) /* No match for EOS! */ - return NULL; - return elms; + while (!isEndOfArray(elms) && (Aword)elms->code != EOS) + elms++; + if (isEndOfArray(elms)) /* No match for EOS! */ + return NULL; + return elms; } /*----------------------------------------------------------------------*/ static ElementEntry *elementForWord(ElementEntry *elms, Aint wordCode) { - while (!isEndOfArray(elms) && elms->code != wordCode) - elms++; - if (isEndOfArray(elms)) - return NULL; - return elms; + while (!isEndOfArray(elms) && elms->code != wordCode) + elms++; + if (isEndOfArray(elms)) + return NULL; + return elms; } /*----------------------------------------------------------------------*/ static bool isInstanceReferenceWord(int wordIndex) { - return isNounWord(wordIndex) || isAdjectiveWord(wordIndex) || isAllWord(wordIndex) - || isLiteralWord(wordIndex) || isItWord(wordIndex) || isThemWord(wordIndex) || isPronounWord(wordIndex); + return isNounWord(wordIndex) || isAdjectiveWord(wordIndex) || isAllWord(wordIndex) + || isLiteralWord(wordIndex) || isItWord(wordIndex) || isThemWord(wordIndex) || isPronounWord(wordIndex); } /*----------------------------------------------------------------------*/ static bool endOfPlayerCommand(int wordIndex) { - return endOfWords(wordIndex) || isConjunctionWord(wordIndex); + return endOfWords(wordIndex) || isConjunctionWord(wordIndex); } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ static ElementEntry *parseInputAccordingToSyntax(SyntaxEntry *syntax, ParameterPosition parameterPositions[]) { - ElementEntry *currentElement = elementTreeOf(syntax); - ElementEntry *nextElement = currentElement; - - int parameterCount = 0; - while (nextElement != NULL) { - /* Traverse the possible branches of currentElement to find a match, let the actual input control what we look for */ - parameterPositions[parameterCount].endOfList = TRUE; - - if (endOfPlayerCommand(currentWordIndex)) { - // TODO If a conjunction word is also some other type of word, like noun? What happens? - return elementForEndOfSyntax(currentElement); - } - - /* Or an instance reference ? */ - if (isInstanceReferenceWord(currentWordIndex)) { - /* If so, save word info for this parameterPosition */ - nextElement = elementForParameter(currentElement); - if (nextElement != NULL) { - // Create parameter structure for the parameter position based on player words - // but without resolving them - ParameterPosition *parameterPosition = ¶meterPositions[parameterCount]; - parseParameterPosition(parameterPosition, nextElement->flags, complexReferencesParser); - parameterPosition->flags = nextElement->flags; - parameterPosition->endOfList = FALSE; - - currentElement = (ElementEntry *) pointerTo(nextElement->next); - parameterCount++; - continue; - } - } - - /* Or maybe preposition? */ - if (isPrepositionWord(currentWordIndex) || isVerbWord(currentWordIndex)) { - /* A preposition? Or rather, an intermediate word? */ - nextElement = elementForWord(currentElement, dictionary[playerWords[currentWordIndex].code].code); - if (nextElement != NULL) { - currentWordIndex++; /* Word matched, go to next */ - currentElement = (ElementEntry *) pointerTo(nextElement->next); - continue; - } - } - - /* Anything else is an error, but we'll handle 'but' specially here */ - if (isExceptWord(currentWordIndex)) - errorButAfterAll(currentWordIndex); - - /* If we get here we couldn't match anything... */ - nextElement = NULL; - } - return NULL; + ElementEntry *currentElement = elementTreeOf(syntax); + ElementEntry *nextElement = currentElement; + + int parameterCount = 0; + while (nextElement != NULL) { + /* Traverse the possible branches of currentElement to find a match, let the actual input control what we look for */ + parameterPositions[parameterCount].endOfList = TRUE; + + if (endOfPlayerCommand(currentWordIndex)) { + // TODO If a conjunction word is also some other type of word, like noun? What happens? + return elementForEndOfSyntax(currentElement); + } + + /* Or an instance reference ? */ + if (isInstanceReferenceWord(currentWordIndex)) { + /* If so, save word info for this parameterPosition */ + nextElement = elementForParameter(currentElement); + if (nextElement != NULL) { + // Create parameter structure for the parameter position based on player words + // but without resolving them + ParameterPosition *parameterPosition = ¶meterPositions[parameterCount]; + parseParameterPosition(parameterPosition, nextElement->flags, complexReferencesParser); + parameterPosition->flags = nextElement->flags; + parameterPosition->endOfList = FALSE; + + currentElement = (ElementEntry *) pointerTo(nextElement->next); + parameterCount++; + continue; + } + } + + /* Or maybe preposition? */ + if (isPrepositionWord(currentWordIndex) || isVerbWord(currentWordIndex)) { + /* A preposition? Or rather, an intermediate word? */ + nextElement = elementForWord(currentElement, dictionary[playerWords[currentWordIndex].code].code); + if (nextElement != NULL) { + currentWordIndex++; /* Word matched, go to next */ + currentElement = (ElementEntry *) pointerTo(nextElement->next); + continue; + } + } + + /* Anything else is an error, but we'll handle 'but' specially here */ + if (isExceptWord(currentWordIndex)) + errorButAfterAll(currentWordIndex); + + /* If we get here we couldn't match anything... */ + nextElement = NULL; + } + return NULL; } /*----------------------------------------------------------------------*/ static bool anyExplicitMultiple(ParameterPosition parameterPositions[]) { - int i; + int i; - for (i = 0; !parameterPositions[i].endOfList; i++) - if (parameterPositions[i].explicitMultiple) - return TRUE; - return FALSE; + for (i = 0; !parameterPositions[i].endOfList; i++) + if (parameterPositions[i].explicitMultiple) + return TRUE; + return FALSE; } /*----------------------------------------------------------------------*/ static bool anyAll(ParameterPosition parameterPositions[]) { - int i; + int i; - for (i = 0; !parameterPositions[i].endOfList; i++) - if (parameterPositions[i].all) - return TRUE; - return FALSE; + for (i = 0; !parameterPositions[i].endOfList; i++) + if (parameterPositions[i].all) + return TRUE; + return FALSE; } /*----------------------------------------------------------------------*/ static void checkRestrictedParameters(ParameterPosition parameterPositions[], ElementEntry elms[]) { - RestrictionEntry *restriction; - static Parameter *localParameters = NULL; - int i; - - localParameters = ensureParameterArrayAllocated(localParameters); - clearParameterArray(localParameters); - - for (i=0; !parameterPositions[i].endOfList; i++) - addParameterToParameterArray(localParameters, ¶meterPositions[i].parameters[0]); - - for (restriction = (RestrictionEntry *) pointerTo(elms->next); !isEndOfArray(restriction); restriction++) { - ParameterPosition *parameterPosition = ¶meterPositions[restriction->parameterNumber-1]; - if (parameterPosition->explicitMultiple) { - /* This was a multiple parameter position, so check all multipleCandidates */ - for (i = 0; !isEndOfArray(¶meterPosition->parameters[i]); i++) { - copyParameter(&localParameters[restriction->parameterNumber-1], ¶meterPosition->parameters[i]); - if (!restrictionCheck(restriction, parameterPosition->parameters[i].instance)) { - /* Multiple could be both an explicit list of instance references and an expansion of ALL */ - if (!parameterPosition->all) { - char marker[80]; - /* It wasn't ALL, we need to say something about it, so - * prepare a printout with $1/2/3 - */ - sprintf(marker, "($%ld)", (unsigned long) restriction->parameterNumber); - setGlobalParameters(localParameters); - output(marker); - runRestriction(restriction, localParameters); - para(); - } - parameterPosition->parameters[i].instance = 0; /* In any case remove it from the list */ - } - } - } else { - if (!restrictionCheck(restriction, parameterPosition->parameters[0].instance)) { - runRestriction(restriction, localParameters); - abortPlayerCommand(); - } - } - parameterPositions[restriction->parameterNumber - 1].checked = TRUE; - } - freeParameterArray(localParameters); - localParameters = NULL; + RestrictionEntry *restriction; + static Parameter *localParameters = NULL; + int i; + + localParameters = ensureParameterArrayAllocated(localParameters); + clearParameterArray(localParameters); + + for (i = 0; !parameterPositions[i].endOfList; i++) + addParameterToParameterArray(localParameters, ¶meterPositions[i].parameters[0]); + + for (restriction = (RestrictionEntry *) pointerTo(elms->next); !isEndOfArray(restriction); restriction++) { + ParameterPosition *parameterPosition = ¶meterPositions[restriction->parameterNumber - 1]; + if (parameterPosition->explicitMultiple) { + /* This was a multiple parameter position, so check all multipleCandidates */ + for (i = 0; !isEndOfArray(¶meterPosition->parameters[i]); i++) { + copyParameter(&localParameters[restriction->parameterNumber - 1], ¶meterPosition->parameters[i]); + if (!restrictionCheck(restriction, parameterPosition->parameters[i].instance)) { + /* Multiple could be both an explicit list of instance references and an expansion of ALL */ + if (!parameterPosition->all) { + char marker[80]; + /* It wasn't ALL, we need to say something about it, so + * prepare a printout with $1/2/3 + */ + sprintf(marker, "($%ld)", (unsigned long) restriction->parameterNumber); + setGlobalParameters(localParameters); + output(marker); + runRestriction(restriction, localParameters); + para(); + } + parameterPosition->parameters[i].instance = 0; /* In any case remove it from the list */ + } + } + } else { + if (!restrictionCheck(restriction, parameterPosition->parameters[0].instance)) { + runRestriction(restriction, localParameters); + abortPlayerCommand(); + } + } + parameterPositions[restriction->parameterNumber - 1].checked = TRUE; + } + freeParameterArray(localParameters); + localParameters = NULL; } @@ -913,173 +913,172 @@ static void impossibleWith(ParameterPosition parameterPositions[], int positionI /*----------------------------------------------------------------------*/ static void checkNonRestrictedParameters(ParameterPosition parameterPositions[]) { - int positionIndex; - for (positionIndex = 0; !parameterPositions[positionIndex].endOfList; positionIndex++) - if (!parameterPositions[positionIndex].checked) { - if (parameterPositions[positionIndex].explicitMultiple) { - /* This was a multiple parameter position, check all multiple candidates and remove failing */ - int i; - for (i = 0; !isEndOfArray(¶meterPositions[positionIndex].parameters[i]); i++) - if (parameterPositions[positionIndex].parameters[i].instance != 0) /* Skip any empty slots */ - if (!isAObject(parameterPositions[positionIndex].parameters[i].instance)) - parameterPositions[positionIndex].parameters[i].instance = 0; - } else if (!isAObject(parameterPositions[positionIndex].parameters[0].instance)) + int positionIndex; + for (positionIndex = 0; !parameterPositions[positionIndex].endOfList; positionIndex++) + if (!parameterPositions[positionIndex].checked) { + if (parameterPositions[positionIndex].explicitMultiple) { + /* This was a multiple parameter position, check all multiple candidates and remove failing */ + int i; + for (i = 0; !isEndOfArray(¶meterPositions[positionIndex].parameters[i]); i++) + if (parameterPositions[positionIndex].parameters[i].instance != 0) /* Skip any empty slots */ + if (!isAObject(parameterPositions[positionIndex].parameters[i].instance)) + parameterPositions[positionIndex].parameters[i].instance = 0; + } else if (!isAObject(parameterPositions[positionIndex].parameters[0].instance)) impossibleWith(parameterPositions, positionIndex); - } + } } /*----------------------------------------------------------------------*/ static void restrictParametersAccordingToSyntax(ParameterPosition parameterPositions[], ElementEntry *elms) { - uncheckAllParameterPositions(parameterPositions); - checkRestrictedParameters(parameterPositions, elms); - checkNonRestrictedParameters(parameterPositions); - int positionIndex; - for (positionIndex = 0; !parameterPositions[positionIndex].endOfList; positionIndex++) - compressParameterArray(parameterPositions[positionIndex].parameters); + uncheckAllParameterPositions(parameterPositions); + checkRestrictedParameters(parameterPositions, elms); + checkNonRestrictedParameters(parameterPositions); + int positionIndex; + for (positionIndex = 0; !parameterPositions[positionIndex].endOfList; positionIndex++) + compressParameterArray(parameterPositions[positionIndex].parameters); } /*----------------------------------------------------------------------*/ static void matchPronoun(Parameter *parameter) { - static Parameter *pronounInstances = NULL; - pronounInstances = ensureParameterArrayAllocated(pronounInstances); - - int pronounCandidateCount = getPronounInstances(playerWords[parameter->firstWord].code, pronounInstances); - if (pronounCandidateCount == 0) - errorWhat(parameter->firstWord); - else if (pronounCandidateCount > 1) - errorWhichPronoun(parameter->firstWord, pronounInstances); - else { - parameter->candidates[0] = pronounInstances[0]; - setEndOfArray(¶meter->candidates[1]); - } + static Parameter *pronounInstances = NULL; + pronounInstances = ensureParameterArrayAllocated(pronounInstances); + + int pronounCandidateCount = getPronounInstances(playerWords[parameter->firstWord].code, pronounInstances); + if (pronounCandidateCount == 0) + errorWhat(parameter->firstWord); + else if (pronounCandidateCount > 1) + errorWhichPronoun(parameter->firstWord, pronounInstances); + else { + parameter->candidates[0] = pronounInstances[0]; + setEndOfArray(¶meter->candidates[1]); + } } /*----------------------------------------------------------------------*/ static void matchNounPhrase(Parameter *parameter, ReferencesFinder adjectiveReferencesFinder, ReferencesFinder nounReferencesFinder) { - int i; + int i; - for (i = parameter->firstWord; i < parameter->lastWord; i++) - updateWithReferences(parameter->candidates, i, adjectiveReferencesFinder); - updateWithReferences(parameter->candidates, parameter->lastWord, nounReferencesFinder); + for (i = parameter->firstWord; i < parameter->lastWord; i++) + updateWithReferences(parameter->candidates, i, adjectiveReferencesFinder); + updateWithReferences(parameter->candidates, parameter->lastWord, nounReferencesFinder); } /*----------------------------------------------------------------------*/ static void instanceMatcher(Parameter *parameter) { - Parameter *candidates = parameter->candidates; - int i; - - if (parameter->isLiteral) { - candidates[0].instance = instanceFromLiteral(playerWords[parameter->firstWord].code - dictionarySize); - setEndOfArray(&candidates[1]); - } else if (parameter->isPronoun) { - matchPronoun(parameter); - } else - matchNounPhrase(parameter, adjectiveReferencesForWord, nounReferencesForWord); - - // Ensure that every candidate have the words, even if there where no candidates - candidates[0].firstWord = parameter->firstWord; - candidates[0].lastWord = parameter->lastWord; - for (i = 0; i < lengthOfParameterArray(candidates); i++) { - candidates[i].firstWord = parameter->firstWord; - candidates[i].lastWord = parameter->lastWord; - } + Parameter *candidates = parameter->candidates; + int i; + + if (parameter->isLiteral) { + candidates[0].instance = instanceFromLiteral(playerWords[parameter->firstWord].code - dictionarySize); + setEndOfArray(&candidates[1]); + } else if (parameter->isPronoun) { + matchPronoun(parameter); + } else + matchNounPhrase(parameter, adjectiveReferencesForWord, nounReferencesForWord); + + // Ensure that every candidate have the words, even if there where no candidates + candidates[0].firstWord = parameter->firstWord; + candidates[0].lastWord = parameter->lastWord; + for (i = 0; i < lengthOfParameterArray(candidates); i++) { + candidates[i].firstWord = parameter->firstWord; + candidates[i].lastWord = parameter->lastWord; + } } /*----------------------------------------------------------------------*/ -static void findCandidates(Parameter parameters[], void (*instanceMatcher)(Parameter *parameter)) -{ - int i; +static void findCandidates(Parameter parameters[], void (*instanceMatcher)(Parameter *parameter)) { + int i; - for (i = 0; i < lengthOfParameterArray(parameters); i++) { - parameters[i].candidates = ensureParameterArrayAllocated(parameters[i].candidates); - instanceMatcher(¶meters[i]); - parameters[i].candidates[0].isPronoun = parameters[i].isPronoun; - } + for (i = 0; i < lengthOfParameterArray(parameters); i++) { + parameters[i].candidates = ensureParameterArrayAllocated(parameters[i].candidates); + instanceMatcher(¶meters[i]); + parameters[i].candidates[0].isPronoun = parameters[i].isPronoun; + } } /*----------------------------------------------------------------------*/ static void handleFailedParse(ElementEntry *elms) { - if (elms == NULL) - error(M_WHAT); - if (elms->next == 0) { /* No verb code, verb not declared! */ - /* TODO Does this ever happen? */ - error(M_CANT0); - } + if (elms == NULL) + error(M_WHAT); + if (elms->next == 0) { /* No verb code, verb not declared! */ + /* TODO Does this ever happen? */ + error(M_CANT0); + } } /*----------------------------------------------------------------------*/ static void convertMultipleCandidatesToMultipleParameters(ParameterPosition parameterPositions[], Parameter multipleParameters[]) { - int parameterIndex; - for (parameterIndex=0; !parameterPositions[parameterIndex].endOfList; parameterIndex++) - if (parameterPositions[parameterIndex].explicitMultiple) { - compressParameterArray(parameterPositions[parameterIndex].parameters); - copyParameterArray(multipleParameters, parameterPositions[parameterIndex].parameters); - } + int parameterIndex; + for (parameterIndex = 0; !parameterPositions[parameterIndex].endOfList; parameterIndex++) + if (parameterPositions[parameterIndex].explicitMultiple) { + compressParameterArray(parameterPositions[parameterIndex].parameters); + copyParameterArray(multipleParameters, parameterPositions[parameterIndex].parameters); + } } /*----------------------------------------------------------------------*/ static ElementEntry *parseInput(ParameterPosition *parameterPositions) { - ElementEntry *element; - SyntaxEntry *stx; + ElementEntry *element; + SyntaxEntry *stx; - stx = findSyntaxTreeForVerb(verbWordCode); - element = parseInputAccordingToSyntax(stx, parameterPositions); - handleFailedParse(element); - current.syntax = element->flags; - current.verb = remapParameterOrder(current.syntax, parameterPositions); - return element; + stx = findSyntaxTreeForVerb(verbWordCode); + element = parseInputAccordingToSyntax(stx, parameterPositions); + handleFailedParse(element); + current.syntax = element->flags; + current.verb = remapParameterOrder(current.syntax, parameterPositions); + return element; } /*----------------------------------------------------------------------*/ static void findCandidatesForPlayerWords(ParameterPosition *parameterPosition) { - ParameterArray parameters = parameterPosition->parameters; - - if (!parameterArrayIsEmpty(parameters)) { - if (parameters[0].isThem) { - parameterPosition->them = TRUE; - getPreviousMultipleParameters(parameters); - if (lengthOfParameterArray(parameters) == 0) - errorWhat(parameters[0].firstWord); - if (lengthOfParameterArray(parameters) > 1) - parameterPosition->explicitMultiple = TRUE; - } else if (parameterPosition->all) { - buildAllHere(parameters); - if (!parameterArrayIsEmpty(parameterPosition->exceptions)) - findCandidates(parameterPosition->exceptions, instanceMatcher); - } else - findCandidates(parameters, instanceMatcher); - } + ParameterArray parameters = parameterPosition->parameters; + + if (!parameterArrayIsEmpty(parameters)) { + if (parameters[0].isThem) { + parameterPosition->them = TRUE; + getPreviousMultipleParameters(parameters); + if (lengthOfParameterArray(parameters) == 0) + errorWhat(parameters[0].firstWord); + if (lengthOfParameterArray(parameters) > 1) + parameterPosition->explicitMultiple = TRUE; + } else if (parameterPosition->all) { + buildAllHere(parameters); + if (!parameterArrayIsEmpty(parameterPosition->exceptions)) + findCandidates(parameterPosition->exceptions, instanceMatcher); + } else + findCandidates(parameters, instanceMatcher); + } } /*----------------------------------------------------------------------*/ static void handleMultiplePosition(ParameterPosition parameterPositions[]) { - int multiplePosition = findMultipleParameterPosition(parameterPositions); - if (anyAll(parameterPositions)) { - /* If the player used ALL, try to find out what was applicable */ - disambiguateCandidatesForPosition(parameterPositions, multiplePosition, parameterPositions[multiplePosition].parameters); - if (lengthOfParameterArray(parameterPositions[multiplePosition].parameters) == 0) - errorWhat(parameterPositions[multiplePosition].parameters[0].firstWord); - subtractParameterArrays(parameterPositions[multiplePosition].parameters, parameterPositions[multiplePosition].exceptions); - if (lengthOfParameterArray(parameterPositions[multiplePosition].parameters) == 0) - error(M_NOT_MUCH); - } else if (anyExplicitMultiple(parameterPositions)) { - compressParameterArray(parameterPositions[multiplePosition].parameters); - if (lengthOfParameterArray(parameterPositions[multiplePosition].parameters) == 0) { - /* If there where multiple parameters but non left, exit without a */ - /* word, assuming we have already said enough */ - abortPlayerCommand(); - } - } + int multiplePosition = findMultipleParameterPosition(parameterPositions); + if (anyAll(parameterPositions)) { + /* If the player used ALL, try to find out what was applicable */ + disambiguateCandidatesForPosition(parameterPositions, multiplePosition, parameterPositions[multiplePosition].parameters); + if (lengthOfParameterArray(parameterPositions[multiplePosition].parameters) == 0) + errorWhat(parameterPositions[multiplePosition].parameters[0].firstWord); + subtractParameterArrays(parameterPositions[multiplePosition].parameters, parameterPositions[multiplePosition].exceptions); + if (lengthOfParameterArray(parameterPositions[multiplePosition].parameters) == 0) + error(M_NOT_MUCH); + } else if (anyExplicitMultiple(parameterPositions)) { + compressParameterArray(parameterPositions[multiplePosition].parameters); + if (lengthOfParameterArray(parameterPositions[multiplePosition].parameters) == 0) { + /* If there where multiple parameters but non left, exit without a */ + /* word, assuming we have already said enough */ + abortPlayerCommand(); + } + } } @@ -1120,345 +1119,368 @@ typedef Parameter *DisambiguationHandler(Parameter allCandidates[], Parameter pr typedef DisambiguationHandler *DisambiguationHandlerTable[3][3][2]; static Parameter *disambiguate00N(Parameter allCandidates[], Parameter presentCandidates[]) { - if (allCandidates[0].isPronoun) - errorWhat(allCandidates[0].firstWord); - else - errorNoSuch(allCandidates[0]); - return NULL; + if (allCandidates[0].isPronoun) + errorWhat(allCandidates[0].firstWord); + else + errorNoSuch(allCandidates[0]); + return NULL; } static Parameter *disambiguate01N(Parameter allCandidates[], Parameter presentCandidates[]) { - if (allCandidates[0].isPronoun) - errorWhat(allCandidates[0].firstWord); - else - errorNoSuch(allCandidates[0]); - return NULL; + if (allCandidates[0].isPronoun) + errorWhat(allCandidates[0].firstWord); + else + errorNoSuch(allCandidates[0]); + return NULL; } static Parameter *disambiguate0MN(Parameter allCandidates[], Parameter presentCandidates[]) { - if (allCandidates[0].isPronoun) - errorWhat(allCandidates[0].firstWord); - else - errorNoSuch(allCandidates[0]); - return NULL; + if (allCandidates[0].isPronoun) + errorWhat(allCandidates[0].firstWord); + else + errorNoSuch(allCandidates[0]); + return NULL; } static Parameter *disambiguate10N(Parameter allCandidates[], Parameter presentCandidates[]) { - return presentCandidates; + return presentCandidates; } static Parameter *disambiguate11N(Parameter allCandidates[], Parameter presentCandidates[]) { - return presentCandidates; + return presentCandidates; } static Parameter *disambiguate1MN(Parameter allCandidates[], Parameter presentCandidates[]) { - return presentCandidates; + return presentCandidates; } static Parameter *disambiguateM0N(Parameter allCandidates[], Parameter presentCandidates[]) { - errorWhichOne(presentCandidates); - return NULL; + errorWhichOne(presentCandidates); + return NULL; } static Parameter *disambiguateM1N(Parameter allCandidates[], Parameter presentCandidates[]) { - errorWhichOne(presentCandidates); - return NULL; + errorWhichOne(presentCandidates); + return NULL; } static Parameter *disambiguateMMN(Parameter allCandidates[], Parameter presentCandidates[]) { - errorWhichOne(presentCandidates); - return NULL; + errorWhichOne(presentCandidates); + return NULL; } static Parameter *disambiguate00Y(Parameter allCandidates[], Parameter presentCandidates[]) { - errorNoSuch(allCandidates[0]); - return NULL; + errorNoSuch(allCandidates[0]); + return NULL; } static Parameter *disambiguate01Y(Parameter allCandidates[], Parameter presentCandidates[]) { - return allCandidates; + return allCandidates; } static Parameter *disambiguate0MY(Parameter allCandidates[], Parameter presentCandidates[]) { - errorWhichOne(allCandidates); - return NULL; + errorWhichOne(allCandidates); + return NULL; } static Parameter *disambiguate10Y(Parameter allCandidates[], Parameter presentCandidates[]) { - return presentCandidates; + return presentCandidates; } static Parameter *disambiguate11Y(Parameter allCandidates[], Parameter presentCandidates[]) { - return presentCandidates; + return presentCandidates; } static Parameter *disambiguate1MY(Parameter allCandidates[], Parameter presentCandidates[]) { - return presentCandidates; + return presentCandidates; } static Parameter *disambiguateM0Y(Parameter allCandidates[], Parameter presentCandidates[]) { - errorWhichOne(presentCandidates); - return NULL; + errorWhichOne(presentCandidates); + return NULL; } static Parameter *disambiguateM1Y(Parameter allCandidates[], Parameter presentCandidates[]) { - errorWhichOne(presentCandidates); - return NULL; + errorWhichOne(presentCandidates); + return NULL; } static Parameter *disambiguateMMY(Parameter allCandidates[], Parameter presentCandidates[]) { - errorWhichOne(presentCandidates);return NULL; -} - -static DisambiguationHandlerTable disambiguationHandlerTable = - { - { // Present == 0 - { // Distant == 0 - disambiguate00N, disambiguate00Y}, - { // Distant == 1 - disambiguate01N, disambiguate01Y}, - { // Distant == M - disambiguate0MN, disambiguate0MY}}, - { // Present == 1 - { // Distant == 0 - disambiguate10N, disambiguate10Y}, - { // Distant == 1 - disambiguate11N, disambiguate11Y}, - { // Distant == M - disambiguate1MN, disambiguate1MY}}, - { // Present == M - { // Distant == 0 - disambiguateM0N, disambiguateM0Y}, - { // Distant == 1 - disambiguateM1N, disambiguateM1Y}, - { // Distant == M - disambiguateMMN, disambiguateMMY}} - }; + errorWhichOne(presentCandidates); + return NULL; +} + +static DisambiguationHandlerTable disambiguationHandlerTable = { + { + // Present == 0 + { + // Distant == 0 + disambiguate00N, disambiguate00Y + }, + { + // Distant == 1 + disambiguate01N, disambiguate01Y + }, + { + // Distant == M + disambiguate0MN, disambiguate0MY + } + }, + { + // Present == 1 + { + // Distant == 0 + disambiguate10N, disambiguate10Y + }, + { + // Distant == 1 + disambiguate11N, disambiguate11Y + }, + { + // Distant == M + disambiguate1MN, disambiguate1MY + } + }, + { + // Present == M + { + // Distant == 0 + disambiguateM0N, disambiguateM0Y + }, + { + // Distant == 1 + disambiguateM1N, disambiguateM1Y + }, + { + // Distant == M + disambiguateMMN, disambiguateMMY + } + } +}; /*----------------------------------------------------------------------*/ static void disambiguateCandidates(Parameter *allCandidates, bool omnipotent, bool (*reachable)(int), DisambiguationHandlerTable handler) { - static Parameter *presentCandidates = NULL; - int present; - int distant; - Parameter *result; + static Parameter *presentCandidates = NULL; + int present; + int distant; + Parameter *result; - presentCandidates = ensureParameterArrayAllocated(presentCandidates); + presentCandidates = ensureParameterArrayAllocated(presentCandidates); - copyParameterArray(presentCandidates, allCandidates); - filterOutNonReachable(presentCandidates, reachable); + copyParameterArray(presentCandidates, allCandidates); + filterOutNonReachable(presentCandidates, reachable); - present = lengthOfParameterArray(presentCandidates); - if (present > 1) present = 2; /* 2 = M */ + present = lengthOfParameterArray(presentCandidates); + if (present > 1) present = 2; /* 2 = M */ - distant = lengthOfParameterArray(allCandidates) - present; - if (distant > 1) distant = 2; /* 2 = M */ + distant = lengthOfParameterArray(allCandidates) - present; + if (distant > 1) distant = 2; /* 2 = M */ - result = handler[present][distant][omnipotent](allCandidates, presentCandidates); + result = handler[present][distant][omnipotent](allCandidates, presentCandidates); - // If we returned then it's ok, use the single candidate found - allCandidates[0] = result[0]; - setEndOfArray(&allCandidates[1]); + // If we returned then it's ok, use the single candidate found + allCandidates[0] = result[0]; + setEndOfArray(&allCandidates[1]); } /*----------------------------------------------------------------------*/ static void disambiguate(ParameterPosition parameterPositions[], ElementEntry *element) { - /* The New Strategy! Parsing has only collected word indications, - not built anything, so we need to match parameters to instances here */ - - int position; - for (position = 0; !parameterPositions[position].endOfList; position++) { - findCandidatesForPlayerWords(¶meterPositions[position]); - } - - /* Now we have candidates for everything the player said, except - if he used ALL or THEM, then we have built those as parameters, or he - referred to the multiple parameters of the previous command - using 'them, if so, they too are stored as parameters */ - - for (position = 0; !parameterPositions[position].endOfList; position++) { - ParameterPosition *parameterPosition = ¶meterPositions[position]; - bool omni = hasBit(parameterPosition->flags, OMNIBIT); - if (!parameterPosition->all && !parameterPosition->them) { - Parameter *parameters = parameterPosition->parameters; - int p; - for (p = 0; p < lengthOfParameterArray(parameters); p++) { - Parameter *parameter = ¶meters[p]; - Parameter *candidates = parameter->candidates; - disambiguateCandidates(candidates, omni, reachable, disambiguationHandlerTable); - parameter->instance = candidates[0].instance; - } - } - if (parameterPosition->all) { - Parameter *exceptions = parameterPosition->exceptions; - int p; - for (p = 0; p < lengthOfParameterArray(exceptions); p++) { - Parameter *parameter = &exceptions[p]; - Parameter *candidates = parameter->candidates; - disambiguateCandidates(candidates, omni, reachable, disambiguationHandlerTable); - parameter->instance = candidates[0].instance; - } - } - } - - handleMultiplePosition(parameterPositions); - - /* Now perform restriction checks */ - restrictParametersAccordingToSyntax(parameterPositions, element); + /* The New Strategy! Parsing has only collected word indications, + not built anything, so we need to match parameters to instances here */ + + int position; + for (position = 0; !parameterPositions[position].endOfList; position++) { + findCandidatesForPlayerWords(¶meterPositions[position]); + } + + /* Now we have candidates for everything the player said, except + if he used ALL or THEM, then we have built those as parameters, or he + referred to the multiple parameters of the previous command + using 'them, if so, they too are stored as parameters */ + + for (position = 0; !parameterPositions[position].endOfList; position++) { + ParameterPosition *parameterPosition = ¶meterPositions[position]; + bool omni = hasBit(parameterPosition->flags, OMNIBIT); + if (!parameterPosition->all && !parameterPosition->them) { + Parameter *parameters = parameterPosition->parameters; + int p; + for (p = 0; p < lengthOfParameterArray(parameters); p++) { + Parameter *parameter = ¶meters[p]; + Parameter *candidates = parameter->candidates; + disambiguateCandidates(candidates, omni, reachable, disambiguationHandlerTable); + parameter->instance = candidates[0].instance; + } + } + if (parameterPosition->all) { + Parameter *exceptions = parameterPosition->exceptions; + int p; + for (p = 0; p < lengthOfParameterArray(exceptions); p++) { + Parameter *parameter = &exceptions[p]; + Parameter *candidates = parameter->candidates; + disambiguateCandidates(candidates, omni, reachable, disambiguationHandlerTable); + parameter->instance = candidates[0].instance; + } + } + } + + handleMultiplePosition(parameterPositions); + + /* Now perform restriction checks */ + restrictParametersAccordingToSyntax(parameterPositions, element); } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ static void tryParam(Parameter parameters[], Parameter multipleParameters[]) { - ElementEntry *element; /* Pointer to element list */ - static ParameterPosition *parameterPositions = NULL; - if (parameterPositions != NULL) - deallocateParameterPositions(parameterPositions); + ElementEntry *element; /* Pointer to element list */ + static ParameterPosition *parameterPositions = NULL; + if (parameterPositions != NULL) + deallocateParameterPositions(parameterPositions); - // TODO newParameterPositionArray()!!!! Or even reallocatePP.. or cleanPP.. - parameterPositions = (ParameterPosition *)allocate(sizeof(ParameterPosition)*(MAXPARAMS+1)); - parameterPositions[0].endOfList = TRUE; + // TODO newParameterPositionArray()!!!! Or even reallocatePP.. or cleanPP.. + parameterPositions = (ParameterPosition *)allocate(sizeof(ParameterPosition) * (MAXPARAMS + 1)); + parameterPositions[0].endOfList = TRUE; - element = parseInput(parameterPositions); + element = parseInput(parameterPositions); - disambiguate(parameterPositions, element); + disambiguate(parameterPositions, element); - // TODO: Now we need to convert back to legacy parameter and multipleParameter format - convertPositionsToParameters(parameterPositions, parameters); - markExplicitMultiple(parameterPositions, parameters); - convertMultipleCandidatesToMultipleParameters(parameterPositions, multipleParameters); + // TODO: Now we need to convert back to legacy parameter and multipleParameter format + convertPositionsToParameters(parameterPositions, parameters); + markExplicitMultiple(parameterPositions, parameters); + convertMultipleCandidatesToMultipleParameters(parameterPositions, multipleParameters); - deallocateParameterPositions(parameterPositions); - parameterPositions = NULL; + deallocateParameterPositions(parameterPositions); + parameterPositions = NULL; } /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -static void parseOneCommand(Parameter parameters[], Parameter multipleParameters[]) -{ - tryParam(parameters, multipleParameters); /* ... to understand what he said */ - - /* More on this line? */ - if (!endOfWords(currentWordIndex)) { - if (isConjunctionWord(currentWordIndex)) - currentWordIndex++; /* If so skip the conjunction */ - else - error(M_WHAT); - } +static void parseOneCommand(Parameter parameters[], Parameter multipleParameters[]) { + tryParam(parameters, multipleParameters); /* ... to understand what he said */ + + /* More on this line? */ + if (!endOfWords(currentWordIndex)) { + if (isConjunctionWord(currentWordIndex)) + currentWordIndex++; /* If so skip the conjunction */ + else + error(M_WHAT); + } } /*======================================================================*/ void initParsing(void) { - currentWordIndex = 0; - continued = FALSE; - ensureSpaceForPlayerWords(0); - clearWordList(playerWords); + currentWordIndex = 0; + continued = FALSE; + ensureSpaceForPlayerWords(0); + clearWordList(playerWords); - pronouns = allocatePronounArray(pronouns); - globalParameters = ensureParameterArrayAllocated(globalParameters); - previousMultipleParameters = ensureParameterArrayAllocated(previousMultipleParameters); + pronouns = allocatePronounArray(pronouns); + globalParameters = ensureParameterArrayAllocated(globalParameters); + previousMultipleParameters = ensureParameterArrayAllocated(previousMultipleParameters); } /*----------------------------------------------------------------------*/ static int pronounWordForInstance(int instance) { - /* Scan through the dictionary to find any pronouns that can be used - for this instance */ - int w; + /* Scan through the dictionary to find any pronouns that can be used + for this instance */ + int w; - for (w = 0; w < dictionarySize; w++) - if (isPronoun(w)) { - Aword *reference = (Aword *)pointerTo(dictionary[w].pronounRefs); - while (*reference != EOD) { - if (*reference == (Aword)instance) - return dictionary[w].code; - reference++; - } - } - return 0; + for (w = 0; w < dictionarySize; w++) + if (isPronoun(w)) { + Aword *reference = (Aword *)pointerTo(dictionary[w].pronounRefs); + while (*reference != EOD) { + if (*reference == (Aword)instance) + return dictionary[w].code; + reference++; + } + } + return 0; } /*----------------------------------------------------------------------*/ static void addPronounForInstance(int thePronoun, int instanceCode) { - int i; + int i; - for (i = 0; !endOfPronouns(i); i++) - if (pronouns[i].pronoun == thePronoun && pronouns[i].instance == instanceCode) - // Don't add the same instance twice for the same pronoun - return; - pronouns[i].pronoun = thePronoun; - pronouns[i].instance = instanceCode; - setEndOfArray(&pronouns[i + 1]); + for (i = 0; !endOfPronouns(i); i++) + if (pronouns[i].pronoun == thePronoun && pronouns[i].instance == instanceCode) + // Don't add the same instance twice for the same pronoun + return; + pronouns[i].pronoun = thePronoun; + pronouns[i].instance = instanceCode; + setEndOfArray(&pronouns[i + 1]); } /*----------------------------------------------------------------------*/ static void notePronounsForParameters(Parameter parameters[]) { - /* For all parameters note which ones can be referred to by a pronoun */ - Parameter *p; - - clearPronounList(pronouns); - for (p = parameters; !isEndOfArray(p); p++) { - int pronoun = pronounWordForInstance(p->instance); - if (pronoun > 0) - addPronounForInstance(pronoun, p->instance); - } + /* For all parameters note which ones can be referred to by a pronoun */ + Parameter *p; + + clearPronounList(pronouns); + for (p = parameters; !isEndOfArray(p); p++) { + int pronoun = pronounWordForInstance(p->instance); + if (pronoun > 0) + addPronounForInstance(pronoun, p->instance); + } } /*----------------------------------------------------------------------*/ static void parseVerbCommand(Parameter parameters[], Parameter multipleParameters[]) { - verbWord = playerWords[currentWordIndex].code; - verbWordCode = dictionary[verbWord].code; - if (isPreBeta2(header->version)) - /* Pre-beta2 didn't generate syntax elements for verb words, - need to skip first word which should be the verb */ - currentWordIndex++; - parseOneCommand(parameters, multipleParameters); - notePronounsForParameters(parameters); - fail = FALSE; + verbWord = playerWords[currentWordIndex].code; + verbWordCode = dictionary[verbWord].code; + if (isPreBeta2(header->version)) + /* Pre-beta2 didn't generate syntax elements for verb words, + need to skip first word which should be the verb */ + currentWordIndex++; + parseOneCommand(parameters, multipleParameters); + notePronounsForParameters(parameters); + fail = FALSE; } /*----------------------------------------------------------------------*/ static void parseInstanceCommand(Parameter parameters[], Parameter multipleParameters[]) { - /* Pick up the parse tree for the syntaxes that start with an - instance reference and parse according to that. The - verbWord code is set to 0 to indicate that it is not a verb - but an instance that starts the command. */ - verbWordCode = 0; - parseOneCommand(parameters, multipleParameters); - notePronounsForParameters(parameters); - fail = FALSE; + /* Pick up the parse tree for the syntaxes that start with an + instance reference and parse according to that. The + verbWord code is set to 0 to indicate that it is not a verb + but an instance that starts the command. */ + verbWordCode = 0; + parseOneCommand(parameters, multipleParameters); + notePronounsForParameters(parameters); + fail = FALSE; } /*======================================================================*/ void parse(void) { - /* longjmp's ahead so these need to survive to not leak memory */ - static Parameter *parameters = NULL; - static Parameter *multipleParameters = NULL; - parameters = ensureParameterArrayAllocated(parameters); - multipleParameters = ensureParameterArrayAllocated(multipleParameters); - - if (endOfWords(currentWordIndex)) { - currentWordIndex = 0; - scan(); - } else if (anyOutput) - para(); - - capitalize = TRUE; - - firstWord = currentWordIndex; - if (isVerbWord(currentWordIndex)) { - parseVerbCommand(parameters, multipleParameters); - action(current.verb, parameters, multipleParameters); - } else if (isDirectionWord(currentWordIndex)) { - clearParameterArray(previousMultipleParameters); - clearPronounList(pronouns); - handleDirectionalCommand(); - } else if (isInstanceReferenceWord(currentWordIndex)) { - parseInstanceCommand(parameters, multipleParameters); - action(current.verb, parameters, multipleParameters); - } else - error(M_WHAT); - - if (fail) error(NO_MSG); - - lastWord = currentWordIndex - 1; - if (isConjunctionWord(lastWord)) - lastWord--; - - if (lengthOfParameterArray(parameters) > 0) - copyParameterArray(previousMultipleParameters, multipleParameters); - else - clearParameterArray(previousMultipleParameters); - - freeParameterArray(parameters); - parameters = NULL; - freeParameterArray(multipleParameters); - multipleParameters = NULL; + /* longjmp's ahead so these need to survive to not leak memory */ + static Parameter *parameters = NULL; + static Parameter *multipleParameters = NULL; + parameters = ensureParameterArrayAllocated(parameters); + multipleParameters = ensureParameterArrayAllocated(multipleParameters); + + if (endOfWords(currentWordIndex)) { + currentWordIndex = 0; + scan(); + } else if (anyOutput) + para(); + + capitalize = TRUE; + + firstWord = currentWordIndex; + if (isVerbWord(currentWordIndex)) { + parseVerbCommand(parameters, multipleParameters); + action(current.verb, parameters, multipleParameters); + } else if (isDirectionWord(currentWordIndex)) { + clearParameterArray(previousMultipleParameters); + clearPronounList(pronouns); + handleDirectionalCommand(); + } else if (isInstanceReferenceWord(currentWordIndex)) { + parseInstanceCommand(parameters, multipleParameters); + action(current.verb, parameters, multipleParameters); + } else + error(M_WHAT); + + if (fail) error(NO_MSG); + + lastWord = currentWordIndex - 1; + if (isConjunctionWord(lastWord)) + lastWord--; + + if (lengthOfParameterArray(parameters) > 0) + copyParameterArray(previousMultipleParameters, multipleParameters); + else + clearParameterArray(previousMultipleParameters); + + freeParameterArray(parameters); + parameters = NULL; + freeParameterArray(multipleParameters); + multipleParameters = NULL; } } // End of namespace Alan3 |