infix: adding slice step notation.

db4
John Benediktsson 2013-03-19 16:52:33 -07:00
parent d7d487dd82
commit e172a081a4
4 changed files with 25 additions and 9 deletions

View File

@ -5,7 +5,7 @@ IN: infix.ast
TUPLE: ast-number value ; TUPLE: ast-number value ;
TUPLE: ast-local name ; TUPLE: ast-local name ;
TUPLE: ast-array name index ; TUPLE: ast-array name index ;
TUPLE: ast-slice name from to ; TUPLE: ast-slice name from to step ;
TUPLE: ast-function name arguments ; TUPLE: ast-function name arguments ;
TUPLE: ast-op left right op ; TUPLE: ast-op left right op ;
TUPLE: ast-negation term ; TUPLE: ast-negation term ;

View File

@ -38,7 +38,9 @@ IN: infix.tests
[ "foo" ] [ [let "foobar" :> s [infix s[0:3] infix] ] ] unit-test [ "foo" ] [ [let "foobar" :> s [infix s[0:3] infix] ] ] unit-test
[ "foo" ] [ [let "foobar" :> s [infix s[:3] infix] ] ] unit-test [ "foo" ] [ [let "foobar" :> s [infix s[:3] infix] ] ] unit-test
[ "bar" ] [ [let "foobar" :> s [infix s[-3:] infix] ] ] unit-test [ "bar" ] [ [let "foobar" :> s [infix s[-3:] infix] ] ] unit-test
[ "rab" ] [ [let "foobar" :> s [infix s[-3::-1] infix] ] ] unit-test
[ "foobar" ] [ [let "foobar" :> s [infix s[:] infix] ] ] unit-test [ "foobar" ] [ [let "foobar" :> s [infix s[:] infix] ] ] unit-test
[ "foa" ] [ [let "foobar" :> s [infix s[::2] infix] ] ] unit-test
[ "bar" ] [ [let "foobar" :> s [infix s[-3:100] infix] ] ] unit-test [ "bar" ] [ [let "foobar" :> s [infix s[-3:100] infix] ] ] unit-test
[ "foobar" ] [ [let "foobar" :> s [infix s[-100:100] infix] ] ] unit-test [ "foobar" ] [ [let "foobar" :> s [infix s[-100:100] infix] ] ] unit-test

View File

@ -2,8 +2,8 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs combinators combinators.short-circuit USING: accessors assocs combinators combinators.short-circuit
effects fry infix.parser infix.ast kernel locals locals.parser effects fry infix.parser infix.ast kernel locals locals.parser
locals.types math math.order multiline namespaces parser locals.types math math.order math.ranges multiline namespaces
quotations sequences summary words vocabs.parser ; parser quotations sequences summary words vocabs.parser ;
IN: infix IN: infix
@ -41,16 +41,27 @@ M: ast-array infix-codegen
[ index>> infix-codegen prepare-operand ] [ index>> infix-codegen prepare-operand ]
[ name>> >local-word ] bi '[ @ _ infix-nth ] ; [ name>> >local-word ] bi '[ @ _ infix-nth ] ;
:: infix-subseq ( from to seq -- subseq ) : infix-subseq-step ( subseq step -- subseq' )
dup 0 < [ [ reverse! ] dip ] when
abs dup 1 = [ drop ] [
[ dup length 1 - 0 swap ] dip
<range> swap nths
] if ;
:: infix-subseq ( from to step seq -- subseq )
seq length :> len seq length :> len
from 0 or dup 0 < [ len + ] when from 0 or dup 0 < [ len + ] when
to [ dup 0 < [ len + ] when ] [ len ] if* to [ dup 0 < [ len + ] when ] [ len ] if*
[ 0 len clamp ] bi@ dupd max seq subseq ; [ 0 len clamp ] bi@ dupd max seq subseq
step [ infix-subseq-step ] when* ;
M: ast-slice infix-codegen M: ast-slice infix-codegen
{
[ from>> [ infix-codegen prepare-operand ] [ [ f ] ] if* ] [ from>> [ infix-codegen prepare-operand ] [ [ f ] ] if* ]
[ to>> [ infix-codegen prepare-operand ] [ [ f ] ] if* ] [ to>> [ infix-codegen prepare-operand ] [ [ f ] ] if* ]
[ name>> >local-word ] tri '[ @ @ _ infix-subseq ] ; [ step>> [ infix-codegen prepare-operand ] [ [ f ] ] if* ]
[ name>> >local-word ]
} cleave '[ @ @ @ _ infix-subseq ] ;
M: ast-op infix-codegen M: ast-op infix-codegen
[ left>> infix-codegen ] [ right>> infix-codegen ] [ left>> infix-codegen ] [ right>> infix-codegen ]
@ -93,6 +104,7 @@ M: ast-function infix-codegen
: [infix-parse ( end -- result/quot ) : [infix-parse ( end -- result/quot )
parse-multiline-string build-infix-ast parse-multiline-string build-infix-ast
infix-codegen prepare-operand ; infix-codegen prepare-operand ;
PRIVATE> PRIVATE>
SYNTAX: [infix SYNTAX: [infix

View File

@ -8,7 +8,9 @@ EBNF: parse-infix
Number = . ?[ ast-number? ]? Number = . ?[ ast-number? ]?
Identifier = . ?[ string? ]? Identifier = . ?[ string? ]?
Array = Identifier:i "[" Sum:s "]" => [[ i s ast-array boa ]] Array = Identifier:i "[" Sum:s "]" => [[ i s ast-array boa ]]
Slice = Identifier:i "[" Sum?:s ":" Sum?:t "]" => [[ i s t ast-slice boa ]] Slice1 = Identifier:i "[" Sum?:from ":" Sum?:to "]" => [[ i from to f ast-slice boa ]]
Slice2 = Identifier:i "[" Sum?:from ":" Sum?:to ":" Sum?:step "]" => [[ i from to step ast-slice boa ]]
Slice = Slice1 | Slice2
Function = Identifier:i "(" FunArgs?:a ")" => [[ i a [ V{ } ] unless* ast-function boa ]] Function = Identifier:i "(" FunArgs?:a ")" => [[ i a [ V{ } ] unless* ast-function boa ]]
FunArgs = FunArgs:a "," Sum:s => [[ s a push a ]] FunArgs = FunArgs:a "," Sum:s => [[ s a push a ]]