예제 #1
0
AstNode* Parser::parseStatement() {
    if (isKeyword(currentTokenValue())) {
      if (currentTokenValue() == "function") {
          return parseFunction();
      } else if (currentTokenValue() == "for") {
          return parseFor();
      } else if (currentTokenValue() == "if") {
          return parseIf();
      } else if (currentTokenValue() == "while") {
          return parseWhile();
      } else if (currentTokenValue() == "print") {
          return parsePrint();
      } else if (currentTokenValue() == "int") {
          return parseDeclaration(VT_INT);
      } else if (currentTokenValue() == "double") {
          return parseDeclaration(VT_DOUBLE);
      } else if (currentTokenValue() == "string") {
          return parseDeclaration(VT_STRING);
      } else if (currentTokenValue() == "return") {
          return parseReturn();
      } else {
          cout << "unhandled keyword " << currentTokenValue() << endl;
          assert(false);
          return 0;
      }
    }
    if (currentToken() == tLBRACE) {
       return parseBlock(true);
    }
    if ((currentToken() == tIDENT) && isAssignment(lookaheadToken(1))) {
        return parseAssignment();
    }
    return parseExpression();
}
예제 #2
0
void AbstractParser::initSpecialCommandMap()
{
    auto &map = m_specialCommandMap;
    map.clear();

    auto add = [this](Abbrev abb, const ParserCallback &callback, const HelpCallback &help) {
        addSpecialCommand(abb.getCommand(), abb.getMinAbbrev(), callback, help);
    };

    const auto makeSimpleHelp = [this](const std::string &help) {
        return [this, help](const std::string &name) {
            sendToUser(QString("Help for %1%2:\r\n  %3\r\n\r\n")
                           .arg(prefixChar)
                           .arg(QString::fromStdString(name))
                           .arg(QString::fromStdString(help)));
        };
    };

    qInfo() << "Adding special commands to the map...";

    // help is important, so it comes first

    add(cmdHelp,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            this->parseHelp(rest);
            return true;
        },
        // TODO: create a parse tree, and show all of the help topics.
        makeSimpleHelp("Provides help."));
    add(cmdMapHelp,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            this->showMapHelp();
            return true;
        },
        makeSimpleHelp("Help for mapping console commands."));
    add(cmdDoorHelp,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            this->showDoorCommandHelp();
            return true;
        },
        makeSimpleHelp("Help for door console commands."));
    add(cmdGroupHelp,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            this->showGroupHelp();
            return true;
        },
        makeSimpleHelp("Help for group manager console commands."));

    // door actions
    for (const DoorActionType x : ALL_DOOR_ACTION_TYPES) {
        if (auto cmd = getParserCommandName(x))
            add(cmd,
                [this, x](const std::vector<StringView> & /*s*/, StringView rest) {
                    return parseDoorAction(x, rest);
                },
                makeSimpleHelp("Sets door action: " + std::string{cmd.getCommand()}));
    }

    for (const DoorFlag x : ALL_DOOR_FLAGS) {
        if (auto cmd = getParserCommandName(x))
            add(getParserCommandName(x),
                [this, x](const std::vector<StringView> & /*s*/, StringView rest) {
                    return parseDoorFlag(x, rest);
                },
                makeSimpleHelp("Sets door flag: " + std::string{cmd.getCommand()}));
    }

    for (const ExitFlag x : ALL_EXIT_FLAGS) {
        if (auto cmd = getParserCommandName(x))
            add(cmd,
                [this, x](const std::vector<StringView> & /*s*/, StringView rest) {
                    return parseExitFlag(x, rest);
                },
                makeSimpleHelp("Sets exit flag: " + std::string{cmd.getCommand()}));
    }

#define ADD_FIELD_CMDS(X) \
    do { \
        for (const auto x : DEFINED_ROOM_##X##_TYPES) { \
            if (auto cmd = getParserCommandName(x)) { \
                auto type = RoomField::X##_TYPE; \
                add(cmd, \
                    [this, x, type](const std::vector<StringView> & /*s*/, StringView rest) { \
                        if (!rest.isEmpty()) \
                            return false; \
                        setRoomFieldCommand(x, type); \
                        return true; \
                    }, \
                    makeSimpleHelp("Sets " #X " flag: " + std::string{cmd.getCommand()})); \
            } \
        } \
    } while (false)
    ADD_FIELD_CMDS(LIGHT);
    ADD_FIELD_CMDS(SUNDEATH);
    ADD_FIELD_CMDS(PORTABLE);
    ADD_FIELD_CMDS(RIDABLE);
    ADD_FIELD_CMDS(ALIGN);
#undef ADD_FIELD_CMDS

    for (const RoomMobFlag x : ALL_MOB_FLAGS) {
        if (auto cmd = getParserCommandName(x)) {
            add(cmd,
                [this, x](const std::vector<StringView> & /*s*/, StringView rest) {
                    if (!rest.isEmpty())
                        return false;
                    toggleRoomFlagCommand(x, RoomField::MOB_FLAGS);
                    return true;
                },
                makeSimpleHelp("Sets room mob flag: " + std::string{cmd.getCommand()}));
        }
    }

    for (const RoomLoadFlag x : ALL_LOAD_FLAGS) {
        if (auto cmd = getParserCommandName(x))
            add(cmd,
                [this, x](const std::vector<StringView> & /*s*/, StringView rest) {
                    if (!rest.isEmpty())
                        return false;
                    toggleRoomFlagCommand(x, RoomField::LOAD_FLAGS);
                    return true;
                },
                makeSimpleHelp("Sets room load flag: " + std::string{cmd.getCommand()}));
    }

    // misc commands

    add(cmdBack,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            this->doBackCommand();
            return true;
        },
        makeSimpleHelp("Delete prespammed commands from queue."));
    add(cmdDirections,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            this->parseDirections(rest);
            return true;
        },
        makeSimpleHelp("Prints directions to matching rooms."));
    add(cmdGroupKick,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            this->parseGroupKick(rest);
            return true;
        },
        makeSimpleHelp("Kick [player] from the group."));
    add(cmdGroupLock,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            this->doGroupLockCommand();
            return true;
        },
        makeSimpleHelp("Toggle the lock on the group."));
    add(cmdGroupTell,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            this->parseGroupTell(rest);
            return true;
        },
        makeSimpleHelp("Send a grouptell with the [message]."));
    add(cmdMarkCurrent,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            this->doMarkCurrentCommand();
            return true;
        },
        makeSimpleHelp("Highlight the room you are currently in."));
    add(cmdName,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            this->parseName(rest);
            return true;
        },
        makeSimpleHelp(
            "Arguments: <dir> <name>;  Sets the name of door in direction <dir> with <name>."));
    add(cmdNote,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            this->parseNoteCmd(rest);
            return true;
        },
        makeSimpleHelp("Sets the note for the current room."));
    add(cmdRemoveDoorNames,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            this->doRemoveDoorNamesCommand();
            return true;
        },
        makeSimpleHelp(
            "Removes all secret door names from the current map (WARNING: destructive)!"));
    add(cmdSearch,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            this->parseSearch(rest);
            return true;
        },
        makeSimpleHelp("Highlight matching rooms on the map."));
    add(cmdSet,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            this->parseSetCommand(rest);
            return true;
        },
        [this](const std::string &name) {
            const char help[]
                = "Subcommands:\r\n"
                  "\tprefix              # Displays the current prefix.\r\n"
                  "\tprefix <punct-char> # Changes the current prefix.\r\n"
                  "\r\n"
                  // REVISIT: Does it actually support LATIN-1 punctuation like the degree symbol?
                  "Note: <punct-char> may be any ASCII punctuation character,\r\n"
                  "      which can be optionally single- or double-quoted.\r\n"
                  "\r\n"
                  "Examples to set prefix:\r\n"
                  "\tprefix /   # slash character\r\n"
                  "\tprefix '/' # single-quoted slash character\r\n"
                  "\tprefix \"/\" # double-quoted slash character\r\n"
                  "\tprefix '   # bare single-quote character\r\n"
                  "\tprefix \"'\" # double-quoted single-quote character\r\n"
                  "\tprefix \"   # bare double-quote character\r\n"
                  "\tprefix '\"' # single-quoted double-quote character\r\n"
                  "\r\n"
                  "Note: Quoted versions do not allow escape codes,\r\n"
                  "so you cannot do ''', '\\'', \"\"\", or \"\\\"\".";
            sendToUser(QString("Help for %1%2:\r\n%3\r\n\r\n")
                           .arg(prefixChar)
                           .arg(QString::fromStdString(name))
                           .arg(QString::fromStdString(help)));
        });
    add(cmdTime,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            this->showMumeTime();
            return true;
        },
        makeSimpleHelp("Displays the current MUME time."));
    add(cmdTrollExit,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            this->toggleTrollMapping();
            return true;
        },
        makeSimpleHelp("Toggles troll-only exit mapping for direct sunlight."));
    add(cmdVote,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            this->openVoteURL();
            return true;
        },
        makeSimpleHelp("Launches a web browser so you can vote for MUME on TMC!"));

    /* print commands */
    add(cmdPrint,
        [this](const std::vector<StringView> & /*s*/, StringView rest) { return parsePrint(rest); },
        makeSimpleHelp("There is no help for this command yet."));

    add(cmdPDynamic,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            printRoomInfo(dynamicRoomFields);
            return true;
        },
        makeSimpleHelp("Prints current room description."));
    add(cmdPStatic,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            printRoomInfo(staticRoomFields);
            return true;
        },
        makeSimpleHelp("Prints current room description without movable items."));

    add(cmdPNote,
        [this](const std::vector<StringView> & /*s*/, StringView rest) {
            if (!rest.isEmpty())
                return false;
            showNote();
            return true;
        },
        makeSimpleHelp("Print the note in the current room."));

    qInfo() << "Total commands + abbreviations: " << map.size();
}