infix: add support for string literals.

Rename ast-number to ast-value (to represent any literal value).
char-rename
John Benediktsson 2017-03-16 16:14:51 -07:00
parent 8e87696719
commit 2e43bc6b90
7 changed files with 43 additions and 40 deletions

View File

@ -2,7 +2,7 @@
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
IN: infix.ast IN: infix.ast
TUPLE: ast-number value ; TUPLE: ast-value 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 step ; TUPLE: ast-slice name from to step ;

View File

@ -62,3 +62,5 @@ INFIX:: foo ( x y -- z ) x**2-abs(y) ;
] ]
] ]
] unit-test ] unit-test
{ "foobar" } [ [infix append("foo", "bar") infix] ] unit-test

View File

@ -33,7 +33,7 @@ ERROR: invalid-op string ;
GENERIC: infix-codegen ( ast -- quot/number ) GENERIC: infix-codegen ( ast -- quot/number )
M: ast-number infix-codegen value>> ; M: ast-value infix-codegen value>> ;
M: ast-local infix-codegen M: ast-local infix-codegen
name>> >local-word ; name>> >local-word ;

View File

@ -3,27 +3,27 @@
USING: infix.ast infix.parser infix.tokenizer tools.test ; USING: infix.ast infix.parser infix.tokenizer tools.test ;
IN: infix.parser.tests IN: infix.parser.tests
{ T{ ast-number { value 1 } } } [ "1" build-infix-ast ] unit-test { T{ ast-value { value 1 } } } [ "1" build-infix-ast ] unit-test
{ T{ ast-negation f T{ ast-number { value 1 } } } } { T{ ast-negation f T{ ast-value { value 1 } } } }
[ "-1" build-infix-ast ] unit-test [ "-1" build-infix-ast ] unit-test
{ T{ ast-op { T{ ast-op
{ left { left
T{ ast-op T{ ast-op
{ left T{ ast-number { value 1 } } } { left T{ ast-value { value 1 } } }
{ right T{ ast-number { value 2 } } } { right T{ ast-value { value 2 } } }
{ op "+" } { op "+" }
} }
} }
{ right T{ ast-number { value 4 } } } { right T{ ast-value { value 4 } } }
{ op "+" } { op "+" }
} } [ "1+2+4" build-infix-ast ] unit-test } } [ "1+2+4" build-infix-ast ] unit-test
{ T{ ast-op { T{ ast-op
{ left T{ ast-number { value 1 } } } { left T{ ast-value { value 1 } } }
{ right { right
T{ ast-op T{ ast-op
{ left T{ ast-number { value 2 } } } { left T{ ast-value { value 2 } } }
{ right T{ ast-number { value 3 } } } { right T{ ast-value { value 3 } } }
{ op "*" } { op "*" }
} }
} }
@ -31,8 +31,8 @@ IN: infix.parser.tests
} } [ "1+2*3" build-infix-ast ] unit-test } } [ "1+2*3" build-infix-ast ] unit-test
{ T{ ast-op { T{ ast-op
{ left T{ ast-number { value 1 } } } { left T{ ast-value { value 1 } } }
{ right T{ ast-number { value 2 } } } { right T{ ast-value { value 2 } } }
{ op "+" } { op "+" }
} } [ "(1+2)" build-infix-ast ] unit-test } } [ "(1+2)" build-infix-ast ] unit-test
@ -44,13 +44,13 @@ IN: infix.parser.tests
{ arguments { arguments
V{ V{
T{ ast-op T{ ast-op
{ left T{ ast-number { value 1 } } } { left T{ ast-value { value 1 } } }
{ right T{ ast-number { value 2 } } } { right T{ ast-value { value 2 } } }
{ op "+" } { op "+" }
} }
T{ ast-op T{ ast-op
{ left T{ ast-number { value 2 } } } { left T{ ast-value { value 2 } } }
{ right T{ ast-number { value 3 } } } { right T{ ast-value { value 3 } } }
{ op "%" } { op "%" }
} }
} }
@ -74,12 +74,12 @@ IN: infix.parser.tests
{ left { left
T{ ast-op T{ ast-op
{ left { left
T{ ast-number T{ ast-value
{ value 2 } { value 2 }
} }
} }
{ right { right
T{ ast-number T{ ast-value
{ value 3 } { value 3 }
} }
} }
@ -87,7 +87,7 @@ IN: infix.parser.tests
} }
} }
{ right { right
T{ ast-number { value 4 } } T{ ast-value { value 4 } }
} }
{ op "+" } { op "+" }
} }
@ -97,16 +97,16 @@ IN: infix.parser.tests
{ op "+" } { op "+" }
} }
} }
{ right T{ ast-number { value 2 } } } { right T{ ast-value { value 2 } } }
{ op "/" } { op "/" }
} } [ "(bar() + baz[2/ 3+4 ] )/2" build-infix-ast ] unit-test } } [ "(bar() + baz[2/ 3+4 ] )/2" build-infix-ast ] unit-test
{ T{ ast-op { T{ ast-op
{ left T{ ast-number { value 1 } } } { left T{ ast-value { value 1 } } }
{ right { right
T{ ast-op T{ ast-op
{ left T{ ast-number { value 2 } } } { left T{ ast-value { value 2 } } }
{ right T{ ast-number { value 3 } } } { right T{ ast-value { value 3 } } }
{ op "/" } { op "/" }
} }
} }
@ -119,9 +119,9 @@ IN: infix.parser.tests
{ name "foo" } { name "foo" }
{ arguments { arguments
V{ V{
T{ ast-number { value 2 } } T{ ast-value { value 2 } }
T{ ast-negation T{ ast-negation
{ term T{ ast-number { value 3 } } } { term T{ ast-value { value 3 } } }
} }
} }
} }
@ -142,7 +142,7 @@ IN: infix.parser.tests
{ name "foo" } { name "foo" }
{ arguments { arguments
V{ V{
T{ ast-number T{ ast-value
{ value 2 } { value 2 }
} }
} }
@ -152,7 +152,7 @@ IN: infix.parser.tests
{ right { right
T{ ast-negation T{ ast-negation
{ term { term
T{ ast-number T{ ast-value
{ value 1 } { value 1 }
} }
} }
@ -163,7 +163,7 @@ IN: infix.parser.tests
} }
} }
} }
{ right T{ ast-number { value 3 } } } { right T{ ast-value { value 3 } } }
{ op "/" } { op "/" }
} }
} }

View File

@ -5,7 +5,7 @@ strings vectors ;
IN: infix.parser IN: infix.parser
EBNF: parse-infix EBNF: parse-infix
Number = . ?[ ast-number? ]? Number = . ?[ ast-value? ]?
Identifier = . ?[ string? ]? Identifier = . ?[ string? ]?
Array = Identifier:i "[" Sum:s "]" => [[ i s ast-array boa ]] Array = Identifier:i "[" Sum:s "]" => [[ i s ast-array boa ]]
Slice1 = Identifier:i "[" Sum?:from ":" Sum?:to "]" => [[ i from to f ast-slice boa ]] Slice1 = Identifier:i "[" Sum?:from ":" Sum?:to "]" => [[ i from to f ast-slice boa ]]

View File

@ -3,19 +3,19 @@
USING: infix.ast infix.tokenizer tools.test ; USING: infix.ast infix.tokenizer tools.test ;
IN: infix.tokenizer.tests IN: infix.tokenizer.tests
{ V{ T{ ast-number f 1 } } } [ "1" tokenize-infix ] unit-test { V{ T{ ast-value f 1 } } } [ "1" tokenize-infix ] unit-test
{ V{ T{ ast-number f 1.02 } CHAR: * T{ ast-number f 3 } } } [ "1.02*3" tokenize-infix ] unit-test { V{ T{ ast-value f 1.02 } CHAR: * T{ ast-value f 3 } } } [ "1.02*3" tokenize-infix ] unit-test
{ V{ T{ ast-number f 3 } CHAR: / CHAR: ( T{ ast-number f 3 } CHAR: + T{ ast-number f 4 } CHAR: ) } } { V{ T{ ast-value f 3 } CHAR: / CHAR: ( T{ ast-value f 3 } CHAR: + T{ ast-value f 4 } CHAR: ) } }
[ "3/(3+4)" tokenize-infix ] unit-test [ "3/(3+4)" tokenize-infix ] unit-test
{ V{ "foo" CHAR: ( "x" CHAR: , "y" CHAR: , "z" CHAR: ) } } [ "foo(x,y,z)" tokenize-infix ] unit-test { V{ "foo" CHAR: ( "x" CHAR: , "y" CHAR: , "z" CHAR: ) } } [ "foo(x,y,z)" tokenize-infix ] unit-test
{ V{ "arr" CHAR: [ "x" CHAR: + T{ ast-number f 3 } CHAR: ] } } { V{ "arr" CHAR: [ "x" CHAR: + T{ ast-value f 3 } CHAR: ] } }
[ "arr[x+3]" tokenize-infix ] unit-test [ "arr[x+3]" tokenize-infix ] unit-test
[ "1.0.4" tokenize-infix ] must-fail [ "1.0.4" tokenize-infix ] must-fail
{ V{ CHAR: + CHAR: ] T{ ast-number f 3.4 } CHAR: , "bar" } } { V{ CHAR: + CHAR: ] T{ ast-value f 3.4 } CHAR: , "bar" } }
[ "+]3.4,bar" tokenize-infix ] unit-test [ "+]3.4,bar" tokenize-infix ] unit-test
{ V{ "baz_34c" } } [ "baz_34c" tokenize-infix ] unit-test { V{ "baz_34c" } } [ "baz_34c" tokenize-infix ] unit-test
{ V{ T{ ast-number f 34 } "c_baz" } } [ "34c_baz" tokenize-infix ] unit-test { V{ T{ ast-value f 34 } "c_baz" } } [ "34c_baz" tokenize-infix ] unit-test
{ V{ CHAR: ( T{ ast-number f 1 } CHAR: + T{ ast-number f 2 } CHAR: ) } } { V{ CHAR: ( T{ ast-value f 1 } CHAR: + T{ ast-value f 2 } CHAR: ) } }
[ "(1+2)" tokenize-infix ] unit-test [ "(1+2)" tokenize-infix ] unit-test
{ V{ T{ ast-number f 1 } CHAR: + T{ ast-number f 2 } CHAR: / T{ ast-number f 3 } } } { V{ T{ ast-value f 1 } CHAR: + T{ ast-value f 2 } CHAR: / T{ ast-value f 3 } } }
[ "1\n+\r2\t/ 3" tokenize-infix ] unit-test [ "1\n+\r2\t/ 3" tokenize-infix ] unit-test

View File

@ -8,8 +8,9 @@ EBNF: tokenize-infix
Letter = [a-zA-Z] Letter = [a-zA-Z]
Digit = [0-9] Digit = [0-9]
Digits = Digit+ Digits = Digit+
Number = Digits '.' Digits => [[ "" concat-as string>number ast-number boa ]] Number = Digits '.' Digits => [[ "" concat-as string>number ast-value boa ]]
| Digits => [[ >string string>number ast-number boa ]] | Digits => [[ >string string>number ast-value boa ]]
String = '"' [^"]* '"' => [[ second >string ast-value boa ]]
Space = [ \t\n\r] Space = [ \t\n\r]
Spaces = Space* => [[ ignore ]] Spaces = Space* => [[ ignore ]]
NameFirst = Letter | "_" => [[ CHAR: _ ]] NameFirst = Letter | "_" => [[ CHAR: _ ]]
@ -18,7 +19,7 @@ Name = NameFirst NameRest* => [[ first2 swap prefix >string ]]
Special = [+*/%(),] | "-" => [[ CHAR: - ]] Special = [+*/%(),] | "-" => [[ CHAR: - ]]
| "[" => [[ CHAR: [ ]] | "]" => [[ CHAR: ] ]] | "[" => [[ CHAR: [ ]] | "]" => [[ CHAR: ] ]]
| ":" => [[ CHAR: : ]] | ":" => [[ CHAR: : ]]
Tok = Spaces (Name | Number | Special ) Tok = Spaces (Name | Number | String | Special )
End = !(.) End = !(.)
Toks = Tok* Spaces End Toks = Tok* Spaces End
;EBNF ;EBNF