Add literal string constants #19

Merged
glen merged 6 commits from string_literal into main 2021-02-18 04:17:05 +00:00
6 changed files with 62 additions and 33 deletions
Showing only changes of commit 804a00902a - Show all commits

View File

@ -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").

View File

@ -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}

View File

@ -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

View File

@ -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)

View File

@ -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))

View File

@ -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])]