]> gitweb.factorcode.org Git - factor.git/commitdiff
infix: adding slice step notation.
authorJohn Benediktsson <mrjbq7@gmail.com>
Tue, 19 Mar 2013 23:52:33 +0000 (16:52 -0700)
committerJohn Benediktsson <mrjbq7@gmail.com>
Tue, 19 Mar 2013 23:52:33 +0000 (16:52 -0700)
extra/infix/ast/ast.factor
extra/infix/infix-tests.factor
extra/infix/infix.factor
extra/infix/parser/parser.factor

index ef5bed35d6dcea147bfd5afd2eec7bc90343965b..465fec6569ea71777c7de72a0b8c25fbd11ddde3 100644 (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 ;
index 79e077f2acf1d2b80e264e2f7ed13c84221ef94b..4cc7ec7eb375091bf26d178074e16c18b8af7e30 100644 (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
 
index 3778031c4df73ee35bcb24ce214e14b12fad02d8..11fb9a86d179fd9edaaab5b2da4daa3db201b7c2 100644 (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 ] ;
+    {
+        [ 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
index ca1570e1119588d9ada08b4db1e5b12b8d4495a6..def3898fad8300f7bd6d4f6941b90c1e90a2f1f2 100644 (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 ]]