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:
Correl Roush 2009-05-05 18:14:05 +00:00
parent 8d1a03d239
commit 0e773a5687
8 changed files with 71 additions and 21 deletions

View file

@ -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);

View file

@ -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
;

View file

@ -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();
};

View file

@ -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;

View file

@ -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;

View file

@ -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();

View file

@ -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;
}

View file

@ -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