Add literal string constants #19
@ -11,7 +11,8 @@ language as possible to work in, given that I inevitably will be doing a
|
||||
bunch of coding. The language will be centrally organized around the
|
||||
concept of "streams" (somewhat in the spirit of
|
||||
[streem](https://github.com/matz/streem) and/or
|
||||
[Orc](http://orc.csres.utexas.edu/index.shtml)). In fact all higher-type
|
||||
[Orc](http://orc.csres.utexas.edu/index.shtml), or to a lesser extent,
|
||||
[Sisal-is](https://github.com/parsifal-47/sisal-is)). In fact all higher-type
|
||||
entities will be cast in terms of streams, or in slogan form, "++f++unctions
|
||||
and (binary) ++o++perators are ++str++eams" (hence the name "fostr").
|
||||
|
||||
|
@ -14,7 +14,7 @@ lexical sorts
|
||||
|
||||
lexical syntax
|
||||
|
||||
STRING_LITERAL = ~[\']*
|
||||
STRING_LITERAL = "'"~[\']*"'"
|
||||
|
||||
context-free sorts
|
||||
|
||||
@ -38,7 +38,7 @@ context-free syntax
|
||||
TermEx.Terminate = <<Ex>;>
|
||||
|
||||
Ex.Int = INT
|
||||
Ex.LitString = <'<STRING_LITERAL>'>
|
||||
Ex.LitString = STRING_LITERAL
|
||||
Ex.Stream = <stream>
|
||||
Ex.Sum = <<Ex> + <Ex>> {left}
|
||||
Ex.Gets = [[Ex] << [Ex]] {left}
|
||||
|
@ -1,15 +1,15 @@
|
||||
module basic
|
||||
language fostr
|
||||
|
||||
|
||||
test hw1_type [[
|
||||
[[stream]] << [['Hello, world!']]
|
||||
[[stream]] << [['Hello, world! ']] << [[3+2]] << ' times.'
|
||||
]]
|
||||
run get-type on #1 to STREAM()
|
||||
run get-type on #2 to STRING()
|
||||
run get-type on #3 to INT()
|
||||
run get-type to STREAM()
|
||||
/** writes
|
||||
Hello, world!**/
|
||||
Hello, world! 5 times.**/
|
||||
|
||||
/** md
|
||||
Title: A whirlwind tour of fostr
|
||||
|
@ -1,15 +1,25 @@
|
||||
module haskell
|
||||
imports libstrategolib signatures/- util
|
||||
imports libstrategolib signatures/- util analysis
|
||||
rules
|
||||
/* Approach: Generate code from the bottom up.
|
||||
At every node, we create a pair of the implementation and
|
||||
necessary preamble of IO actions.
|
||||
We concatenate preambles as we go up.
|
||||
Finally, at the toplevel we emit the preamble before returning the
|
||||
final value.
|
||||
/* Approach:
|
||||
A) We will define a local transformation taking a term with value strings
|
||||
at each child to a value string for the node.
|
||||
B) We will append IO actions needed to set up for the value progressively
|
||||
to a Preactions rule (mapping () to the list of actions). There will
|
||||
be a utility `add-preaction` to append a new clause to value of this
|
||||
rule.
|
||||
C) We will use bottomup-para to traverse the full AST with the
|
||||
transformation from A so that we have access to the original expression
|
||||
(and get get the Statix-associated type when we need to).
|
||||
Hence the transformation in (A) must actually take a pair of
|
||||
an (original) term and a term with value strings at each child,
|
||||
and be certain to return a value string.
|
||||
|
||||
Finally, at the toplevel we emit the result of <Preactions>() before
|
||||
returning the final value.
|
||||
*/
|
||||
|
||||
hs: TopLevel((c,p)) -> $[import System.IO
|
||||
hs: (_, TopLevel(val)) -> $[import System.IO
|
||||
data IOStream = StdIO
|
||||
|
||||
gets :: Show b => a -> b -> IO a
|
||||
@ -17,25 +27,35 @@ rules
|
||||
putStr(show d)
|
||||
return s
|
||||
|
||||
getsStr :: a -> String -> IO a
|
||||
getsStr s d = do
|
||||
putStr(d)
|
||||
return s
|
||||
|
||||
main = do
|
||||
[p]return [c]]
|
||||
[<Preactions>()]return [val]]
|
||||
|
||||
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: (_, Stream()) -> "StdIO"
|
||||
hs: (_, Int(x)) -> x
|
||||
hs: (_, LitString(x)) -> <haskLitString>x
|
||||
hs: (_, Sum(x, y)) -> $[([x] + [y])]
|
||||
|
||||
hs: Gets((c, p), (d, q)) -> <hsget>(c,d,<conc-strings>(p,q),<newname>"fosgt")
|
||||
hsget: (s, x, p, v) -> (v, <concat-strings>[p, $[[v] <- [s] `gets` [x]],
|
||||
"\n"])
|
||||
hs: (Gets(_, xn), Gets(s, x)) -> v
|
||||
with v := <newname>"_fostr_get"
|
||||
; <add-preactions>[$[[v] <- [<hs_gets>(s, xn, x)]]]
|
||||
hs: (To(xn, _), To(x, s)) -> v
|
||||
with v := <newname>"_fostr_to"
|
||||
; <add-preactions>[$[let [v] = [x]], <hs_gets>(s, xn, v)]
|
||||
|
||||
hs: To( (c, p), (d, q)) -> <hsto>(c,d,<conc-strings>(p,q),<newname>"fosto")
|
||||
hsto: (x, s, p, v) -> (v, <concat-strings>[p, $[let [v] = [x]], "\n",
|
||||
$[[s] `gets` [v]], "\n"])
|
||||
hs_gets: (s, xn, x ) -> $[[s] [<hs_getOp>xn] [x]]
|
||||
hs_getOp = get-type; (?STRING() < !"`getsStr`" + !"`gets`")
|
||||
|
||||
hs: Terminate((c,p)) -> ($[[c];;], p)
|
||||
hs: Sequence(l) -> (<last; Fst>l, <map(Snd); concat-strings>l)
|
||||
hs: (_, Terminate(x)) -> $[[x];;]
|
||||
hs: (_, Sequence(l)) -> <last>l
|
||||
/* One drawback of using paramorphism is at the very leaves we have
|
||||
to undouble the tuple:
|
||||
*/
|
||||
hs: (x, x) -> x where <is-string>x
|
||||
|
||||
/* Characters we need to escape in Haskell string constants */
|
||||
Hascape: ['\t' | cs ] -> ['\', 't' | cs ]
|
||||
@ -47,9 +67,15 @@ rules
|
||||
Hascape: [ 12 | cs ] -> ['\', 'f' | cs ] // Form feed
|
||||
|
||||
strategies
|
||||
HaskellEscape = Escape <+ Hascape
|
||||
haskLitString = un-single-quote
|
||||
; string-as-chars(escape-chars(Escape <+ Hascape))
|
||||
; double-quote
|
||||
|
||||
haskell = bottomup(try(hs))
|
||||
haskell = rules(Preactions: () -> ""); bottomup-para(try(hs))
|
||||
|
||||
/* See "Approach" at top of file */
|
||||
add-preactions = newp := <conc-strings>(<Preactions>(), <lines>)
|
||||
; rules(Preactions: () -> newp)
|
||||
|
||||
// Interface haskell code generation with editor services and file system
|
||||
to-haskell: (selected, _, _, path, project-path) -> (filename, result)
|
||||
|
@ -13,7 +13,7 @@ rules
|
||||
|
||||
js: Stream() -> $[Stdio]
|
||||
js: Int(x) -> x
|
||||
js: LitString(x) -> $['[<string-as-chars(escape-chars(JavaEscape))>x]']
|
||||
js: LitString(x) -> <javaLitString>x
|
||||
js: Sum(x,y) -> $[[x] + [y]]
|
||||
js: Gets(x, y) -> $[[x].gets([y])]
|
||||
js: To(x, y) -> $[to([x],[y])]
|
||||
@ -29,7 +29,9 @@ rules
|
||||
Jscape: [ 12 | cs ] -> ['\', 'f' | cs ] // Form feed
|
||||
|
||||
strategies
|
||||
JavaEscape = Escape <+ Jscape
|
||||
javaLitString = un-single-quote
|
||||
; string-as-chars(escape-chars(Escape <+ Jscape))
|
||||
; single-quote
|
||||
|
||||
javascript = bottomup(try(js))
|
||||
|
||||
|
@ -15,7 +15,7 @@ rules
|
||||
|
||||
py: Stream() -> $[Stdio]
|
||||
py: Int(x) -> x
|
||||
py: LitString(x) -> $[r'[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