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
|
bunch of coding. The language will be centrally organized around the
|
||||||
concept of "streams" (somewhat in the spirit of
|
concept of "streams" (somewhat in the spirit of
|
||||||
[streem](https://github.com/matz/streem) and/or
|
[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
|
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").
|
and (binary) ++o++perators are ++str++eams" (hence the name "fostr").
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ lexical sorts
|
|||||||
|
|
||||||
lexical syntax
|
lexical syntax
|
||||||
|
|
||||||
STRING_LITERAL = ~[\']*
|
STRING_LITERAL = "'"~[\']*"'"
|
||||||
|
|
||||||
context-free sorts
|
context-free sorts
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ context-free syntax
|
|||||||
TermEx.Terminate = <<Ex>;>
|
TermEx.Terminate = <<Ex>;>
|
||||||
|
|
||||||
Ex.Int = INT
|
Ex.Int = INT
|
||||||
Ex.LitString = <'<STRING_LITERAL>'>
|
Ex.LitString = STRING_LITERAL
|
||||||
Ex.Stream = <stream>
|
Ex.Stream = <stream>
|
||||||
Ex.Sum = <<Ex> + <Ex>> {left}
|
Ex.Sum = <<Ex> + <Ex>> {left}
|
||||||
Ex.Gets = [[Ex] << [Ex]] {left}
|
Ex.Gets = [[Ex] << [Ex]] {left}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
module basic
|
module basic
|
||||||
language fostr
|
language fostr
|
||||||
|
|
||||||
|
|
||||||
test hw1_type [[
|
test hw1_type [[
|
||||||
[[stream]] << [['Hello, world!']]
|
[[stream]] << [['Hello, world! ']] << [[3+2]] << ' times.'
|
||||||
]]
|
]]
|
||||||
run get-type on #1 to STREAM()
|
run get-type on #1 to STREAM()
|
||||||
run get-type on #2 to STRING()
|
run get-type on #2 to STRING()
|
||||||
|
run get-type on #3 to INT()
|
||||||
run get-type to STREAM()
|
run get-type to STREAM()
|
||||||
/** writes
|
/** writes
|
||||||
Hello, world!**/
|
Hello, world! 5 times.**/
|
||||||
|
|
||||||
/** md
|
/** md
|
||||||
Title: A whirlwind tour of fostr
|
Title: A whirlwind tour of fostr
|
||||||
|
@ -1,15 +1,25 @@
|
|||||||
module haskell
|
module haskell
|
||||||
imports libstrategolib signatures/- util
|
imports libstrategolib signatures/- util analysis
|
||||||
rules
|
rules
|
||||||
/* Approach: Generate code from the bottom up.
|
/* Approach:
|
||||||
At every node, we create a pair of the implementation and
|
A) We will define a local transformation taking a term with value strings
|
||||||
necessary preamble of IO actions.
|
at each child to a value string for the node.
|
||||||
We concatenate preambles as we go up.
|
B) We will append IO actions needed to set up for the value progressively
|
||||||
Finally, at the toplevel we emit the preamble before returning the
|
to a Preactions rule (mapping () to the list of actions). There will
|
||||||
final value.
|
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
|
data IOStream = StdIO
|
||||||
|
|
||||||
gets :: Show b => a -> b -> IO a
|
gets :: Show b => a -> b -> IO a
|
||||||
@ -17,25 +27,35 @@ rules
|
|||||||
putStr(show d)
|
putStr(show d)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
getsStr :: a -> String -> IO a
|
||||||
|
getsStr s d = do
|
||||||
|
putStr(d)
|
||||||
|
return s
|
||||||
|
|
||||||
main = do
|
main = do
|
||||||
[p]return [c]]
|
[<Preactions>()]return [val]]
|
||||||
|
|
||||||
hs: Stream() -> ("StdIO", "")
|
hs: (_, Stream()) -> "StdIO"
|
||||||
hs: Int(x) -> (x, "")
|
hs: (_, Int(x)) -> x
|
||||||
hs: LitString(x)
|
hs: (_, LitString(x)) -> <haskLitString>x
|
||||||
-> ($["[<string-as-chars(escape-chars(HaskellEscape))>x]"], "")
|
hs: (_, Sum(x, y)) -> $[([x] + [y])]
|
||||||
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(_, xn), Gets(s, x)) -> v
|
||||||
hsget: (s, x, p, v) -> (v, <concat-strings>[p, $[[v] <- [s] `gets` [x]],
|
with v := <newname>"_fostr_get"
|
||||||
"\n"])
|
; <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")
|
hs_gets: (s, xn, x ) -> $[[s] [<hs_getOp>xn] [x]]
|
||||||
hsto: (x, s, p, v) -> (v, <concat-strings>[p, $[let [v] = [x]], "\n",
|
hs_getOp = get-type; (?STRING() < !"`getsStr`" + !"`gets`")
|
||||||
$[[s] `gets` [v]], "\n"])
|
|
||||||
|
|
||||||
hs: Terminate((c,p)) -> ($[[c];;], p)
|
hs: (_, Terminate(x)) -> $[[x];;]
|
||||||
hs: Sequence(l) -> (<last; Fst>l, <map(Snd); concat-strings>l)
|
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 */
|
/* Characters we need to escape in Haskell string constants */
|
||||||
Hascape: ['\t' | cs ] -> ['\', 't' | cs ]
|
Hascape: ['\t' | cs ] -> ['\', 't' | cs ]
|
||||||
@ -47,9 +67,15 @@ rules
|
|||||||
Hascape: [ 12 | cs ] -> ['\', 'f' | cs ] // Form feed
|
Hascape: [ 12 | cs ] -> ['\', 'f' | cs ] // Form feed
|
||||||
|
|
||||||
strategies
|
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
|
// Interface haskell code generation with editor services and file system
|
||||||
to-haskell: (selected, _, _, path, project-path) -> (filename, result)
|
to-haskell: (selected, _, _, path, project-path) -> (filename, result)
|
||||||
|
@ -13,7 +13,7 @@ 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: LitString(x) -> <javaLitString>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])]
|
||||||
@ -29,7 +29,9 @@ rules
|
|||||||
Jscape: [ 12 | cs ] -> ['\', 'f' | cs ] // Form feed
|
Jscape: [ 12 | cs ] -> ['\', 'f' | cs ] // Form feed
|
||||||
|
|
||||||
strategies
|
strategies
|
||||||
JavaEscape = Escape <+ Jscape
|
javaLitString = un-single-quote
|
||||||
|
; string-as-chars(escape-chars(Escape <+ Jscape))
|
||||||
|
; single-quote
|
||||||
|
|
||||||
javascript = bottomup(try(js))
|
javascript = bottomup(try(js))
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ rules
|
|||||||
|
|
||||||
py: Stream() -> $[Stdio]
|
py: Stream() -> $[Stdio]
|
||||||
py: Int(x) -> x
|
py: Int(x) -> x
|
||||||
py: LitString(x) -> $[r'[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])]
|
||||||
|
Loading…
Reference in New Issue
Block a user