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:
Glen Whitney 2021-02-11 10:02:43 -08:00
parent c516ed6d7f
commit 904f651897
5 changed files with 39 additions and 6 deletions

View File

@ -8,6 +8,14 @@ context-free start-symbols
Start Start
lexical sorts
STRING_LITERAL
lexical syntax
STRING_LITERAL = ~[\']*
context-free sorts context-free sorts
Start LineSeq Line OptTermEx TermExLst TermEx Ex Start LineSeq Line OptTermEx TermExLst TermEx Ex
@ -29,13 +37,14 @@ context-free syntax
TermEx.Terminate = <<Ex>;> TermEx.Terminate = <<Ex>;>
Ex.Int = INT Ex.Int = INT
Ex.Stream = <stream> Ex.LitString = <'<STRING_LITERAL>'>
Ex.Sum = [[Ex] + [Ex]] {left} Ex.Stream = <stream>
Ex.Gets = [[Ex] << [Ex]] {left} Ex.Sum = <<Ex> + <Ex>> {left}
Ex.To = [[Ex] >> [Ex]] {left} Ex.Gets = [[Ex] << [Ex]] {left}
Ex.To = [[Ex] >> [Ex]] {left}
Ex = <(<Ex>)> {bracket} Ex = <(<Ex>)> {bracket}
context-free priorities context-free priorities

1
tests/hw.fos Normal file
View File

@ -0,0 +1 @@
stream << 'Hello, world!'

View File

@ -22,6 +22,8 @@ rules
hs: Stream() -> ("StdIO", "") hs: Stream() -> ("StdIO", "")
hs: Int(x) -> (x, "") 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: 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") 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: Terminate((c,p)) -> ($[[c];;], p)
hs: Sequence(l) -> (<last; Fst>l, <map(Snd); concat-strings>l) 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 strategies
HaskellEscape = Escape <+ Hascape
haskell = bottomup(try(hs)) haskell = bottomup(try(hs))

View File

@ -13,13 +13,23 @@ rules
js: Stream() -> $[Stdio] js: Stream() -> $[Stdio]
js: Int(x) -> x js: Int(x) -> x
js: LitString(x) -> $['[<string-as-chars(escape-chars(JavaEscape))>x]']
js: Sum(x,y) -> $[[x] + [y]] js: Sum(x,y) -> $[[x] + [y]]
js: Gets(x, y) -> $[[x].gets([y])] js: Gets(x, y) -> $[[x].gets([y])]
js: To(x, y) -> $[to([x],[y])] js: To(x, y) -> $[to([x],[y])]
js: Terminate(x) -> x js: Terminate(x) -> x
js: Sequence(l) -> <join(|";\n")>l 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 strategies
JavaEscape = Escape <+ Jscape
javascript = bottomup(try(js)) javascript = bottomup(try(js))

View File

@ -15,6 +15,7 @@ rules
py: Stream() -> $[Stdio] py: Stream() -> $[Stdio]
py: Int(x) -> x py: Int(x) -> x
py: LitString(x) -> $[r'[x]']
py: Sum(x,y) -> $[[x] + [y]] py: Sum(x,y) -> $[[x] + [y]]
py: Gets(x, y) -> $[[x].gets([y])] py: Gets(x, y) -> $[[x].gets([y])]
py: To(x, y) -> $[to([x],[y])] py: To(x, y) -> $[to([x],[y])]