mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-06 06:48:48 +00:00
Fixed bug with mutable closures in interpret (not really --- up to closure recursion)
This commit is contained in:
parent
1d28f4af6b
commit
dad4c35a80
5 changed files with 31 additions and 7 deletions
|
|
@ -8,9 +8,9 @@ check: $(TESTS)
|
|||
|
||||
$(TESTS): %: %.expr
|
||||
@echo $@
|
||||
$(RC) $< && cat $@.input | ./$@ 2> /dev/null > $@.log && diff $@.log orig/$@.log
|
||||
$(RC) $< && cat $@.input | ./$@ > $@.log && diff $@.log orig/$@.log
|
||||
cat $@.input | $(RC) -i $< > $@.log && diff $@.log orig/$@.log
|
||||
cat $@.input | $(RC) -s $< 2> /dev/null > $@.log && diff $@.log orig/$@.log
|
||||
cat $@.input | $(RC) -s $< > $@.log && diff $@.log orig/$@.log
|
||||
|
||||
clean:
|
||||
$(RM) test*.log *.s *~ $(TESTS)
|
||||
|
|
|
|||
3
regression/orig/test068.log
Normal file
3
regression/orig/test068.log
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
> 1
|
||||
800
|
||||
800
|
||||
19
regression/test068.expr
Normal file
19
regression/test068.expr
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
fun lazy (f) {
|
||||
local flag = 0, value = 0;
|
||||
|
||||
return fun () {
|
||||
if flag
|
||||
then return value
|
||||
else
|
||||
value := f ();
|
||||
flag := 1;
|
||||
return value
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
local l = lazy (fun () {write (1); return 800});
|
||||
local x = read ();
|
||||
|
||||
write (l ());
|
||||
write (l ())
|
||||
1
regression/test068.input
Normal file
1
regression/test068.input
Normal file
|
|
@ -0,0 +1 @@
|
|||
5
|
||||
|
|
@ -295,8 +295,8 @@ module Expr =
|
|||
(* The type of configuration: a state, an input stream, an output stream,
|
||||
and a stack of values
|
||||
*)
|
||||
@type 'a value = ('a, 'a value State.t) Value.t with show,html
|
||||
@type 'a config = 'a value State.t * int list * int list * 'a value list with show,html
|
||||
@type 'a value = ('a, 'a value State.t array) Value.t with show, html
|
||||
@type 'a config = 'a value State.t * int list * int list * 'a value list with show, html
|
||||
(* The type for expressions. Note, in regular OCaml there is no "@type..."
|
||||
notation, it came from GT.
|
||||
*)
|
||||
|
|
@ -411,7 +411,7 @@ module Expr =
|
|||
in
|
||||
match expr with
|
||||
| Lambda (args, body) ->
|
||||
eval (st, i, o, Value.Closure (args, body, st) ::vs) Skip k
|
||||
eval (st, i, o, Value.Closure (args, body, [|st|]) :: vs) Skip k
|
||||
| Scope (defs, body) ->
|
||||
let vars, body, bnds =
|
||||
List.fold_left
|
||||
|
|
@ -442,7 +442,7 @@ module Expr =
|
|||
let v =
|
||||
match State.eval st x with
|
||||
| Value.FunRef (_, args, body, level) ->
|
||||
Value.Closure (args, body, State.prune st level)
|
||||
Value.Closure (args, body, [|State.prune st level|])
|
||||
| v -> v
|
||||
in
|
||||
eval (st, i, o, v :: vs) Skip k
|
||||
|
|
@ -468,8 +468,9 @@ module Expr =
|
|||
| Value.Builtin name ->
|
||||
Builtin.eval (st, i, o, vs') es name
|
||||
| Value.Closure (args, body, closure) ->
|
||||
let st' = State.push (State.leave st closure) (State.from_list @@ List.combine args es) (List.map (fun x -> x, true) args) in
|
||||
let st' = State.push (State.leave st closure.(0)) (State.from_list @@ List.combine args es) (List.map (fun x -> x, true) args) in
|
||||
let st'', i', o', vs'' = eval (st', i, o, []) Skip body in
|
||||
closure.(0) <- st'';
|
||||
(State.leave st'' st, i', o', match vs'' with [v] -> v::vs' | _ -> Value.Empty :: vs')
|
||||
| _ -> invalid_arg (Printf.sprintf "callee did not evaluate to a function: %s" (show(Value.t) (fun _ -> "<expr>") (fun _ -> "<state>") f))
|
||||
))]))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue