Better scoping in repeat/for, lazy expression (no implicit import yet)

This commit is contained in:
Dmitry Boulytchev 2020-02-14 08:13:52 +03:00
parent cf78cd20e3
commit 556ce81106
11 changed files with 42 additions and 16 deletions

View file

@ -1,3 +1 @@
> > > 0 > > > 5
0
5

View file

@ -0,0 +1,10 @@
> 0
1
2
3
4
5
6
7
8
9

View file

@ -1,4 +1,4 @@
fun lazy (f) { fun makeLazy (f) {
local flag = 0, value = 0; local flag = 0, value = 0;
return fun () { return fun () {
@ -12,7 +12,7 @@ fun lazy (f) {
} }
} }
local l = lazy (fun () {write (1); return 800}); local l = makeLazy (fun () {write (1); return 800});
local x = read (); local x = read ();
write (l ()); write (l ());

View file

@ -1,4 +1,4 @@
fun lazy (f) { fun makeLazy (f) {
local flag = 0, value = 0; local flag = 0, value = 0;
fun () { fun () {
@ -12,7 +12,7 @@ fun lazy (f) {
} }
} }
local l = lazy (fun () {write (1); 800}); local l = makeLazy (fun () {write (1); 800});
local x = read (); local x = read ();
write (l ()); write (l ());

View file

@ -1,4 +1,8 @@
local x;
repeat repeat
local n = read (); local n = read ();
write (n) x := n
until n > 0 until n > 0;
write (x)

5
regression/test104.expr Normal file
View file

@ -0,0 +1,5 @@
local n = read ();
for local i; i := 0, i<10, i := i + 1 do
write (i)
od

1
regression/test104.input Normal file
View file

@ -0,0 +1 @@
5

View file

@ -14,7 +14,7 @@ let parse cmd =
"case"; "of"; "esac"; "when"; "case"; "of"; "esac"; "when";
"boxed"; "unboxed"; "string"; "sexp"; "array"; "boxed"; "unboxed"; "string"; "sexp"; "array";
"infix"; "infixl"; "infixr"; "at"; "before"; "after"; "infix"; "infixl"; "infixr"; "at"; "before"; "after";
"true"; "false"] "true"; "false"; "lazy"]
in in
Util.parse Util.parse
(object (object

View file

@ -731,8 +731,14 @@ module Expr =
| %"while" e:parse[def][infix][Val] %"do" s:scope[def][infix][Void][parse def] | %"while" e:parse[def][infix][Val] %"do" s:scope[def][infix][Void][parse def]
=> {isVoid atr} => %"od" {materialize atr (While (e, s))} => {isVoid atr} => %"od" {materialize atr (While (e, s))}
| %"for" i:parse[def][infix][Void] "," c:parse[def][infix][Val] "," s:parse[def][infix][Void] %"do" b:scope[def][infix][Void][parse def] => {isVoid atr} => %"od" | %"for" i:scope[def][infix][Void][parse def] ","
{materialize atr (Seq (i, While (c, Seq (b, s))))} c:parse[def][infix][Val] ","
s:parse[def][infix][Void] %"do" b:scope[def][infix][Void][parse def] => {isVoid atr} => %"od"
{materialize atr
(match i with
| Scope (defs, i) -> Scope (defs, Seq (i, While (c, Seq (b, s))))
| _ -> Seq (i, While (c, Seq (b, s))))
}
| %"repeat" s:scope[def][infix][Void][parse def] %"until" e:basic[def][infix][Val] => {isVoid atr} => { | %"repeat" s:scope[def][infix][Void][parse def] %"until" e:basic[def][infix][Val] => {isVoid atr} => {
materialize atr @@ materialize atr @@
@ -754,6 +760,8 @@ module Expr =
| %"case" l:$ e:parse[def][infix][Val] %"of" bs:!(Util.listBy)[ostap ("|")][ostap (!(Pattern.parse) -"->" scope[def][infix][atr][parse def])] %"esac" | %"case" l:$ e:parse[def][infix][Val] %"of" bs:!(Util.listBy)[ostap ("|")][ostap (!(Pattern.parse) -"->" scope[def][infix][atr][parse def])] %"esac"
{Case (e, bs, l#coord, atr)} {Case (e, bs, l#coord, atr)}
| l:$ %"lazy" e:basic[def][infix][Val] => {notRef atr} :: (not_a_reference l) => {ignore atr (Call (Var "makeLazy", [Lambda ([], e)]))}
| -"(" parse[def][infix][atr] -")" | -"(" parse[def][infix][atr] -")"
) )

View file

@ -1,4 +1,4 @@
public fun lazy (f) { public fun makeLazy (f) {
local value, set = false; local value, set = false;
fun () { fun () {