diff --git a/extra/infix/ast/ast.factor b/extra/infix/ast/ast.factor index 1908b3d39b..ef5bed35d6 100644 --- a/extra/infix/ast/ast.factor +++ b/extra/infix/ast/ast.factor @@ -5,6 +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-function name arguments ; TUPLE: ast-op left right op ; TUPLE: ast-negation term ; diff --git a/extra/infix/infix-docs.factor b/extra/infix/infix-docs.factor index 3885fcc613..52df131b0e 100644 --- a/extra/infix/infix-docs.factor +++ b/extra/infix/infix-docs.factor @@ -65,6 +65,13 @@ $nl "[let { 1 2 3 4 } :> myarr [infix myarr[4/2]*3 infix] ] ." "9" } +$nl +"You can create sub-" { $vocab-link "sequences" } " inside infix expressions using " { $snippet "arr[from:to]" } " notation." +{ $example + "USING: arrays locals infix ;" + "[let \"foobar\" :> s [infix s[0:3] infix] ] ." + "\"foo\"" +} ; ABOUT: "infix" diff --git a/extra/infix/infix-tests.factor b/extra/infix/infix-tests.factor index c2b0d9d7b4..79e077f2ac 100644 --- a/extra/infix/infix-tests.factor +++ b/extra/infix/infix-tests.factor @@ -32,3 +32,13 @@ IN: infix.tests [ 10 ] [ [infix stupid_function (0, 1, 2, 3, 4) infix] ] unit-test [ -1 ] [ [let 1 :> a [infix -a infix] ] ] unit-test + +[ CHAR: f ] [ [let "foo" :> s [infix s[0] infix] ] ] unit-test +[ CHAR: r ] [ [let "bar" :> s [infix s[-1] infix] ] ] unit-test +[ "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 +[ "foobar" ] [ [let "foobar" :> s [infix s[:] 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 48ac35264b..1945b2e906 100644 --- a/extra/infix/infix.factor +++ b/extra/infix/infix.factor @@ -1,9 +1,10 @@ ! Copyright (C) 2009 Philipp Brüschweiler ! See http://factorcode.org/license.txt for BSD license. USING: accessors assocs combinators combinators.short-circuit -effects fry infix.parser infix.ast kernel locals.parser -locals.types math multiline namespaces parser quotations -sequences summary words vocabs.parser ; +effects fry infix.parser infix.ast kernel locals locals.parser +locals.types math math.order multiline namespaces parser +quotations sequences summary words vocabs.parser ; + IN: infix > ; M: ast-local infix-codegen name>> >local-word ; +:: infix-nth ( n seq -- elt ) + n dup 0 < [ seq length + ] when seq nth ; + M: ast-array infix-codegen [ index>> infix-codegen prepare-operand ] - [ name>> >local-word ] bi '[ @ _ nth ] ; + [ name>> >local-word ] bi '[ @ _ infix-nth ] ; + +:: infix-subseq ( from to 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 ; + +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 ] ; M: ast-op infix-codegen [ left>> infix-codegen ] [ right>> infix-codegen ] diff --git a/extra/infix/parser/parser.factor b/extra/infix/parser/parser.factor index 2f9ab03d18..ca1570e111 100644 --- a/extra/infix/parser/parser.factor +++ b/extra/infix/parser/parser.factor @@ -8,6 +8,7 @@ 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 ]] Function = Identifier:i "(" FunArgs?:a ")" => [[ i a [ V{ } ] unless* ast-function boa ]] FunArgs = FunArgs:a "," Sum:s => [[ s a push a ]] @@ -15,7 +16,7 @@ FunArgs = FunArgs:a "," Sum:s => [[ s a push a ]] Terminal = ("-"|"+"):op Terminal:term => [[ term op "-" = [ ast-negation boa ] when ]] | "(" Sum:s ")" => [[ s ]] - | Number | Array | Function + | Number | Array | Slice | Function | Identifier => [[ ast-local boa ]] Product = Product:p ("*"|"/"|"%"):op Terminal:term => [[ p term op ast-op boa ]] diff --git a/extra/infix/tokenizer/tokenizer.factor b/extra/infix/tokenizer/tokenizer.factor index f5bce4b6d7..7bf1bddcd4 100644 --- a/extra/infix/tokenizer/tokenizer.factor +++ b/extra/infix/tokenizer/tokenizer.factor @@ -17,6 +17,7 @@ NameRest = NameFirst | Digit Name = NameFirst NameRest* => [[ first2 swap prefix >string ]] Special = [+*/%(),] | "-" => [[ CHAR: - ]] | "[" => [[ CHAR: [ ]] | "]" => [[ CHAR: ] ]] + | ":" => [[ CHAR: : ]] Tok = Spaces (Name | Number | Special ) End = !(.) Toks = Tok* Spaces End