summaryrefslogtreecommitdiff
path: root/src/lem_interp/interp.lem
diff options
context:
space:
mode:
Diffstat (limited to 'src/lem_interp/interp.lem')
-rw-r--r--src/lem_interp/interp.lem68
1 files changed, 38 insertions, 30 deletions
diff --git a/src/lem_interp/interp.lem b/src/lem_interp/interp.lem
index 6febc709..4965deb8 100644
--- a/src/lem_interp/interp.lem
+++ b/src/lem_interp/interp.lem
@@ -398,30 +398,6 @@ let rec fupdate_record base updates =
end
-val update_vector_slice : value -> value -> lmem -> lmem
-let rec update_vector_slice vector value mem =
- match (vector,value) with
- | ((V_vector m inc vs),(V_vector n inc2 vals)) ->
- foldr2 (fun vbox v mem -> match vbox with
- | V_boxref n t -> update_mem mem n v end)
- mem vs vals
- | ((V_vector m inc vs),(V_vector_sparse n o inc2 vals d)) ->
- let (_,mem) = foldr (fun vbox (i,mem) ->
- match vbox with
- | V_boxref n t ->
- (if inc then i+1 else i-1,
- update_mem mem n (match List.lookup i vals with
- | Nothing -> d
- | Just v -> v end))
- end) (m,mem) vs in
- mem
- | ((V_vector m inc vs),v) ->
- List.foldr (fun vbox mem -> match vbox with
- | V_boxref n t -> update_mem mem n v end)
- mem vs
- | (V_track v1 r1, v) -> (update_vector_slice v1 value mem)
-end
-
val fupdate_sparse : (integer -> integer -> bool) -> list (integer*value) -> integer -> value -> list (integer*value)
let rec fupdate_sparse compare vs n vexp =
match vs with
@@ -444,6 +420,7 @@ let rec fupdate_vec v n vexp =
| _ -> V_track (fupdate_vec v n vexp) r end)
end
+
val replace_is : forall 'a. list 'a -> list 'a -> integer -> integer -> integer -> list 'a
let rec replace_is ls vs base start stop =
match (ls,vs) with
@@ -451,7 +428,7 @@ let rec replace_is ls vs base start stop =
| (ls,[]) -> ls
| (l::ls,v::vs) ->
if base >= start then
- if start >= stop then ls
+ if start >= stop then v::ls
else v::(replace_is ls vs (base + 1) (start + 1) stop)
else l::(replace_is ls (v::vs) (base+1) start stop)
end
@@ -484,6 +461,35 @@ let rec fupdate_vector_slice vec replace start stop =
| (vec, V_track vr rr) -> taint (fupdate_vector_slice vec vr start stop) rr
end
+val update_vector_slice : value -> value -> integer -> integer -> lmem -> lmem
+let rec update_vector_slice vector value start stop mem =
+ match (vector,value) with
+ | ((V_boxref n t), v) ->
+ update_mem mem n (fupdate_vector_slice (in_mem mem n) v start stop)
+ | ((V_vector m inc vs),(V_vector n inc2 vals)) ->
+ let (V_vector m' _ vs') = slice_vector vector start stop in
+ foldr2 (fun vbox v mem -> match vbox with
+ | V_boxref n t -> update_mem mem n v end)
+ mem vs' vals
+ | ((V_vector m inc vs),(V_vector_sparse n o inc2 vals d)) ->
+ let (V_vector m' _ vs') = slice_vector vector start stop in
+ let (_,mem) = foldr (fun vbox (i,mem) ->
+ match vbox with
+ | V_boxref n t ->
+ (if inc then i+1 else i-1,
+ update_mem mem n (match List.lookup i vals with
+ | Nothing -> d
+ | Just v -> v end))
+ end) (m,mem) vs' in
+ mem
+ | ((V_vector m inc vs),v) ->
+ let (V_vector m' _ vs') = slice_vector vector start stop in
+ List.foldr (fun vbox mem -> match vbox with
+ | V_boxref n t -> update_mem mem n v end)
+ mem vs'
+ | (V_track v1 r1, v) -> (update_vector_slice v1 value start stop mem)
+end
+
val in_ctors : list (id * typ) -> id -> maybe typ
let rec in_ctors ctors id =
match ctors with
@@ -1776,10 +1782,10 @@ and create_write_message_or_update mode t_level value l_env l_mem is_top_level (
match tag with
| Tag_empty ->
match in_lenv l_env id with
- | (V_boxref n t) ->
+ | ((V_boxref n t) as v) ->
if is_top_level
then ((Value (V_lit (L_aux L_unit l)), update_mem l_mem n value, l_env),Nothing)
- else ((Value (in_mem l_mem n), l_mem, l_env),Just (fun e env -> (LEXP_aux (LEXP_id id) (l,annot), env)))
+ else ((Value v, l_mem, l_env),Just (fun e env -> (LEXP_aux (LEXP_id id) (l,annot), env)))
| V_unknown ->
if is_top_level then
let (LMem c m) = l_mem in
@@ -1891,10 +1897,10 @@ and create_write_message_or_update mode t_level value l_env l_mem is_top_level (
match tag with
| Tag_empty ->
match in_lenv l_env id with
- | V_boxref n t ->
+ | ((V_boxref n t) as v) ->
if is_top_level
then ((Value (V_lit (L_aux L_unit l)), update_mem l_mem n value, l_env),Nothing)
- else ((Value (in_mem l_mem n), l_mem, l_env),Just (fun e env -> (LEXP_aux (LEXP_cast typc id) (l,annot), env)))
+ else ((Value v, l_mem, l_env),Just (fun e env -> (LEXP_aux (LEXP_cast typc id) (l,annot), env)))
| V_unknown ->
if is_top_level
then begin
@@ -1992,7 +1998,9 @@ and create_write_message_or_update mode t_level value l_env l_mem is_top_level (
| ((Value v,lm,le), Just lexp_builder) ->
(match (v,is_top_level) with
| (V_vector m inc vs,true) ->
- ((Value (V_lit (L_aux L_unit Unknown)), update_vector_slice (slice_vector v n1 n2) value lm, l_env), Nothing)
+ ((Value (V_lit (L_aux L_unit Unknown)), update_vector_slice v value n1 n2 lm, l_env), Nothing)
+ | (V_boxref _ _, true) ->
+ ((Value (V_lit (L_aux L_unit Unknown)), update_vector_slice v value n1 n2 lm, l_env), Nothing)
| (V_vector m inc vs,false) ->
((Value (slice_vector v n1 n2),lm,l_env), Just (next_builder lexp_builder))
| _ -> ((Error l "Vector required",lm,le),Nothing) end)