mirror of
https://github.com/correl/mercenary.git
synced 2024-12-27 11:09:33 +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;
|
||||
QString _return_value;
|
||||
QTextStream *output;
|
||||
MIRCScript* current_script;
|
||||
int line_offset;
|
||||
|
||||
public:
|
||||
MIRCScriptManager(QObject *parent = 0);
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/utility/confix.hpp>
|
||||
#include <boost/spirit/dynamic/if.hpp>
|
||||
#include <boost/spirit/iterator/position_iterator.hpp>
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
@ -28,12 +29,15 @@ using namespace boost;
|
|||
using namespace boost::spirit;
|
||||
|
||||
typedef QMap<QString, QString> mirc_variables;
|
||||
typedef position_iterator<char const*> 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<mirc_script> {
|
|||
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<mirc_script> {
|
|||
;
|
||||
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<mirc_script> {
|
|||
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
|
||||
;
|
||||
|
|
|
@ -16,6 +16,8 @@ private:
|
|||
QMap<QString, QString> _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<QString, mirc_alias> aliases();
|
||||
QMap<QString, QString> variables();
|
||||
};
|
||||
|
|
|
@ -1,26 +1,25 @@
|
|||
#include <QTextStream>
|
||||
#include <QDebug>
|
||||
#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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<iterator_t> 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<QString, mirc_alias> MIRCScript::aliases() {
|
||||
return _aliases;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue