tail call optimization
parent
b2cebbb5e4
commit
daac96e764
|
@ -1,49 +1,105 @@
|
||||||
! A simple IRC client written in Factor.
|
! A simple IRC client written in Factor.
|
||||||
|
|
||||||
|
IN: irc
|
||||||
|
USE: generic
|
||||||
USE: stdio
|
USE: stdio
|
||||||
USE: namespaces
|
USE: namespaces
|
||||||
USE: streams
|
USE: streams
|
||||||
USE: kernel
|
USE: kernel
|
||||||
USE: threads
|
USE: threads
|
||||||
|
USE: lists
|
||||||
|
USE: strings
|
||||||
|
USE: words
|
||||||
|
USE: math
|
||||||
|
|
||||||
SYMBOL: irc-stream
|
SYMBOL: irc-stream
|
||||||
|
SYMBOL: channels
|
||||||
SYMBOL: channel
|
SYMBOL: channel
|
||||||
|
SYMBOL: nickname
|
||||||
|
|
||||||
: irc-write ( str -- )
|
: irc-write ( s -- ) irc-stream get fwrite ;
|
||||||
irc-stream get fwrite ;
|
: irc-print ( s -- ) irc-stream get fprint irc-stream get fflush ;
|
||||||
|
|
||||||
: irc-print ( str -- )
|
: nick ( nick -- )
|
||||||
irc-stream get fprint irc-stream get fflush ;
|
dup nickname set "NICK " irc-write irc-print ;
|
||||||
|
|
||||||
: join ( chan -- )
|
|
||||||
dup channel set "JOIN " irc-write irc-print ;
|
|
||||||
|
|
||||||
: login ( nick -- )
|
: login ( nick -- )
|
||||||
"NICK " irc-write dup irc-print
|
dup nick
|
||||||
"USER " irc-write irc-write
|
"USER " irc-write irc-write
|
||||||
" hostname servername :irc.factor" irc-print ;
|
" hostname servername :irc.factor" irc-print ;
|
||||||
|
|
||||||
: connect ( channel nick server -- )
|
: connect ( server -- ) 6667 <client> irc-stream set ;
|
||||||
6667 <client> irc-stream set login join ;
|
|
||||||
|
: write-highlighted ( line -- )
|
||||||
|
dup nickname get index-of -1 =
|
||||||
|
f [ [ "ansi-fg" | "3" ] ] ? write-attr ;
|
||||||
|
|
||||||
|
: extract-nick ( line -- nick )
|
||||||
|
"!" split1 drop ;
|
||||||
|
|
||||||
|
: write-nick ( line -- )
|
||||||
|
"!" split1 drop [ [ "bold" | t ] ] write-attr ;
|
||||||
|
|
||||||
|
GENERIC: irc-display
|
||||||
|
PREDICATE: string privmsg "PRIVMSG" index-of -1 > ;
|
||||||
|
PREDICATE: string action "ACTION" index-of -1 > ;
|
||||||
|
|
||||||
|
M: string irc-display ( line -- )
|
||||||
|
print ;
|
||||||
|
|
||||||
|
M: privmsg irc-display ( line -- )
|
||||||
|
"PRIVMSG" split1 >r write-nick r>
|
||||||
|
write-highlighted terpri flush ;
|
||||||
|
|
||||||
|
! Doesn't look good
|
||||||
|
! M: action irc-display ( line -- )
|
||||||
|
! " * " write
|
||||||
|
! "ACTION" split1 >r write-nick r>
|
||||||
|
! write-highlighted terpri flush ;
|
||||||
|
|
||||||
: in-loop ( -- )
|
: in-loop ( -- )
|
||||||
irc-stream get freadln [ print in-loop ] when* ;
|
irc-stream get freadln [ irc-display in-loop ] when* ;
|
||||||
|
|
||||||
: say ( input -- )
|
: input-thread ( -- ) [ in-loop ] in-thread ;
|
||||||
"PRIVMSG " irc-write
|
: disconnect ( -- ) irc-stream get fclose ;
|
||||||
channel get irc-write
|
|
||||||
" :" irc-write irc-print ;
|
|
||||||
|
|
||||||
: say-loop ( -- )
|
: command ( line -- )
|
||||||
read [ say say-loop ] when* ;
|
#! IRC /commands are just words.
|
||||||
|
" " split1 swap [
|
||||||
|
"irc" "listener" "parser" "scratchpad"
|
||||||
|
] search execute ;
|
||||||
|
|
||||||
: disconnect ( -- )
|
: (msg) ( line nick -- )
|
||||||
irc-stream get fclose ;
|
"PRIVMSG " irc-write irc-write " :" irc-write irc-print ;
|
||||||
|
|
||||||
: input-thread ( -- )
|
: say ( line -- )
|
||||||
[ in-loop ] in-thread ;
|
channel get [ (msg) ] [ "No channel." print ] ifte* ;
|
||||||
|
|
||||||
: irc ( channel nick server -- )
|
: talk ( input -- ) "/" ?str-head [ command ] [ say ] ifte ;
|
||||||
[ connect input-thread say-loop disconnect ] with-scope ;
|
: talk-loop ( -- ) read [ talk talk-loop ] when* ;
|
||||||
|
|
||||||
"#concatenative" "conc" "irc.freenode.net" irc
|
: irc ( nick server -- )
|
||||||
|
[
|
||||||
|
channels off
|
||||||
|
channel off
|
||||||
|
connect
|
||||||
|
login
|
||||||
|
input-thread
|
||||||
|
talk-loop
|
||||||
|
disconnect
|
||||||
|
] with-scope ;
|
||||||
|
|
||||||
|
! /commands
|
||||||
|
: join ( chan -- )
|
||||||
|
dup channels [ cons ] change
|
||||||
|
dup channel set
|
||||||
|
"JOIN " irc-write irc-print ;
|
||||||
|
|
||||||
|
: leave ( chan -- )
|
||||||
|
dup channels [ remove ] change
|
||||||
|
channels get dup [ car ] when channel set
|
||||||
|
"PART " irc-write irc-print ;
|
||||||
|
|
||||||
|
: msg ( line -- ) " " split1 swap (msg) ;
|
||||||
|
: me ( line -- ) "\u0001ACTION " swap "\u0001" cat3 say ;
|
||||||
|
: quit ( line -- ) drop disconnect ;
|
||||||
|
|
|
@ -41,10 +41,7 @@ USE: unparser
|
||||||
USE: vectors
|
USE: vectors
|
||||||
USE: words
|
USE: words
|
||||||
|
|
||||||
! <LittleDan> peephole?
|
: compiling ( word -- definition )
|
||||||
! <LittleDan> "whose peephole are we optimizing" "your mom's"
|
|
||||||
|
|
||||||
: begin-compiling ( word -- definition )
|
|
||||||
"verbose-compile" get [
|
"verbose-compile" get [
|
||||||
"Compiling " write dup . flush
|
"Compiling " write dup . flush
|
||||||
] when
|
] when
|
||||||
|
@ -52,12 +49,12 @@ USE: words
|
||||||
|
|
||||||
: (compile) ( word -- )
|
: (compile) ( word -- )
|
||||||
#! Should be called inside the with-compiler scope.
|
#! Should be called inside the with-compiler scope.
|
||||||
begin-compiling dataflow optimize linearize generate ;
|
compiling dataflow optimize linearize simplify generate ;
|
||||||
|
|
||||||
: precompile ( word -- )
|
: precompile ( word -- )
|
||||||
#! Print linear IR of word.
|
#! Print linear IR of word.
|
||||||
[
|
[
|
||||||
word-parameter dataflow optimize linearize [.]
|
word-parameter dataflow optimize linearize simplify [.]
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
||||||
: compile-postponed ( -- )
|
: compile-postponed ( -- )
|
||||||
|
|
|
@ -96,8 +96,10 @@ SYMBOL: #target ( part of jump table )
|
||||||
] "linearizer" set-word-property
|
] "linearizer" set-word-property
|
||||||
|
|
||||||
: <label> ( -- label )
|
: <label> ( -- label )
|
||||||
gensym
|
gensym dup t "label" set-word-property ;
|
||||||
dup t "label" set-word-property ;
|
|
||||||
|
: label? ( obj -- ? )
|
||||||
|
dup word ? [ "label" word-property ] [ drop f ] ifte ;
|
||||||
|
|
||||||
: label, ( label -- )
|
: label, ( label -- )
|
||||||
#label swons , ;
|
#label swons , ;
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
! :folding=indent:collapseFolds=1:
|
||||||
|
|
||||||
|
! $Id$
|
||||||
|
!
|
||||||
|
! Copyright (C) 2004 Slava Pestov.
|
||||||
|
!
|
||||||
|
! Redistribution and use in source and binary forms, with or without
|
||||||
|
! modification, are permitted provided that the following conditions are met:
|
||||||
|
!
|
||||||
|
! 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
! this list of conditions and the following disclaimer.
|
||||||
|
!
|
||||||
|
! 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
! this list of conditions and the following disclaimer in the documentation
|
||||||
|
! and/or other materials provided with the distribution.
|
||||||
|
!
|
||||||
|
! THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
! INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
! FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
! DEVELOPERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
! OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
! WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
IN: compiler
|
||||||
|
USE: inference
|
||||||
|
USE: errors
|
||||||
|
USE: generic
|
||||||
|
USE: hashtables
|
||||||
|
USE: kernel
|
||||||
|
USE: lists
|
||||||
|
USE: math
|
||||||
|
USE: namespaces
|
||||||
|
USE: parser
|
||||||
|
USE: prettyprint
|
||||||
|
USE: stdio
|
||||||
|
USE: strings
|
||||||
|
USE: unparser
|
||||||
|
USE: vectors
|
||||||
|
USE: words
|
||||||
|
|
||||||
|
! <LittleDan> peephole?
|
||||||
|
! <LittleDan> "whose peephole are we optimizing" "your mom's"
|
||||||
|
|
||||||
|
: labels ( linear -- list )
|
||||||
|
#! Make a list of all labels defined in the linear IR.
|
||||||
|
[ [ unswons #label = [ , ] [ drop ] ifte ] each ] make-list ;
|
||||||
|
|
||||||
|
: label-called? ( label linear -- ? )
|
||||||
|
[ unswons #label = [ drop f ] [ over = ] ifte ] some? nip ;
|
||||||
|
|
||||||
|
: purge-label ( label linear -- )
|
||||||
|
>r dup cdr r> label-called? [ , ] [ drop ] ifte ;
|
||||||
|
|
||||||
|
: purge-labels ( linear -- linear )
|
||||||
|
#! Remove all unused labels.
|
||||||
|
[
|
||||||
|
dup [
|
||||||
|
dup car #label = [ over purge-label ] [ , ] ifte
|
||||||
|
] each drop
|
||||||
|
] make-list ;
|
||||||
|
|
||||||
|
: simplify-node ( node rest -- rest ? )
|
||||||
|
over car "simplifier" word-property [
|
||||||
|
call
|
||||||
|
] [
|
||||||
|
swap , f
|
||||||
|
] ifte* ;
|
||||||
|
|
||||||
|
: find-label ( label linear -- rest )
|
||||||
|
[ cdr over = ] some? cdr nip ;
|
||||||
|
|
||||||
|
: (simplify) ( list -- ? )
|
||||||
|
dup [ uncons simplify-node drop (simplify) ] [ drop ] ifte ;
|
||||||
|
|
||||||
|
: simplify ( linear -- linear )
|
||||||
|
purge-labels [ (simplify) ] make-list ;
|
||||||
|
|
||||||
|
: follows? ( op list -- ? ) dup [ car car = ] [ 2drop f ] ifte ;
|
||||||
|
|
||||||
|
GENERIC: call-simplifier ( node rest -- rest ? )
|
||||||
|
|
||||||
|
M: cons call-simplifier ( node rest -- ? )
|
||||||
|
swap , f ;
|
||||||
|
|
||||||
|
PREDICATE: cons return-follows #return swap follows? ;
|
||||||
|
M: return-follows call-simplifier ( node rest -- rest ? )
|
||||||
|
cdr swap cdr #jump swons , t ;
|
||||||
|
|
||||||
|
#call [ call-simplifier ] "simplifier" set-word-property
|
|
@ -0,0 +1,13 @@
|
||||||
|
IN: scratchpad
|
||||||
|
USE: compiler
|
||||||
|
USE: test
|
||||||
|
USE: inference
|
||||||
|
USE: lists
|
||||||
|
|
||||||
|
[ [ ] ] [ [ ] simplify ] unit-test
|
||||||
|
[ [ [ #return ] ] ] [ [ [ #return ] ] simplify ] unit-test
|
||||||
|
[ [ [ #jump | car ] ] ] [ [ [ #call | car ] [ #return ] ] simplify ] unit-test
|
||||||
|
|
||||||
|
[ [ [ #return ] ] ]
|
||||||
|
[ 123 [ [ #call | car ] [ #label | 123 ] [ #return ] ] find-label ]
|
||||||
|
unit-test
|
Loading…
Reference in New Issue