! Copyright (C) 2009 Bruno Deferrari ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays assocs classes.parser classes.tuple combinators fry generic.parser kernel lexer mirrors namespaces parser sequences splitting strings words ; IN: irc.messages.base TUPLE: irc-message line prefix command parameters trailing timestamp sender ; TUPLE: unhandled < irc-message ; SYMBOL: string-irc-type-mapping string-irc-type-mapping [ H{ } clone ] initialize : register-irc-message-type ( type string -- ) string-irc-type-mapping get set-at ; : irc>type ( string -- irc-message-class ) string-irc-type-mapping get at unhandled or ; GENERIC: irc-trailing-slot ( irc-message -- string/f ) M: irc-message irc-trailing-slot drop f ; GENERIC: irc-parameter-slots ( irc-message -- seq ) M: irc-message irc-parameter-slots drop f ; GENERIC: process-irc-trailing ( irc-message -- ) M: irc-message process-irc-trailing dup irc-trailing-slot [ swap [ trailing>> swap ] [ ] bi set-at ] [ drop ] if* ; GENERIC: process-irc-prefix ( irc-message -- ) M: irc-message process-irc-prefix drop ; GENERIC: process-irc-parameters ( irc-message -- ) M: irc-message process-irc-parameters dup irc-parameter-slots [ swap [ parameters>> swap ] [ [slot-setter] ] bi 2each ] [ drop ] if* ; GENERIC: post-process-irc-message ( irc-message -- ) M: irc-message post-process-irc-message drop ; GENERIC: fill-irc-message-slots ( irc-message -- ) M: irc-message fill-irc-message-slots { [ process-irc-trailing ] [ process-irc-prefix ] [ process-irc-parameters ] [ post-process-irc-message ] } cleave ; GENERIC: irc-command-string ( irc-message -- string ) M: irc-message irc-command-string drop f ; ! FIXME: inverse of post-process is missing GENERIC: set-irc-parameters ( irc-message -- ) M: irc-message set-irc-parameters dup irc-parameter-slots [ over '[ _ at ] map >>parameters ] when* drop ; GENERIC: set-irc-trailing ( irc-message -- ) M: irc-message set-irc-trailing dup irc-trailing-slot [ over at >>trailing ] when* drop ; GENERIC: set-irc-command ( irc-message -- ) M: irc-message set-irc-command [ irc-command-string ] [ (>>command) ] bi ; : irc-message>string ( irc-message -- string ) { [ prefix>> ] [ command>> ] [ parameters>> " " join ] [ trailing>> dup [ CHAR: : prefix ] when ] } cleave 4array sift " " join ; #! SYNTAX: #! IRC: type "COMMAND" slot1 ...; #! IRC: type "COMMAND" slot1 ... : trailing-slot; : IRC: ( name string parameters -- ) CREATE-CLASS [ scan-object register-irc-message-type ] keep ";" parse-tokens [ define-irc-class ] [ define-irc-parameter-slots ] 2bi ; parsing