infix: add support for string literals.
Rename ast-number to ast-value (to represent any literal value).char-rename
parent
8e87696719
commit
2e43bc6b90
|
@ -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 ;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 ;
|
||||||
|
|
|
@ -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 "/" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 ]]
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue