Now supports aliases that return values.

git-svn-id: file:///srv/svn/ircclient/trunk@8 a9804ffe-773b-11dd-bd7c-89c3ef1d2733
This commit is contained in:
Correl Roush 2009-04-22 18:24:39 +00:00
parent c720c5aa5e
commit b2726144df
5 changed files with 52 additions and 10 deletions

View file

@ -2,6 +2,7 @@
#define MIRC_H #define MIRC_H
#include <QObject> #include <QObject>
#include <QDebug>
#include <QString> #include <QString>
#include <QStringList> #include <QStringList>
#include <QMap> #include <QMap>
@ -10,6 +11,8 @@
#include "script.h" #include "script.h"
#include "parser.h" #include "parser.h"
#define MIRC_VERSION "0.1"
class MIRCScript; class MIRCScript;
class MIRCScriptManager : public QObject { class MIRCScriptManager : public QObject {
@ -20,6 +23,7 @@ private:
QMap<QString, QString> _variables; QMap<QString, QString> _variables;
QMap<QString,void (*)(QStringList)> internal_aliases; QMap<QString,void (*)(QStringList)> internal_aliases;
QMap<QString, mirc_alias> aliases; QMap<QString, mirc_alias> aliases;
QString _return_value;
QTextStream *output; QTextStream *output;
public: public:
MIRCScriptManager(QObject *parent = 0); MIRCScriptManager(QObject *parent = 0);
@ -34,6 +38,9 @@ public:
QString variable(QString variable); QString variable(QString variable);
void variable(QString variable, QString value); void variable(QString variable, QString value);
QMap<QString, QString> variables(); QMap<QString, QString> variables();
QString return_value();
public slots:
void return_value(QString value);
signals: signals:
void unknown_alias(QString alias, QStringList arguments); void unknown_alias(QString alias, QStringList arguments);
}; };

View file

@ -53,6 +53,7 @@ private:
mirc_variables::iterator current_variable; mirc_variables::iterator current_variable;
QStringList current_value; QStringList current_value;
QStack<QStringList> stack; QStack<QStringList> stack;
QString _alias;
public: public:
mirc_engine_stage stage; mirc_engine_stage stage;
@ -66,6 +67,7 @@ public:
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 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*);
void declare_variable(char const* str, char const* end); void declare_variable(char const* str, char const* end);
@ -109,6 +111,7 @@ struct mirc_script : public grammar<mirc_script> {
s_action a_def ( bind( &mirc_script_engine::handle_alias_definition, self.actions, _1, _2 ) ); s_action a_def ( bind( &mirc_script_engine::handle_alias_definition, self.actions, _1, _2 ) );
s_action l_def ( bind( &mirc_script_engine::handle_alias_definition_local, self.actions, _1, _2 ) ); s_action l_def ( bind( &mirc_script_engine::handle_alias_definition_local, self.actions, _1, _2 ) );
s_action a_close ( bind( &mirc_script_engine::close_alias, self.actions, _1, _2 ) ); s_action a_close ( bind( &mirc_script_engine::close_alias, self.actions, _1, _2 ) );
s_action a_set ( bind( &mirc_script_engine::set_alias, self.actions, _1, _2 ) );
s_action a_call ( bind( &mirc_script_engine::call_alias, self.actions, _1, _2 ) ); s_action a_call ( bind( &mirc_script_engine::call_alias, self.actions, _1, _2 ) );
s_action a_return ( bind( &mirc_script_engine::return_alias, self.actions, _1, _2 ) ); s_action a_return ( bind( &mirc_script_engine::return_alias, self.actions, _1, _2 ) );
s_action v_def ( bind( &mirc_script_engine::declare_variable, self.actions, _1, _2 ) ); s_action v_def ( bind( &mirc_script_engine::declare_variable, self.actions, _1, _2 ) );
@ -141,7 +144,7 @@ struct mirc_script : public grammar<mirc_script> {
; ;
value value
= ( variable[v_append][v_fetch] = ( variable[v_append][v_fetch]
| alias_function[v_append] | alias_function[v_append][a_return]
| string[v_append] | string[v_append]
) )
; ;
@ -150,7 +153,8 @@ struct mirc_script : public grammar<mirc_script> {
>> *(+space >> (+(*nospace >> value))[e_append]) >> *(+space >> (+(*nospace >> value))[e_append])
; ;
expression_group expression_group
= expression | expression_group = (*nospace >> *(*(ch_p(',') | ch_p('(') | ch_p(')'))[v_append] >> value))[e_append]
>> *(+space >> (+(*nospace >> *(*(ch_p(',') | ch_p('(') | ch_p(')'))[v_append] >> value))[e_append])[e_append])
; ;
parameters parameters
= expression >> *(*space >> ch_p(',') >> *space >> expression) = expression >> *(*space >> ch_p(',') >> *space >> expression)
@ -166,10 +170,10 @@ struct mirc_script : public grammar<mirc_script> {
; ;
alias_action alias_action
= !ch_p('/') >> !ch_p('/') = !ch_p('/') >> !ch_p('/')
>> (identifier >> *(*space >> parameters))[a_call] >> (identifier[a_set] >> *(*space >> parameters))[a_call]
; ;
alias_function alias_function
= ch_p('$') >> identifier = ch_p('$') >> identifier[a_set]
>> !( >> !(
ch_p('(') >> *space ch_p('(') >> *space
>> parameters >> *space >> parameters >> *space

View file

@ -26,10 +26,28 @@ void MIRCScriptManager::call_alias(QString alias, QStringList arguments) {
internal_aliases[alias](arguments); internal_aliases[alias](arguments);
} else { } else {
//TODO: check known scripted aliases!!! //TODO: check known scripted aliases!!!
emit unknown_alias(alias, arguments);
// Handle some builtins
if (alias == "lower") {
return_value(arguments.join(" ").toLower());
} else if (alias == "version") {
return_value(MIRC_VERSION);
} else {
qDebug() << aliases.keys();
if (aliases.find(alias) != aliases.end()) {
mirc_alias a = aliases[alias];
qDebug() << "SCRIPTED ALIAS" << alias;
}
emit unknown_alias(alias, arguments);
}
} }
} }
QString MIRCScriptManager::return_value() {
return _return_value;
}
void MIRCScriptManager::return_value(QString value) {
_return_value = value;
}
bool MIRCScriptManager::register_alias(QString alias, void (*fn)(QStringList)) { bool MIRCScriptManager::register_alias(QString alias, void (*fn)(QStringList)) {
internal_aliases[alias] = fn; internal_aliases[alias] = fn;
} }

View file

@ -41,14 +41,26 @@ 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::set_alias(char const* str, char const* end) {
string s(str, end);
_alias = s.c_str();
stack.push(QStringList());
}
void mirc_script_engine::call_alias(char const* str, char const* end) { void mirc_script_engine::call_alias(char const* str, char const* end) {
if (stage != EXECUTE) return; if (stage != EXECUTE) return;
string s(str, end); string s(str, end);
QStringList params = QString(s.c_str()).split(" "); QStringList params = QString(s.c_str()).split(" ");
QString alias = params.takeFirst(); QString alias = params.takeFirst();
manager->call_alias(alias, stack.top()); manager->call_alias(alias, stack.top());
stack.pop();
} }
void mirc_script_engine::return_alias(char const*, char const*) { void mirc_script_engine::return_alias(char const* str, char const* end) {
if (stage != EXECUTE) return;
string s(str, end);
manager->call_alias(_alias, stack.top());
stack.pop();
current_value.clear();
current_value << manager->return_value();
} }
void mirc_script_engine::declare_variable(char const* str, char const* end) { void mirc_script_engine::declare_variable(char const* str, char const* end) {
if (stage != EXECUTE) return; if (stage != EXECUTE) return;

View file

@ -3,9 +3,10 @@ set name Correl
%first = Correl %first = Correl
%middle = Joseph %middle = Joseph
%name = %first $& %name = %first $&
%middle $+ Roush $& %middle Roush
$+ ... how are you? echo Hello %name $+ ! $&
echo Hello, %name! How $lower(ArE YoU) $+ ?
echo You're testing Mercenary v $+ $version
alias dostuff { alias dostuff {
; Not very useful, but good for testing the parser! ; Not very useful, but good for testing the parser!
var %b = 42 var %b = 42