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-local name ;
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-op left right op ;
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[: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
[ "foa" ] [ [let "foobar" :> s [infix s[::2] 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

View File

@ -2,8 +2,8 @@
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs combinators combinators.short-circuit
effects fry infix.parser infix.ast kernel locals locals.parser
locals.types math math.order multiline namespaces parser
quotations sequences summary words vocabs.parser ;
locals.types math math.order math.ranges multiline namespaces
parser quotations sequences summary words vocabs.parser ;
IN: infix
@ -41,16 +41,27 @@ M: ast-array infix-codegen
[ index>> infix-codegen prepare-operand ]
[ 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
from 0 or dup 0 < [ len + ] when
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
{
[ from>> [ 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
[ left>> infix-codegen ] [ right>> infix-codegen ]
@ -93,6 +104,7 @@ M: ast-function infix-codegen
: [infix-parse ( end -- result/quot )
parse-multiline-string build-infix-ast
infix-codegen prepare-operand ;
PRIVATE>
SYNTAX: [infix

View File

@ -8,7 +8,9 @@ EBNF: parse-infix
Number = . ?[ ast-number? ]?
Identifier = . ?[ string? ]?
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 ]]
FunArgs = FunArgs:a "," Sum:s => [[ s a push a ]]