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

View file

@ -53,6 +53,7 @@ private:
mirc_variables::iterator current_variable;
QStringList current_value;
QStack<QStringList> stack;
QString _alias;
public:
mirc_engine_stage stage;
@ -66,6 +67,7 @@ public:
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 set_alias(char const* str, char const* end);
void call_alias(char const*, char const*);
void return_alias(char const*, char const*);
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 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_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_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 ) );
@ -141,7 +144,7 @@ struct mirc_script : public grammar<mirc_script> {
;
value
= ( variable[v_append][v_fetch]
| alias_function[v_append]
| alias_function[v_append][a_return]
| string[v_append]
)
;
@ -150,7 +153,8 @@ struct mirc_script : public grammar<mirc_script> {
>> *(+space >> (+(*nospace >> value))[e_append])
;
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
= expression >> *(*space >> ch_p(',') >> *space >> expression)
@ -166,10 +170,10 @@ struct mirc_script : public grammar<mirc_script> {
;
alias_action
= !ch_p('/') >> !ch_p('/')
>> (identifier >> *(*space >> parameters))[a_call]
>> (identifier[a_set] >> *(*space >> parameters))[a_call]
;
alias_function
= ch_p('$') >> identifier
= ch_p('$') >> identifier[a_set]
>> !(
ch_p('(') >> *space
>> parameters >> *space

View file

@ -26,10 +26,28 @@ void MIRCScriptManager::call_alias(QString alias, QStringList arguments) {
internal_aliases[alias](arguments);
} else {
//TODO: check known scripted aliases!!!
// 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)) {
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");
}
}
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) {
if (stage != EXECUTE) return;
string s(str, end);
QStringList params = QString(s.c_str()).split(" ");
QString alias = params.takeFirst();
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) {
if (stage != EXECUTE) return;

View file

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