From 0daa494480f7abe37a6e593c6238811009b7b914 Mon Sep 17 00:00:00 2001 From: Zoffix Znet Date: Fri, 3 Jun 2016 07:01:14 -0400 Subject: Start rewrite --- lib/IRC/Client.pm6 | 56 ++++++++++++++++++++++++++++++++++++++ lib/IRC/Client/Grammar.pm6 | 21 ++++++++++++++ lib/IRC/Client/Grammar/Actions.pm6 | 31 +++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 lib/IRC/Client/Grammar.pm6 create mode 100644 lib/IRC/Client/Grammar/Actions.pm6 (limited to 'lib/IRC') diff --git a/lib/IRC/Client.pm6 b/lib/IRC/Client.pm6 index e69de29..7c30c4a 100644 --- a/lib/IRC/Client.pm6 +++ b/lib/IRC/Client.pm6 @@ -0,0 +1,56 @@ +unit class IRC::Client; + +use IRC::Client::Grammar; +use IRC::Client::Grammar::Actions; + +has Str:D $.host = 'localhost'; +has Bool $.debug = False; +has Str $.password; +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 = ['#perl6']; +has @.plugins; +has IO::Socket::Async $!sock; + +method run { + await IO::Socket::Async.connect( $!host, $!port ).then({ + $!sock = .result; + self!ssay: "PASS $!password\n" if $!password.defined; + self!ssay: "NICK $!nick\n"; + self!ssay: "USER $!username $!username $!host :$!userreal\n"; + + my $left-overs = ''; + react { + whenever $!sock.Supply :bin -> $buf is copy { + my $str = try $buf.decode: 'utf8'; + $str or $str = $buf.decode: 'latin-1'; + $str ~= $left-overs; + $!debug and "[server {DateTime.now}] {$str}".put; + (my $events, $left-overs) = IRC::Client::Grammar.parse( + $str, actions => IRC::Client::Grammar::Actions + ).made; + + for @$events -> $e { + say "[event] $e"; + CATCH { warn .backtrace } + } + } + + CATCH { warn .backtrace } + } + + say "Closing connection"; + $!sock.close; + + # CATCH { warn .backtrace } + }); +} + +method !ssay (Str:D $msg) { + $!debug and "$msg".put; + $!sock.print("$msg\n"); + self; +} diff --git a/lib/IRC/Client/Grammar.pm6 b/lib/IRC/Client/Grammar.pm6 new file mode 100644 index 0000000..255528a --- /dev/null +++ b/lib/IRC/Client/Grammar.pm6 @@ -0,0 +1,21 @@ +unit grammar IRC::Client::Grammar; +token TOP { + } +token leftovers { \N* } +token SPACE { ' '+ } +token message { [':' ]? \n } + token prefix { + [ || ['!' ]? ['@' ]? ] + > + } + token servername { } + token nick { [ | | ]* } + token user { <-[\ \x0\r\n]>+? | '@']>} + token host { <-[\s!@]>+ } + token command { + | **3 } + token params { * [ ':' | ]? } + token middle { <-[:\ \x0\r\n]> <-[\ \x0\r\n]>* } + token trailing { <-[\x0\r\n]>* } + + token letter { <[a..zA..Z]> } + token number { <[0..9]> } + token special { <[-_\[\]\\`^{}]> } diff --git a/lib/IRC/Client/Grammar/Actions.pm6 b/lib/IRC/Client/Grammar/Actions.pm6 new file mode 100644 index 0000000..74ae4e8 --- /dev/null +++ b/lib/IRC/Client/Grammar/Actions.pm6 @@ -0,0 +1,31 @@ +unit class IRC::Client::Grammar::Actions; + +method TOP ($/) { $/.make: ($ยป.made, $) } +method left-overs ($/) { + $/.made: $/.defined ?? !$/ !! ''; +} + +method message ($/) { + my $pref = $/; + my %args = command => ~$/; + for qw/nick user host/ { + $pref{$_}.defined or next; + %args{$_} = $pref{$_}.Str; + } + %args = ~$pref if $pref.defined; + + my $p = $/; + + for ^100 { # bail out after 100 iterations; we're stuck + if ( $p.defined ) { + %args.append: ~$p; + } + if ( $p.defined ) { + %args.append: ~$p; + last; + } + $p = $p; + } + + $/.make: %args; +} -- cgit v1.1