mirror of
https://github.com/correl/mercenary.git
synced 2024-11-23 19:19:51 +00:00
Crazed attempts at getting line number info.
git-svn-id: file:///srv/svn/ircclient/trunk@10 a9804ffe-773b-11dd-bd7c-89c3ef1d2733
This commit is contained in:
parent
8d1a03d239
commit
0e773a5687
8 changed files with 71 additions and 21 deletions
|
@ -24,6 +24,9 @@ private:
|
||||||
QMap<QString,void (*)(QStringList)> internal_aliases;
|
QMap<QString,void (*)(QStringList)> internal_aliases;
|
||||||
QString _return_value;
|
QString _return_value;
|
||||||
QTextStream *output;
|
QTextStream *output;
|
||||||
|
MIRCScript* current_script;
|
||||||
|
int line_offset;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MIRCScriptManager(QObject *parent = 0);
|
MIRCScriptManager(QObject *parent = 0);
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <boost/spirit/core.hpp>
|
#include <boost/spirit/core.hpp>
|
||||||
#include <boost/spirit/utility/confix.hpp>
|
#include <boost/spirit/utility/confix.hpp>
|
||||||
#include <boost/spirit/dynamic/if.hpp>
|
#include <boost/spirit/dynamic/if.hpp>
|
||||||
|
#include <boost/spirit/iterator/position_iterator.hpp>
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
@ -28,12 +29,15 @@ using namespace boost;
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
|
|
||||||
typedef QMap<QString, QString> mirc_variables;
|
typedef QMap<QString, QString> mirc_variables;
|
||||||
|
typedef position_iterator<char const*> iterator_t;
|
||||||
|
|
||||||
struct mirc_alias {
|
struct mirc_alias {
|
||||||
mirc_alias(bool _global = true) {
|
mirc_alias(int _line = 0, bool _global = true) {
|
||||||
|
line = _line;
|
||||||
global = _global;
|
global = _global;
|
||||||
}
|
}
|
||||||
bool global;
|
bool global;
|
||||||
|
int line;
|
||||||
QString code;
|
QString code;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,13 +64,17 @@ public:
|
||||||
mirc_alias script;
|
mirc_alias script;
|
||||||
mirc_aliases aliases;
|
mirc_aliases aliases;
|
||||||
mirc_variables vars;
|
mirc_variables vars;
|
||||||
|
int line;
|
||||||
|
|
||||||
mirc_script_engine(MIRCScriptManager *m);
|
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(char const* str, char const* end);
|
||||||
void handle_alias_definition_local(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 close_alias(char const*, char const*);
|
||||||
void store_code(char const* str, char const* end);
|
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 set_alias(char const* str, char const* end);
|
||||||
void call_alias(char const*, char const*);
|
void call_alias(char const*, char const*);
|
||||||
void return_alias(char const*, char const*);
|
void return_alias(char const*, char const*);
|
||||||
|
@ -120,6 +128,7 @@ struct mirc_script : public grammar<mirc_script> {
|
||||||
s_action v_append ( bind( &mirc_script_engine::append_value, self.actions, _1, _2 ) );
|
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 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 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 ) );
|
s_action c_stack ( bind( &mirc_script_engine::clear_stack, self.actions, _1, _2 ) );
|
||||||
|
|
||||||
script
|
script
|
||||||
|
@ -130,7 +139,7 @@ struct mirc_script : public grammar<mirc_script> {
|
||||||
;
|
;
|
||||||
space
|
space
|
||||||
= ( blank_p
|
= ( blank_p
|
||||||
| str_p("$&") >> *blank_p >> eol_p
|
| str_p("$&") >> *blank_p >> eol_p[c_line]
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
nospace
|
nospace
|
||||||
|
@ -183,23 +192,23 @@ struct mirc_script : public grammar<mirc_script> {
|
||||||
alias_definition
|
alias_definition
|
||||||
= str_p("alias") >> *space
|
= str_p("alias") >> *space
|
||||||
>> if_p(str_p("-l") >> *space)[identifier[l_def]].else_p[identifier[a_def]]
|
>> 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_block
|
||||||
;
|
;
|
||||||
code_line
|
code_line
|
||||||
= *space
|
= *space
|
||||||
>> ( comment
|
>> ( comment[c_line]
|
||||||
| (
|
| (
|
||||||
assignment /* Must come first to avoid "var" being caught as an action */
|
assignment /* Must come first to avoid "var" being caught as an action */
|
||||||
| alias_action
|
| alias_action
|
||||||
)[s_code]
|
)[s_code]
|
||||||
)[c_stack]
|
)[c_stack]
|
||||||
>> !eol_p
|
>> !eol_p[c_line]
|
||||||
;
|
;
|
||||||
code_block
|
code_block
|
||||||
= ( *space >> ch_p('{') >> *space >> !eol_p
|
= ( *space >> ch_p('{') >> *space >> !eol_p[c_line]
|
||||||
>> (*code_line)
|
>> (*code_line)
|
||||||
>> ch_p('}') >> *space >> !eol_p
|
>> ch_p('}') >> *space >> !eol_p[c_line]
|
||||||
)
|
)
|
||||||
| code_line
|
| code_line
|
||||||
;
|
;
|
||||||
|
|
|
@ -16,6 +16,8 @@ private:
|
||||||
QMap<QString, QString> _variables;
|
QMap<QString, QString> _variables;
|
||||||
mirc_script_engine *interpreter;
|
mirc_script_engine *interpreter;
|
||||||
mirc_script *parser;
|
mirc_script *parser;
|
||||||
|
iterator_t *begin;
|
||||||
|
iterator_t *end;
|
||||||
bool loaded;
|
bool loaded;
|
||||||
public:
|
public:
|
||||||
MIRCScript(MIRCScriptManager *m);
|
MIRCScript(MIRCScriptManager *m);
|
||||||
|
@ -25,6 +27,7 @@ public:
|
||||||
bool run(QString alias);
|
bool run(QString alias);
|
||||||
QString code();
|
QString code();
|
||||||
QString code(QString alias);
|
QString code(QString alias);
|
||||||
|
int line();
|
||||||
QMap<QString, mirc_alias> aliases();
|
QMap<QString, mirc_alias> aliases();
|
||||||
QMap<QString, QString> variables();
|
QMap<QString, QString> variables();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,26 +1,25 @@
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
#include <QDebug>
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
|
||||||
QTextStream output(stdout);
|
|
||||||
|
|
||||||
void alias_echo(QStringList arguments) {
|
void alias_echo(QStringList arguments) {
|
||||||
output << "[ECHO] " << arguments.join(" ") << "\n";
|
qDebug() << "[ECHO] " << arguments.join(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
output << "* Creating manager\n";
|
// qDebug() << "* Creating manager\n";
|
||||||
MIRCScriptManager *mirc = new MIRCScriptManager;
|
MIRCScriptManager *mirc = new MIRCScriptManager;
|
||||||
mirc->register_alias("echo", &alias_echo);
|
mirc->register_alias("echo", &alias_echo);
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
output << "! No mIRC script file was specified!\n";
|
qDebug() << "! No mIRC script file was specified!\n";
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
output << "* Attempting to load " << argv[1] << "\n";
|
// qDebug() << "* Attempting to load " << argv[1] << "\n";
|
||||||
if (mirc->load(argv[1])) {
|
if (mirc->load(argv[1])) {
|
||||||
// ??
|
// ??
|
||||||
} else {
|
} else {
|
||||||
output << "Failed to load " << argv[1] << "\n";
|
qDebug() << "Failed to load " << argv[1] << "\n";
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
|
|
||||||
MIRCScriptManager::MIRCScriptManager(QObject *parent) {
|
MIRCScriptManager::MIRCScriptManager(QObject *parent) {
|
||||||
this->parent = parent;
|
this->parent = parent;
|
||||||
|
line_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MIRCScriptManager::load(QString filename) {
|
bool MIRCScriptManager::load(QString filename) {
|
||||||
MIRCScript *script = new MIRCScript(this);
|
MIRCScript *script = new MIRCScript(this);
|
||||||
if (script->load(filename)) {
|
if (script->load(filename)) {
|
||||||
scripts << script;
|
scripts << script;
|
||||||
|
current_script = script;
|
||||||
script->run();
|
script->run();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -35,10 +37,10 @@ void MIRCScriptManager::call_alias(QString alias, QStringList arguments) {
|
||||||
if (internal_aliases.find(alias) != internal_aliases.end()) {
|
if (internal_aliases.find(alias) != internal_aliases.end()) {
|
||||||
internal_aliases[alias](arguments);
|
internal_aliases[alias](arguments);
|
||||||
} else {
|
} else {
|
||||||
//TODO: check known scripted aliases!!!
|
|
||||||
|
|
||||||
// Handle some builtins
|
// 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());
|
return_value(arguments.join(" ").toLower());
|
||||||
} else if (alias == "return") {
|
} else if (alias == "return") {
|
||||||
return_value(arguments.join(" "));
|
return_value(arguments.join(" "));
|
||||||
|
@ -58,12 +60,18 @@ void MIRCScriptManager::call_alias(QString alias, QStringList arguments) {
|
||||||
}
|
}
|
||||||
if (found) {
|
if (found) {
|
||||||
MIRCScript *s = new MIRCScript(this);
|
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);
|
QString code = scripts.at(script_index)->code(alias);
|
||||||
if (s->parse(code)) {
|
if (s->parse(code)) {
|
||||||
s->run();
|
s->run();
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "SYNTAX ERROR IN " << alias;
|
qDebug() << "SYNTAX ERROR IN " << alias;
|
||||||
}
|
}
|
||||||
|
current_script = p;
|
||||||
|
line_offset = offset;
|
||||||
delete s;
|
delete s;
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "UNKNOWN ALIAS" << alias;
|
qDebug() << "UNKNOWN ALIAS" << alias;
|
||||||
|
|
|
@ -4,24 +4,29 @@
|
||||||
|
|
||||||
mirc_script_engine::mirc_script_engine(MIRCScriptManager *m) : script() {
|
mirc_script_engine::mirc_script_engine(MIRCScriptManager *m) : script() {
|
||||||
manager = m;
|
manager = m;
|
||||||
stage = PARSE;
|
set_stage(PARSE);
|
||||||
current_alias = aliases.end();
|
current_alias = aliases.end();
|
||||||
current_variable = vars.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) {
|
void mirc_script_engine::handle_alias_definition(char const* str, char const* end) {
|
||||||
if (stage != PARSE) return;
|
if (stage != PARSE) return;
|
||||||
|
|
||||||
string s(str, end);
|
string s(str, end);
|
||||||
QString alias(s.c_str());
|
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);
|
current_alias = this->aliases.find(alias);
|
||||||
}
|
}
|
||||||
void mirc_script_engine::handle_alias_definition_local(char const* str, char const* end) {
|
void mirc_script_engine::handle_alias_definition_local(char const* str, char const* end) {
|
||||||
if (stage != PARSE) return;
|
if (stage != PARSE) return;
|
||||||
|
|
||||||
string s(str, end);
|
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());
|
current_alias = aliases.find(s.c_str());
|
||||||
}
|
}
|
||||||
void mirc_script_engine::close_alias(char const*, char const*) {
|
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");
|
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) {
|
void mirc_script_engine::set_alias(char const* str, char const* end) {
|
||||||
string s(str, end);
|
string s(str, end);
|
||||||
_alias = s.c_str();
|
_alias = s.c_str();
|
||||||
|
|
|
@ -19,6 +19,7 @@ bool MIRCScript::load(QString filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MIRCScript::parse(QString code) {
|
bool MIRCScript::parse(QString code) {
|
||||||
|
const char* _code = code.toLatin1();
|
||||||
parse_info<> info = boost::spirit::parse((const char*)code.toLatin1(), *parser);
|
parse_info<> info = boost::spirit::parse((const char*)code.toLatin1(), *parser);
|
||||||
loaded = info.full;
|
loaded = info.full;
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
|
@ -30,7 +31,18 @@ bool MIRCScript::parse(QString code) {
|
||||||
|
|
||||||
bool MIRCScript::run() {
|
bool MIRCScript::run() {
|
||||||
if (!loaded) return false;
|
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<iterator_t> info = boost::spirit::parse(*begin, *end, *parser);
|
||||||
|
*/
|
||||||
parse_info<> info = boost::spirit::parse((const char*)script.toLatin1(), *parser);
|
parse_info<> info = boost::spirit::parse((const char*)script.toLatin1(), *parser);
|
||||||
if (info.full) {
|
if (info.full) {
|
||||||
_variables = interpreter->vars;
|
_variables = interpreter->vars;
|
||||||
|
@ -55,6 +67,10 @@ QString MIRCScript::code(QString alias) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MIRCScript::line() {
|
||||||
|
return interpreter->line;
|
||||||
|
}
|
||||||
|
|
||||||
QMap<QString, mirc_alias> MIRCScript::aliases() {
|
QMap<QString, mirc_alias> MIRCScript::aliases() {
|
||||||
return _aliases;
|
return _aliases;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
; Hey, here's some test code
|
; 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
|
set name Correl
|
||||||
%first = Correl
|
%first = Correl
|
||||||
%middle = Joseph
|
%middle = Joseph
|
||||||
|
@ -19,5 +22,6 @@ alias -l getversion {
|
||||||
}
|
}
|
||||||
alias -l showversion {
|
alias -l showversion {
|
||||||
echo You're testing Mercenary $getversion
|
echo You're testing Mercenary $getversion
|
||||||
|
echo TEST Code line match [ 23 = $line ]
|
||||||
}
|
}
|
||||||
dostuff
|
dostuff
|
||||||
|
|
Loading…
Reference in a new issue