forked from glen/fostr
feat: Complete stream extraction
Also implements ++ string concatenation operator. Resolves #7, #18.
This commit is contained in:
parent
7c69b82484
commit
f827c37baa
@ -13,6 +13,9 @@ DESTINATION = 'tests/extracted'
|
||||
# Extension for extracted files:
|
||||
EXT = 'fos'
|
||||
|
||||
# Extension for desired input:
|
||||
INP = 'in'
|
||||
|
||||
# Extension for expectations:
|
||||
EXP = 'expect'
|
||||
|
||||
@ -34,6 +37,11 @@ for path in TEST_LIST:
|
||||
expath = destdir / f"{name}.{EXT}"
|
||||
expath.write_text(example)
|
||||
echo Wrote @(expath)
|
||||
im = re.search(r'/\*\*\s+accepts.*?\n([\s\S]*?)\*\*/', details[em.end():])
|
||||
if im:
|
||||
ipath = destdir / f"{name}.{INP}"
|
||||
ipath.write_text(im[1])
|
||||
echo " ...and" @(ipath)
|
||||
xm = re.search(r'/\*\*\s+writes.*?\n([\s\S]*?)\*\*/', details[em.end():])
|
||||
if xm:
|
||||
xpath = destdir / f"{name}.{EXP}"
|
||||
|
@ -9,8 +9,14 @@ diffed=0
|
||||
for dir in tests/extracted/*; do
|
||||
for file in $dir/*.$ext; do
|
||||
((total++))
|
||||
$command $file > $file.out
|
||||
if [[ $? -ne 0 ]]; then
|
||||
if [[ -f ${file%.*}.in ]]; then
|
||||
cat ${file%.*}.in | $command $file > $file.out
|
||||
result=$?
|
||||
else
|
||||
$command $file > $file.out
|
||||
result=$?
|
||||
fi
|
||||
if [[ $result -ne 0 ]]; then
|
||||
echo ERROR: $command $file failed.
|
||||
((failed++))
|
||||
else
|
||||
|
@ -9,7 +9,7 @@ plugins:
|
||||
- search
|
||||
- semiliterate:
|
||||
ignore_folders: [target, lib]
|
||||
exclude_extensions: ['.o', '.hi']
|
||||
exclude_extensions: ['.o', '.hi', '.cmi', '.cmo']
|
||||
extract_standard_markdown:
|
||||
terminate: <!-- /md -->
|
||||
theme:
|
||||
|
@ -293,7 +293,7 @@ test emit_several_default [[
|
||||
>>>
|
||||
]] parse succeeds
|
||||
/** writes
|
||||
3399677527121313*/
|
||||
3399677527121313**/
|
||||
|
||||
/** md
|
||||
### Streams are bidirectional
|
||||
@ -318,12 +318,13 @@ Kilroy
|
||||
**/
|
||||
/** writes
|
||||
What is your name?
|
||||
Hello, Kilroy**/
|
||||
Hello, Kilroy
|
||||
**/
|
||||
|
||||
/** md
|
||||
```
|
||||
|
||||
queries users for their name and then writes a customized greeting. It also
|
||||
illustratesthe use of `++` for string concatenation, as opposed to `+` for
|
||||
illustrates the use of `++` for string concatenation, as opposed to `+` for
|
||||
(numerical) addition.
|
||||
**/
|
||||
|
@ -23,6 +23,7 @@ rules
|
||||
import System.IO
|
||||
data IOStream = StdIO
|
||||
|
||||
-- Danger: These currently assume the stream is StdIO
|
||||
gets :: Show b => a -> b -> IO a
|
||||
gets s d = do
|
||||
putStr(show d)
|
||||
@ -33,6 +34,8 @@ rules
|
||||
putStr(d)
|
||||
return s
|
||||
|
||||
emit s = getLine
|
||||
|
||||
main = do
|
||||
[<Preactions>()]return [val]]
|
||||
|
||||
@ -41,6 +44,7 @@ rules
|
||||
hs: (_, LitString(x)) -> <haskLitString>x
|
||||
hs: (_, EscString(x)) -> x
|
||||
hs: (_, Sum(x, y)) -> $[([x] + [y])]
|
||||
hs: (_, Concat(x, y)) -> $[([x] ++ [y])]
|
||||
|
||||
hs: (Gets(_, xn), Gets(s, x)) -> v
|
||||
with v := <newname>"_fostr_get"
|
||||
@ -52,6 +56,10 @@ rules
|
||||
hs_gets: (s, xn, x ) -> $[[s] [<hs_getOp>xn] [x]]
|
||||
hs_getOp = get-type; (?STRING() < !"`getsStr`" + !"`gets`")
|
||||
|
||||
hs: (_, Emits(s)) -> v
|
||||
with v := <newname>"_fostr_emitted"
|
||||
; <add-preactions>[$[[v] <- emit [s]]]
|
||||
|
||||
hs: (_, Terminate(x)) -> $[[x];;]
|
||||
hs: (_, Sequence(l)) -> <last>l
|
||||
/* One drawback of using paramorphism is we have to handle lists
|
||||
|
@ -3,24 +3,41 @@ imports libstrategolib signatures/- util
|
||||
|
||||
rules
|
||||
js: TopLevel(x) -> $[// Fostr preamble
|
||||
const _fostr_readline = require('readline');
|
||||
const _fostr_events = require('events');
|
||||
const _fostr_rl = _fostr_readline.createInterface({input: process.stdin});
|
||||
const Stdio = {
|
||||
gets: v => { process.stdout.write(String(v)); return Stdio; },
|
||||
gets: v => { process.stdout.write(String(v)); return Stdio; },
|
||||
emit: async () => {
|
||||
const [line] = await _fostr_events.once(_fostr_rl, 'line');
|
||||
return line + "\n"; }
|
||||
}
|
||||
function to(data, strm) {
|
||||
strm.gets(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
const _fostr_body = async () => {
|
||||
// End of preamble
|
||||
|
||||
[x]]
|
||||
[x]
|
||||
|
||||
// Fostr coda
|
||||
_fostr_rl.close()
|
||||
}
|
||||
_fostr_body();
|
||||
]
|
||||
with line := "[line]"
|
||||
|
||||
js: Stream() -> $[Stdio]
|
||||
js: Int(x) -> x
|
||||
js: LitString(x) -> <javaLitString>x
|
||||
js: EscString(x) -> x
|
||||
js: Sum(x,y) -> $[[x] + [y]]
|
||||
js: Sum(x, y) -> $[[x] + [y]]
|
||||
js: Concat(x, y) -> $[[x] + [y]]
|
||||
js: Gets(x, y) -> $[[x].gets([y])]
|
||||
js: To(x, y) -> $[to([x],[y])]
|
||||
js: Emits(x) -> $[(await [x].emit())]
|
||||
js: Terminate(x) -> x
|
||||
js: Sequence(l) -> <join(|";\n")>l
|
||||
|
||||
|
@ -12,9 +12,10 @@ imports libstrategolib signatures/- util signature/TYPE analysis
|
||||
|
||||
rules
|
||||
ml: (_, TopLevel(x)) -> $[(* fostr preamble *)
|
||||
type stream = { getS: string -> stream }
|
||||
type stream = { getS: string -> stream; emitS: unit -> string }
|
||||
let rec stdio = {
|
||||
getS = (fun s -> print_string s; stdio)
|
||||
getS = (fun s -> print_string s; stdio);
|
||||
emitS = (fun () -> (read_line ()) ^ "\n");
|
||||
};;
|
||||
(* End of preamble *)
|
||||
|
||||
@ -24,11 +25,15 @@ rules
|
||||
ml: (_, Int(x)) -> x
|
||||
ml: (_, LitString(x)) -> $[{|[<un-single-quote>x]|}]
|
||||
ml: (_, EscString(x)) -> x
|
||||
ml: (_, Sum(x,y)) -> $[[x] + [y]]
|
||||
ml: (_, Sum(x, y)) -> $[[x] + [y]]
|
||||
ml: (_, Concat(x, y)) -> $[[x] ^ [y]]
|
||||
|
||||
ml: (Gets(_,yn), Gets(x, y))
|
||||
-> $[([x]).getS ([<ml_str>(yn,y)])]
|
||||
ml: (To(xn,_), To(x, y))
|
||||
-> $[let _fto = ([x]) in (ignore (([y]).getS ([<ml_str>(xn,"_fto")])); _fto)]
|
||||
ml: (_, Emits(s)) -> $[[s].emitS ()]
|
||||
|
||||
ml: (_, Terminate(x)) -> x
|
||||
ml: (_, Sequence(l)) -> <ml_seq>l
|
||||
|
||||
|
@ -9,7 +9,7 @@ rules
|
||||
print(v, file=sys.stdout, end='')
|
||||
return self
|
||||
def emit(self):
|
||||
return input()
|
||||
return input() + "\n" # Python inconsistently strips when using input
|
||||
def to(data,strm):
|
||||
strm.gets(data)
|
||||
return data
|
||||
|
Loading…
Reference in New Issue
Block a user