From e172a081a42bff85043bd181138b5671c1ea0e61 Mon Sep 17 00:00:00 2001 From: John Benediktsson Date: Tue, 19 Mar 2013 16:52:33 -0700 Subject: [PATCH] infix: adding slice step notation. --- extra/infix/ast/ast.factor | 2 +- extra/infix/infix-tests.factor | 2 ++ extra/infix/infix.factor | 26 +++++++++++++++++++------- extra/infix/parser/parser.factor | 4 +++- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/extra/infix/ast/ast.factor b/extra/infix/ast/ast.factor index ef5bed35d6..465fec6569 100644 --- a/extra/infix/ast/ast.factor +++ b/extra/infix/ast/ast.factor @@ -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 ; diff --git a/extra/infix/infix-tests.factor b/extra/infix/infix-tests.factor index 79e077f2ac..4cc7ec7eb3 100644 --- a/extra/infix/infix-tests.factor +++ b/extra/infix/infix-tests.factor @@ -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 diff --git a/extra/infix/infix.factor b/extra/infix/infix.factor index 3778031c4d..11fb9a86d1 100644 --- a/extra/infix/infix.factor +++ b/extra/infix/infix.factor @@ -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 + 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 ] ; + { + [ from>> [ infix-codegen prepare-operand ] [ [ f ] ] if* ] + [ to>> [ infix-codegen prepare-operand ] [ [ f ] ] if* ] + [ 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 diff --git a/extra/infix/parser/parser.factor b/extra/infix/parser/parser.factor index ca1570e111..def3898fad 100644 --- a/extra/infix/parser/parser.factor +++ b/extra/infix/parser/parser.factor @@ -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 ]]