aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--DESIGN-NOTES.md41
-rw-r--r--examples/bot.pl64
-rw-r--r--lib/IRC/Client.pm624
-rw-r--r--lib/IRC/Grammar.pm639
-rw-r--r--lib/IRC/Grammar/Actions.pm66
-rw-r--r--test.p637
7 files changed, 138 insertions, 14 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4a5e4c7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+lib/.precomp
diff --git a/DESIGN-NOTES.md b/DESIGN-NOTES.md
index b91ec73..84b93a7 100644
--- a/DESIGN-NOTES.md
+++ b/DESIGN-NOTES.md
@@ -23,3 +23,44 @@ Each IRC message may consist of up to three main parts: the prefix (optional),
the command, and the command parameters (of which there may be up to 15). The
prefix, command, and all parameters are separated by one (or more) ASCII space
character(s) (0x20).
+
+***Clients should not use prefix when sending a message from themselves;***
+
+The command must either be a valid IRC command or a three (3) digit number represented in ASCII text.
+
+IRC messages are always lines of characters terminated with a CR-LF (Carriage Return - Line Feed) pair, and these messages shall ***not exceed 512 characters*** in length, counting all characters **including the trailing CR-LF**. Thus, there are 510 characters maximum allowed for the command and its parameters. There is no provision for continuation message lines. See section 7 for more details about current implementations.
+
+
+The BNF representation for this is:
+
+::=
+
+[':' <prefix> <SPACE> ] <command> <params> <crlf>
+
+::=
+
+<servername> | <nick> [ '!' <user> ] [ '@' <host> ]
+
+::=
+
+<letter> { <letter> } | <number> <number> <number>
+
+::=
+
+' ' { ' ' }
+
+::=
+
+<SPACE> [ ':' <trailing> | <middle> <params> ]
+
+::=
+
+<Any *non-empty* sequence of octets not including SPACE or NUL or CR or LF, the first of which may not be ':'>
+
+::=
+
+<Any, possibly *empty*, sequence of octets not including NUL or CR or LF>
+
+::=
+
+CR LF
diff --git a/examples/bot.pl6 b/examples/bot.pl6
index 00a8406..3bd14cc 100644
--- a/examples/bot.pl6
+++ b/examples/bot.pl6
@@ -1,12 +1,12 @@
use v6;
use lib 'lib';
use IRC::Client;
-use IRC::Client::Plugin::HNY;
+# use IRC::Client::Plugin::HNY;
my $irc = IRC::Client.new(
:host('irc.freenode.net'),
:debug,
plugins => [
- IRC::Client::Plugin::HNY.new,
+ # IRC::Client::Plugin::HNY.new,
]
).run;
diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6
index ae8f245..4635301 100644
--- a/lib/IRC/Client.pm6
+++ b/lib/IRC/Client.pm6
@@ -1,16 +1,16 @@
use v6;
role IRC::Client::Plugin { ... }
class IRC::Client:ver<1.001001> {
- has Bool $.debug = False;
- has Str $.host = 'localhost';
- has Int $.port where 0 <= $_ <= 65535 = 6667;
- has Str $.nick where 1 <= .chars <= 9 = 'Perl6IRC';
- has Str $.username = 'Perl6IRC';
- has Str $.userhost = 'localhost';
- has Str $.userreal = 'Perl6 IRC Client';
- has Str @.channels = ['#perl6bot'];
- has @.plugins = [];
- has IO::Socket::Async $.sock;
+ has Bool:D $.debug = False;
+ has Str:D $.host = 'localhost';
+ has Int:D $.port where 0 <= $_ <= 65535 = 6667;
+ has Str:D $.nick = 'Perl6IRC';
+ has Str:D $.username = 'Perl6IRC';
+ has Str:D $.userhost = 'localhost';
+ has Str:D $.userreal = 'Perl6 IRC Client';
+ has Str:D @.channels = ['#perl6bot'];
+ has IRC::Client::Plugin @.plugins = [];
+ has IO::Socket::Async $.sock;
method run {
await IO::Socket::Async.connect( $!host, $!port ).then({
@@ -23,8 +23,8 @@ class IRC::Client:ver<1.001001> {
for @!plugins.grep(*.interval);
react {
- whenever $!sock.chars-supply -> $str is copy {
- $str.say;
+ whenever $!sock.Supply -> $str is copy {
+ "[$str]".perl.say;
.msg(self, $str) for @!plugins.grep(so *.msg);
}
}
diff --git a/lib/IRC/Grammar.pm6 b/lib/IRC/Grammar.pm6
new file mode 100644
index 0000000..2013b9b
--- /dev/null
+++ b/lib/IRC/Grammar.pm6
@@ -0,0 +1,39 @@
+# use Grammar::Debugger;
+unit grammar IRC::Grammar:ver<1.001001>;
+token ws { ' ' }
+token TOP { [ <message> \r\n ]* }
+token message { [':' <prefix> ' '+ ]? <command> <params> }
+token prefix { [<servername> | <nick>] [ '!' <user> ]? [ '@' <host> ]? }
+token command { <letter>+ | <number>**3 }
+token params { ' '+ [ ':' <trailing> | <middle> <params> ]? }
+token middle { <-[: \0\r\n]> <-[ \0\r\n]>+ }
+token trailing { <-[\0\r\n]>+ }
+token target { <to> [ ',' <target> ]? }
+token to { <channel> | <user> '@' <servername> | <nick> | <mask> }
+token channel { ['#' | '&'] <chstring> }
+token servername { \S+ } # see RFC 952 [DNS:4] for details on allowed hostnames
+token nick { <letter> [ <letter> | <number> | <special> ]+ }
+token mask { <[#$]> <chstring> }
+token chstring { <-[ \a\0\r\l,]> }
+token user { <-[ \0\r\l]>+ }
+token letter { <[a..zA..Z]> }
+token number { <[0..9]> }
+token special { <[-\[\]\\`^{}]> }
+
+# unit class IRC::Grammar::Actions:ver<1.001001>;
+# method TOP ($/) { $/.make: $<message>».made }
+# method message ($/) { $/.make:
+# prefix => $<prefix> .made,
+# command => $<command>.made,
+# params => $<params .made,
+# }
+# method prefix ($/) { [<servername> | <nick>] [ '!' <user> ]? [ '@' <host> ]? }
+# method command ($/) { <letter>+ | <number>**3 }
+# method params ($/) { ' '+ [ ':' <trailing> | <middle> <params> ]? }
+# method middle ($/) { <-[: \0\r\n]> <-[ \0\r\n]>+ }
+# method trailing ($/) { <-[\0\r\n]> }
+#
+# method class ($/) { $/.make: ~$/ }
+# method rules ($/) { $/.make: ~$/ }
+# method pair ($/) { $/.make: $<class>.made => $<rules>.made }
+# method TOP ($/) { $/.make: $<pair>».made }
diff --git a/lib/IRC/Grammar/Actions.pm6 b/lib/IRC/Grammar/Actions.pm6
new file mode 100644
index 0000000..039f11e
--- /dev/null
+++ b/lib/IRC/Grammar/Actions.pm6
@@ -0,0 +1,6 @@
+class IRC::Grammar::Actions {
+ method class ($/) { $/.make: ~$/ }
+ method rules ($/) { $/.make: ~$/ }
+ method pair ($/) { $/.make: $<class>.made => $<rules>.made }
+ method TOP ($/) { $/.make: $<pair>».made }
+}
diff --git a/test.p6 b/test.p6
new file mode 100644
index 0000000..a1f5062
--- /dev/null
+++ b/test.p6
@@ -0,0 +1,37 @@
+use v6;
+# use Grammar::Tracer;
+grammar IRC::Grammar:ver<1.001001> {
+ token TOP { [ <message> \n ] }
+ token message { [':' <prefix> ' '+ ]? <command> <params> }
+ token prefix { <servername> | <nick> ['!' <user>]? ['@' <host> ]? }
+ token command { <letter>+ | <number>**3 }
+ token params { ' '* [ ':' <trailing> | <middle> <params> ]? }
+ token middle { <-[: \0\r\n]> <-[ \0\r\n]>+ }
+ token trailing { <-[\0\r\n]>+ }
+ token target { <to> [ ',' <target> ]? }
+ token to { <channel> | <user> '@' <servername> | <nick> | <mask> }
+ token channel { ['#' | '&'] <chstring> }
+ token servername { <host> }
+ token host { \S+ }# see RFC 952 [DNS:4] for allowed hostnames
+ token nick { <letter> [ <letter> | <number> | <special> ]+ }
+ token mask { <[#$]> <chstring> }
+ token chstring { <-[ \a\0\r\l,]> }
+ token user { <-[ \0\r\l]>+ }
+ token letter { <[a..zA..Z]> }
+ token number { <[0..9]> }
+ token special { <[-\[\]\\`^{}]> }
+}
+
+class IRC::Grammar::Actions {
+ # method class ($/) { $/.make: ~$/ }
+ # method rules ($/) { $/.make: ~$/ }
+ # method pair ($/) { $/.make: $<class>.made => $<rules>.made }
+ # method command ($/) { $/.make: $<command> }
+ method message ($/) { $/.make: 42 }
+ method TOP ($/) { $/.make: $<message>».made; } #$<message>».made }
+ # }
+}
+
+my $res = IRC::Grammar.parse(":verne.freenode.net 372 Perl6IRC :- running for their sustained support.\r\n", :actions(IRC::Grammar::Actions)).made;
+say $res;
+# say $res<command>;