diff --git a/mirc/includes/mirc.h b/mirc/includes/mirc.h index 5a523d6..f8c95dc 100644 --- a/mirc/includes/mirc.h +++ b/mirc/includes/mirc.h @@ -24,6 +24,9 @@ private: QMap internal_aliases; QString _return_value; QTextStream *output; + MIRCScript* current_script; + int line_offset; + public: MIRCScriptManager(QObject *parent = 0); diff --git a/mirc/includes/parser.h b/mirc/includes/parser.h index 1d09b9f..70819d0 100644 --- a/mirc/includes/parser.h +++ b/mirc/includes/parser.h @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -28,12 +29,15 @@ using namespace boost; using namespace boost::spirit; typedef QMap mirc_variables; +typedef position_iterator iterator_t; struct mirc_alias { - mirc_alias(bool _global = true) { + mirc_alias(int _line = 0, bool _global = true) { + line = _line; global = _global; } bool global; + int line; QString code; }; @@ -60,13 +64,17 @@ public: mirc_alias script; mirc_aliases aliases; mirc_variables vars; + int line; mirc_script_engine(MIRCScriptManager *m); + void set_stage(mirc_engine_stage _stage); + void handle_alias_definition(char const* str, char const* end); void handle_alias_definition_local(char const* str, char const* end); void close_alias(char const*, char const*); void store_code(char const* str, char const* end); + void code_line(char const* str, char const* end); void set_alias(char const* str, char const* end); void call_alias(char const*, char const*); void return_alias(char const*, char const*); @@ -120,6 +128,7 @@ struct mirc_script : public grammar { s_action v_append ( bind( &mirc_script_engine::append_value, self.actions, _1, _2 ) ); s_action e_append ( bind( &mirc_script_engine::append_expression, self.actions, _1, _2 ) ); s_action s_code ( bind( &mirc_script_engine::store_code, self.actions, _1, _2 ) ); + s_action c_line (bind( &mirc_script_engine::code_line, self.actions, _1, _2 ) ); s_action c_stack ( bind( &mirc_script_engine::clear_stack, self.actions, _1, _2 ) ); script @@ -130,7 +139,7 @@ struct mirc_script : public grammar { ; space = ( blank_p - | str_p("$&") >> *blank_p >> eol_p + | str_p("$&") >> *blank_p >> eol_p[c_line] ) ; nospace @@ -183,23 +192,23 @@ struct mirc_script : public grammar { alias_definition = str_p("alias") >> *space >> if_p(str_p("-l") >> *space)[identifier[l_def]].else_p[identifier[a_def]] - >> *space >> !eol_p + >> *space >> !eol_p[c_line] >> code_block ; code_line = *space - >> ( comment + >> ( comment[c_line] | ( assignment /* Must come first to avoid "var" being caught as an action */ | alias_action )[s_code] )[c_stack] - >> !eol_p + >> !eol_p[c_line] ; code_block - = ( *space >> ch_p('{') >> *space >> !eol_p + = ( *space >> ch_p('{') >> *space >> !eol_p[c_line] >> (*code_line) - >> ch_p('}') >> *space >> !eol_p + >> ch_p('}') >> *space >> !eol_p[c_line] ) | code_line ; diff --git a/mirc/includes/script.h b/mirc/includes/script.h index 0c86160..c20ef75 100644 --- a/mirc/includes/script.h +++ b/mirc/includes/script.h @@ -16,6 +16,8 @@ private: QMap _variables; mirc_script_engine *interpreter; mirc_script *parser; + iterator_t *begin; + iterator_t *end; bool loaded; public: MIRCScript(MIRCScriptManager *m); @@ -25,6 +27,7 @@ public: bool run(QString alias); QString code(); QString code(QString alias); + int line(); QMap aliases(); QMap variables(); }; diff --git a/mirc/src/main.cpp b/mirc/src/main.cpp index 52d0e98..6326a00 100644 --- a/mirc/src/main.cpp +++ b/mirc/src/main.cpp @@ -1,26 +1,25 @@ #include +#include #include "script.h" -QTextStream output(stdout); - void alias_echo(QStringList arguments) { - output << "[ECHO] " << arguments.join(" ") << "\n"; + qDebug() << "[ECHO] " << arguments.join(" "); } int main(int argc, char* argv[]) { - output << "* Creating manager\n"; +// qDebug() << "* Creating manager\n"; MIRCScriptManager *mirc = new MIRCScriptManager; mirc->register_alias("echo", &alias_echo); if (argc < 2) { - output << "! No mIRC script file was specified!\n"; + qDebug() << "! No mIRC script file was specified!\n"; return(1); } - output << "* Attempting to load " << argv[1] << "\n"; +// qDebug() << "* Attempting to load " << argv[1] << "\n"; if (mirc->load(argv[1])) { // ?? } else { - output << "Failed to load " << argv[1] << "\n"; + qDebug() << "Failed to load " << argv[1] << "\n"; return(1); } return 0; diff --git a/mirc/src/mirc.cpp b/mirc/src/mirc.cpp index 1a9e011..dd751cf 100644 --- a/mirc/src/mirc.cpp +++ b/mirc/src/mirc.cpp @@ -2,12 +2,14 @@ MIRCScriptManager::MIRCScriptManager(QObject *parent) { this->parent = parent; + line_offset = 0; } bool MIRCScriptManager::load(QString filename) { MIRCScript *script = new MIRCScript(this); if (script->load(filename)) { scripts << script; + current_script = script; script->run(); return true; } @@ -35,10 +37,10 @@ void MIRCScriptManager::call_alias(QString alias, QStringList arguments) { if (internal_aliases.find(alias) != internal_aliases.end()) { internal_aliases[alias](arguments); } else { - //TODO: check known scripted aliases!!! - // Handle some builtins - if (alias == "lower") { + if (alias == "line") { + return_value(QString::number(current_script->line() + line_offset)); + } else if (alias == "lower") { return_value(arguments.join(" ").toLower()); } else if (alias == "return") { return_value(arguments.join(" ")); @@ -58,12 +60,18 @@ void MIRCScriptManager::call_alias(QString alias, QStringList arguments) { } if (found) { MIRCScript *s = new MIRCScript(this); + MIRCScript *p = current_script; + int offset = line_offset; + line_offset = scripts.at(script_index)->aliases()[alias].line; + current_script = s; QString code = scripts.at(script_index)->code(alias); if (s->parse(code)) { s->run(); } else { qDebug() << "SYNTAX ERROR IN " << alias; } + current_script = p; + line_offset = offset; delete s; } else { qDebug() << "UNKNOWN ALIAS" << alias; diff --git a/mirc/src/parser.cpp b/mirc/src/parser.cpp index e5960e1..a4e9d3b 100644 --- a/mirc/src/parser.cpp +++ b/mirc/src/parser.cpp @@ -4,24 +4,29 @@ mirc_script_engine::mirc_script_engine(MIRCScriptManager *m) : script() { manager = m; - stage = PARSE; + set_stage(PARSE); current_alias = aliases.end(); current_variable = vars.end(); } +void mirc_script_engine::set_stage(mirc_engine_stage _stage) { + this->stage = _stage; + this->line = 1; +} + void mirc_script_engine::handle_alias_definition(char const* str, char const* end) { if (stage != PARSE) return; string s(str, end); QString alias(s.c_str()); - this->aliases.insert(alias, mirc_alias(true)); + this->aliases.insert(alias, mirc_alias(line, true)); current_alias = this->aliases.find(alias); } void mirc_script_engine::handle_alias_definition_local(char const* str, char const* end) { if (stage != PARSE) return; string s(str, end); - aliases.insert(s.c_str(), mirc_alias(false)); + aliases.insert(s.c_str(), mirc_alias(line, false)); current_alias = aliases.find(s.c_str()); } void mirc_script_engine::close_alias(char const*, char const*) { @@ -41,6 +46,9 @@ void mirc_script_engine::store_code(char const* str, char const* end) { script.code.append(s.c_str()).append("\n"); } } +void mirc_script_engine::code_line(char const* str, char const* end) { + line++; +} void mirc_script_engine::set_alias(char const* str, char const* end) { string s(str, end); _alias = s.c_str(); diff --git a/mirc/src/script.cpp b/mirc/src/script.cpp index ff0e572..7bbaa85 100644 --- a/mirc/src/script.cpp +++ b/mirc/src/script.cpp @@ -19,6 +19,7 @@ bool MIRCScript::load(QString filename) { } bool MIRCScript::parse(QString code) { + const char* _code = code.toLatin1(); parse_info<> info = boost::spirit::parse((const char*)code.toLatin1(), *parser); loaded = info.full; if (loaded) { @@ -30,7 +31,18 @@ bool MIRCScript::parse(QString code) { bool MIRCScript::run() { if (!loaded) return false; - interpreter->stage = EXECUTE; + interpreter->set_stage(EXECUTE); +// interpreter->stage = EXECUTE; +// interpreter->line = 0; +// iterator_t begin(_code, _code+strlen(_code)); +// iterator_t end; + + /* Doing it this way affects all the damned callbacks... + const char* _code = (const char*)script.toLatin1(); + begin = new iterator_t(_code, _code+strlen(_code)); + end = new iterator_t(); + parse_info info = boost::spirit::parse(*begin, *end, *parser); + */ parse_info<> info = boost::spirit::parse((const char*)script.toLatin1(), *parser); if (info.full) { _variables = interpreter->vars; @@ -55,6 +67,10 @@ QString MIRCScript::code(QString alias) { } } +int MIRCScript::line() { + return interpreter->line; +} + QMap MIRCScript::aliases() { return _aliases; } diff --git a/mirc/test.mrc b/mirc/test.mrc index b54fe7b..5f68825 100644 --- a/mirc/test.mrc +++ b/mirc/test.mrc @@ -1,4 +1,7 @@ ; Hey, here's some test code +echo TEST Code line match [ 2 = $line ] +; Test comment +echo TEST Code line match [ 4 = $line ] set name Correl %first = Correl %middle = Joseph @@ -19,5 +22,6 @@ alias -l getversion { } alias -l showversion { echo You're testing Mercenary $getversion + echo TEST Code line match [ 23 = $line ] } dostuff