forked from glen/fostr
feat: Add syntax for string literals
Also rudimentary code generation. The difficulty is that for Haskell generation, we need to know whether an expression is a string or in to send it to standard output. So we will need to begin implementation of a type system for fostr.
This commit is contained in:
parent
c516ed6d7f
commit
904f651897
@ -8,6 +8,14 @@ context-free start-symbols
|
||||
|
||||
Start
|
||||
|
||||
lexical sorts
|
||||
|
||||
STRING_LITERAL
|
||||
|
||||
lexical syntax
|
||||
|
||||
STRING_LITERAL = ~[\']*
|
||||
|
||||
context-free sorts
|
||||
|
||||
Start LineSeq Line OptTermEx TermExLst TermEx Ex
|
||||
@ -30,8 +38,9 @@ context-free syntax
|
||||
TermEx.Terminate = <<Ex>;>
|
||||
|
||||
Ex.Int = INT
|
||||
Ex.LitString = <'<STRING_LITERAL>'>
|
||||
Ex.Stream = <stream>
|
||||
Ex.Sum = [[Ex] + [Ex]] {left}
|
||||
Ex.Sum = <<Ex> + <Ex>> {left}
|
||||
Ex.Gets = [[Ex] << [Ex]] {left}
|
||||
Ex.To = [[Ex] >> [Ex]] {left}
|
||||
|
||||
|
1
tests/hw.fos
Normal file
1
tests/hw.fos
Normal file
@ -0,0 +1 @@
|
||||
stream << 'Hello, world!'
|
@ -22,6 +22,8 @@ rules
|
||||
|
||||
hs: Stream() -> ("StdIO", "")
|
||||
hs: Int(x) -> (x, "")
|
||||
hs: LitString(x)
|
||||
-> ($["[<string-as-chars(escape-chars(HaskellEscape))>x]"], "")
|
||||
hs: Sum( (c, p), (d, q)) -> ($[([c] + [d])], <conc-strings>(p,q))
|
||||
|
||||
hs: Gets((c, p), (d, q)) -> <hsget>(c,d,<conc-strings>(p,q),<newname>"fosgt")
|
||||
@ -35,7 +37,17 @@ rules
|
||||
hs: Terminate((c,p)) -> ($[[c];;], p)
|
||||
hs: Sequence(l) -> (<last; Fst>l, <map(Snd); concat-strings>l)
|
||||
|
||||
/* Characters we need to escape in Haskell string constants */
|
||||
Hascape: ['\t' | cs ] -> ['\', 't' | cs ]
|
||||
/* I think I can just use ASCII constants for characters... */
|
||||
Hascape: [ 0 | cs ] -> ['\', '0' | cs ]
|
||||
Hascape: [ 7 | cs ] -> ['\', 'a' | cs ] // Alert
|
||||
Hascape: [ 8 | cs ] -> ['\', 'b' | cs ] // Backspace
|
||||
Hascape: [ 11 | cs ] -> ['\', 'v' | cs ] // Vertical tab
|
||||
Hascape: [ 12 | cs ] -> ['\', 'f' | cs ] // Form feed
|
||||
|
||||
strategies
|
||||
HaskellEscape = Escape <+ Hascape
|
||||
|
||||
haskell = bottomup(try(hs))
|
||||
|
||||
|
@ -13,13 +13,23 @@ rules
|
||||
|
||||
js: Stream() -> $[Stdio]
|
||||
js: Int(x) -> x
|
||||
js: LitString(x) -> $['[<string-as-chars(escape-chars(JavaEscape))>x]']
|
||||
js: Sum(x,y) -> $[[x] + [y]]
|
||||
js: Gets(x, y) -> $[[x].gets([y])]
|
||||
js: To(x, y) -> $[to([x],[y])]
|
||||
js: Terminate(x) -> x
|
||||
js: Sequence(l) -> <join(|";\n")>l
|
||||
|
||||
/* Characters we need to escape in Javascript string constants */
|
||||
Jscape: ['\t' | cs ] -> ['\', 't' | cs ]
|
||||
/* I think I can just use ASCII constants for characters... */
|
||||
Jscape: [ 0 | cs ] -> ['\', '0' | cs ]
|
||||
Jscape: [ 8 | cs ] -> ['\', 'b' | cs ] // Backspace
|
||||
Jscape: [ 11 | cs ] -> ['\', 'v' | cs ] // Vertical tab
|
||||
Jscape: [ 12 | cs ] -> ['\', 'f' | cs ] // Form feed
|
||||
|
||||
strategies
|
||||
JavaEscape = Escape <+ Jscape
|
||||
|
||||
javascript = bottomup(try(js))
|
||||
|
||||
|
@ -15,6 +15,7 @@ rules
|
||||
|
||||
py: Stream() -> $[Stdio]
|
||||
py: Int(x) -> x
|
||||
py: LitString(x) -> $[r'[x]']
|
||||
py: Sum(x,y) -> $[[x] + [y]]
|
||||
py: Gets(x, y) -> $[[x].gets([y])]
|
||||
py: To(x, y) -> $[to([x],[y])]
|
||||
|
Loading…
Reference in New Issue
Block a user