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.lem256
1 files changed, 147 insertions, 109 deletions
diff --git a/src/lem_interp/interp.lem b/src/lem_interp/interp.lem
index a16d81cc..a57c71a4 100644
--- a/src/lem_interp/interp.lem
+++ b/src/lem_interp/interp.lem
@@ -1,22 +1,26 @@
open import Pervasives
import Map
import Map_extra
-import Maybe
import List_extra
-import String
+open import String_extra
open import Interp_ast
type tannot = maybe (t * tag * list nec * effect)
+val pure : effect
+let pure = Effect_aux(Effect_set []) Unknown
+
val intern_annot : tannot -> tannot
let intern_annot annot =
match annot with
| Just (t,_,ncs,effect) ->
- Just (t,Tag_empty,ncs,Effect_aux (Effect_set []) Unknown)
+ Just (t,Tag_empty,ncs,pure)
| Nothing -> Nothing
end
+let val_annot typ = Just(typ,Tag_empty,[],pure)
+
(* Workaround Lem's inability to scrap my (type classes) boilerplate.
* Implementing only Eq, and only for literals - hopefully this will
* be enough, but we should in principle implement ordering for everything in
@@ -163,8 +167,8 @@ let get_effects (Typ_aux t _) =
(*Look for externs as well*)
val to_memory_ops : defs tannot -> list (id * typ)
-let rec to_memory_ops (Defs defs) =
- match defs with
+let rec to_memory_ops (Defs defs) = []
+(* match defs with
| [] -> []
| (DEF_aux def _) ::defs ->
match def with
@@ -184,11 +188,11 @@ let rec to_memory_ops (Defs defs) =
if has_memory_effect eff then (id,t)::(to_memory_ops (Defs defs)) else (to_memory_ops (Defs defs))
| _ -> to_memory_ops (Defs defs) end
| _ -> to_memory_ops (Defs defs) end
- end
+ end*)
val to_externs : defs tannot -> list (id * string)
-let rec to_externs (Defs defs) =
- match defs with
+let rec to_externs (Defs defs) = []
+(* match defs with
| [] -> []
| (DEF_aux def _) ::defs ->
match def with
@@ -198,7 +202,7 @@ let rec to_externs (Defs defs) =
(id,s)::(to_externs (Defs defs))
| _ -> to_externs (Defs defs) end
| _ -> to_externs (Defs defs) end
- end
+ end*)
val to_data_constructors : defs tannot -> list (id * typ)
let rec to_data_constructors (Defs defs) =
@@ -253,8 +257,8 @@ let litV_to_vec (L_aux lit l) =
V_vector 0 true []
| L_bin s ->
let bits = String.toCharList s in
- let exploded_bits = List.map (fun c -> String.toString [c]) bits in
- let bits = List.map (fun s -> match s with | "0" -> (V_lit (L_aux L_zero l)) | "1" -> (V_lit (L_aux L_one l)) end) exploded_bits in
+ let exploded_bits = bits in (*List.map (fun c -> String.toString [c]) bits in*)
+ let bits = List.map (fun s -> match s with | #'0' -> (V_lit (L_aux L_zero l)) | #'1' -> (V_lit (L_aux L_one l)) end) exploded_bits in
(* XXX assume binary constants are written in big-endian, convert them to
* little-endian by default - we might need syntax to change both of those
* assumptions. *)
@@ -282,13 +286,15 @@ val from_n_to_n :forall 'a. natural -> natural -> natural -> list 'a -> list 'a
let rec from_n_to_n from to_ acc ls =
match ls with
| [] -> []
- | l::ls ->
- if (acc <= from)
- then if (from = to_)
- then [ l ]
- else l::(from_n_to_n (from + 1) to_ acc ls)
- else from_n_to_n from to_ (acc + 1) ls
- end
+ | l::ls ->
+ if from > acc
+ then from_n_to_n from to_ acc ls
+ else if from = to_
+ then [l]
+ else l::(from_n_to_n from to_ acc ls)
+end
+
+(*Needs debugging*)
val slice_vector : value -> natural -> natural -> value
let slice_vector v n1 n2 =
@@ -440,7 +446,7 @@ let rec val_typ v =
let rec to_exp v =
E_aux
(match v with
- | V_boxref n t -> E_id (Id_aux (Id ("XXX string_of_num n")) Unknown)
+ | V_boxref n t -> E_id (Id_aux (Id (show n)) Unknown)
| V_lit lit -> E_lit lit
| V_tuple(vals) -> E_tuple (List.map to_exp vals)
| V_vector n inc vals ->
@@ -457,7 +463,7 @@ let rec to_exp v =
| V_list(vals) -> E_list (List.map to_exp vals)
| V_ctor id t vals -> E_app id [to_exp vals]
end)
- (Unknown,Nothing)
+ (Unknown,(val_annot (val_typ v)))
val find_type_def : defs tannot -> id -> maybe (type_def tannot)
val find_function : defs tannot -> id -> maybe (list (funcl tannot))
@@ -691,7 +697,7 @@ and interp_main t_level l_env l_mem (E_aux exp (l,annot)) =
let regf = Reg id typ in
(Action (Read_reg regf Nothing)
(Frame (Id_aux (Id "0") Unknown)
- (E_aux (E_id (Id_aux (Id "0") l)) (l,Just(typ,Tag_empty,ncs,effect))) l_env l_mem Top),
+ (E_aux (E_id (Id_aux (Id "0") l)) (l,intern_annot annot)) l_env l_mem Top),
l_mem,l_env)
| _ -> (Error l (String.stringAppend "Internal error: tag other than empty,enum,or extern " name),l_mem,l_env)
end
@@ -700,54 +706,59 @@ and interp_main t_level l_env l_mem (E_aux exp (l,annot)) =
(fun value lm le ->
match value with
| V_lit(L_aux L_true _) -> interp_main t_level l_env lm thn
- | V_lit(L_aux L_false _) -> interp_main t_level l_env lm els
- | _ -> (Error l "Type error, not provided boolean for if",lm,l_env) end)
+ | V_lit(L_aux L_false _) -> interp_main t_level l_env lm els end)
(fun a -> update_stack a (add_to_top_frame (fun c -> (E_aux (E_if c thn els) (l,annot)))))
- | E_for id from to_ by order exp ->
+ | E_for id from to_ by ((Ord_aux o _) as order) exp ->
+ let is_inc = match o with
+ | Ord_inc -> true
+ | _ -> false end in
resolve_outcome (interp_main t_level l_env l_mem from)
(fun from_val lm le ->
match from_val with
- | V_lit(L_aux(L_num from_num) _) ->
+ | (V_lit(L_aux(L_num from_num) fl) as fval) ->
resolve_outcome (interp_main t_level le lm to_)
(fun to_val lm le ->
match to_val with
- | V_lit(L_aux (L_num to_num) _) ->
+ | (V_lit(L_aux (L_num to_num) tl) as tval) ->
resolve_outcome
(interp_main t_level le lm by)
(fun by_val lm le ->
match by_val with
- | V_lit (L_aux (L_num by_num) _) ->
+ | (V_lit (L_aux (L_num by_num) bl) as bval) ->
if (from_num = to_num)
- then (Value(V_lit (L_aux L_unit Unknown)),lm,le)
- else interp_main t_level le lm
- (E_aux
- (E_block
- [(E_aux (E_let
- (LB_aux (LB_val_implicit
- (P_aux (P_id id) (Unknown,Nothing))
- (E_aux (E_lit(L_aux(L_num from_num) Unknown)) (Unknown,Nothing)))
- (Unknown,Nothing))
- exp) (Unknown,Nothing));
- (E_aux (E_for id
- (E_aux (E_lit (L_aux (L_num (from_num + by_num)) Unknown))
- (Unknown,Nothing))
- (E_aux (E_lit (L_aux (L_num to_num) Unknown)) (Unknown,Nothing))
- (E_aux (E_lit (L_aux (L_num by_num) Unknown)) (Unknown,Nothing))
- order exp) (l,annot))])
- (l,annot))
- | _ -> (Error l "by must be a number",lm,le) end)
+ then (Value(V_lit (L_aux L_unit l)),lm,le)
+ else
+ let (ftyp,ttyp,btyp) = (val_typ fval,val_typ tval,val_typ bval) in
+ interp_main t_level le lm
+ (E_aux
+ (E_block
+ [(E_aux (E_let
+ (LB_aux (LB_val_implicit
+ (P_aux (P_id id) (fl,val_annot ftyp))
+ (E_aux (E_lit(L_aux(L_num from_num) fl)) (fl,val_annot ftyp)))
+ (Unknown,val_annot ftyp))
+ exp) (l,annot));
+ (E_aux (E_for id
+ (if is_inc
+ then (E_aux (E_lit (L_aux (L_num (from_num + by_num)) fl)) (fl,val_annot (combine_typs [ftyp;ttyp])))
+ else (E_aux (E_lit (L_aux (L_num (from_num - by_num)) fl)) (fl,val_annot (combine_typs [ttyp;ftyp]))))
+ (E_aux (E_lit (L_aux (L_num to_num) tl)) (tl,val_annot ttyp))
+ (E_aux (E_lit (L_aux (L_num by_num) bl)) (bl,val_annot btyp))
+ order exp) (l,annot))])
+ (l,annot))
+ | _ -> (Error l "internal error: by must be a number",lm,le) end)
(fun a -> update_stack a
(add_to_top_frame (fun b ->
(E_aux (E_for id
- (E_aux (E_lit (L_aux (L_num from_num) Unknown)) (Unknown,Nothing))
- (E_aux (E_lit (L_aux (L_num to_num) Unknown)) (Unknown,Nothing))
+ (E_aux (E_lit (L_aux (L_num from_num) fl)) (fl,(val_annot (val_typ fval))))
+ (E_aux (E_lit (L_aux (L_num to_num) tl)) (tl,(val_annot (val_typ tval))))
b order exp) (l,annot)))))
- | _ -> (Error l "to must be a number",lm,le) end)
+ | _ -> (Error l "internal error: to must be a number",lm,le) end)
(fun a -> update_stack a
(add_to_top_frame (fun t ->
- (E_aux (E_for id (E_aux (E_lit (L_aux (L_num from_num) Unknown)) (Unknown,Nothing))
+ (E_aux (E_for id (E_aux (E_lit (L_aux (L_num from_num) fl)) (fl,val_annot (val_typ fval)))
t by order exp) (l,annot)))))
- | _ -> (Error l "from must be a number",lm,le) end)
+ | _ -> (Error l "internal error: from must be a number",lm,le) end)
(fun a -> update_stack a (add_to_top_frame (fun f -> (E_aux (E_for id f to_ by order exp) (l,annot)))))
| E_case exp pats ->
resolve_outcome (interp_main t_level l_env l_mem exp)
@@ -908,77 +919,103 @@ and interp_main t_level l_env l_mem (E_aux exp (l,annot)) =
exp_list t_level (fun exps -> E_aux (E_vector exps) (l,annot)) (fun vals -> V_vector 0 true vals) l_env l_mem [] exps
| E_vector_indexed(iexps) ->
let (indexes,exps) = List.unzip iexps in
+ let is_inc = match typ with
+ | T_app (Id_aux (Id "vector") _) (T_args [T_arg_nexp _;T_arg_nexp _; T_arg_order (Ord_aux Ord_inc _); _]) -> true
+ | _ -> false end in
exp_list t_level (fun es -> (E_aux (E_vector_indexed (map2 (fun i e -> (i,e)) indexes es)) (l,annot)))
- (fun vals -> V_vector (List_extra.head indexes) true vals) (*Need to see increasing or not, can look at types later*) l_env l_mem [] exps
+ (fun vals -> V_vector (List_extra.head indexes) is_inc vals) l_env l_mem [] exps
| E_block(exps) -> interp_block t_level l_env l_env l_mem exps
| E_app f args ->
(match (exp_list t_level (fun es -> E_aux (E_app f es) (l,annot))
(fun vs -> match vs with | [] -> V_lit (L_aux L_unit l) | [v] -> v | vs -> V_tuple vs end)
l_env l_mem [] args) with
| (Value v,lm,le) ->
- (match (f,t_level) with
- | (id,(Env defs externs lets regs mems ctors)) ->
- (match find_function defs id with
- | Just(funcls) ->
- (match find_funcl funcls v with
- | Nothing ->
- let name = get_id id in
- (Error l (String.stringAppend "No matching pattern for function " name ),l_mem,l_env)
- | Just(env,exp) ->
- resolve_outcome (interp_main t_level env l_mem exp)
- (fun ret lm le -> (Value ret, lm,l_env))
- (fun a -> update_stack a
- (fun stack -> (Frame (Id_aux (Id "0") l)
- (E_aux (E_id (Id_aux (Id "0") l)) (l,annot)) l_env l_mem stack)))
+ let name = get_id f in
+ (match tag with
+ | Tag_empty ->
+ (match find_function defs f with
+ | Just(funcls) ->
+ (match find_funcl funcls v with
+ | Nothing ->
+ (Error l (String.stringAppend "No matching pattern for function " name ),l_mem,l_env)
+ | Just(env,exp) ->
+ resolve_outcome (interp_main t_level env l_mem exp)
+ (fun ret lm le -> (Value ret, lm,l_env))
+ (fun a -> update_stack a
+ (fun stack -> (Frame (id_of_string "0") (E_aux (E_id (Id_aux (Id "0") l)) (l,annot)) l_env l_mem stack)))
end)
- | Nothing ->
- (match in_ctors ctors id with
- | Just(_) -> (Value (V_ctor id typ v), lm, le)
- | Nothing ->
- (match find_memory mems id with
- | Just(typ) ->
- (Action (Read_mem id v Nothing)
- (Frame (Id_aux (Id "0") l) (E_aux (E_id (Id_aux (Id "0") l)) (l,annot)) le lm Top), lm, le)
- | Nothing ->
- (match find_extern externs id with
- | Just(str) ->
- (Action (Call_extern str v)
- (Frame (Id_aux (Id "0") l) (E_aux (E_id (Id_aux (Id "0") l)) (l,annot)) le lm Top), lm, le)
- | Nothing -> (Error l (String.stringAppend "Unknown function call " (get_id id)),lm,le) end)
- end) end) end) end)
- | out -> out end)
+ | Nothing -> (Error l (String.stringAppend "Internal error: function with empty tag unfound " name),lm,le) end)
+ | Tag_spec ->
+ (match find_function defs f with
+ | Just(funcls) ->
+ (match find_funcl funcls v with
+ | Nothing ->
+ (Error l (String.stringAppend "No matching pattern for function " name ),l_mem,l_env)
+ | Just(env,exp) ->
+ resolve_outcome (interp_main t_level env l_mem exp)
+ (fun ret lm le -> (Value ret, lm,l_env))
+ (fun a -> update_stack a
+ (fun stack -> (Frame (id_of_string "0") (E_aux (E_id (Id_aux (Id "0") l)) (l,annot)) l_env l_mem stack)))
+ end)
+ | Nothing -> (Error l (String.stringAppend "Specified function must be defined before executing " name),lm,le) end)
+ | Tag_ctor ->
+ (match in_ctors ctors f with
+ | Just(_) -> (Value (V_ctor f typ v), lm, le)
+ | Nothing -> (Error l (String.stringAppend "Internal error: function with ctor tag unfound " name),lm,le)
+ end)
+ | Tag_extern opt_name ->
+ let name_ext = match opt_name with | Just s -> s | Nothing -> name end in
+ if has_memory_effect (match effect with | Effect_aux(Effect_set es) _ -> es | _ -> [] end)
+ then
+ (Action (Read_mem (id_of_string name_ext) v Nothing)
+ (Frame (Id_aux (Id "0") l) (E_aux (E_id (Id_aux (Id "0") l)) (l,intern_annot annot)) le lm Top), lm, le)
+ else
+ (Action (Call_extern name_ext v)
+ (Frame (Id_aux (Id "0") l) (E_aux (E_id (Id_aux (Id "0") l)) (l,intern_annot annot)) le lm Top), lm, le)
+ | _ -> (Error l (String.stringAppend "Tag other than empty, spec, ctor, or extern on function call " name),lm,le) end)
+ | out -> out end)
| E_app_infix lft op r ->
let op = match op with
| Id_aux (Id x) il -> Id_aux (DeIid x) il
| _ -> op
end in
+ let name = get_id op in
resolve_outcome (interp_main t_level l_env l_mem lft)
(fun lv lm le ->
resolve_outcome (interp_main t_level l_env lm r)
(fun rv lm le ->
- (match t_level with
- | (Env defs externs lets regs mems ctors) ->
+ match tag with
+ | Tag_empty ->
(match find_function defs op with
- | Nothing ->
- (match find_extern externs op with
- | Just(str) ->
- (Action (Call_extern str (V_tuple [lv;rv]))
- (Frame (Id_aux (Id "0") l)
- (E_aux (E_id (Id_aux (Id "0") l)) (l,annot)) le lm Top),lm,le)
- | Nothing ->
- (Error l (String.stringAppend "No matching function " (get_id op)),lm,l_env) end)
- | Just (funcls) ->
+ | Nothing -> (Error l (String.stringAppend "Internal error, no function def for " name),lm,le)
+ | Just (funcls) ->
(match find_funcl funcls (V_tuple [lv;rv]) with
- | Nothing -> (Error l "No matching pattern for function",lm,l_env)
+ | Nothing -> (Error l (String.stringAppend "No matching pattern for function " name),lm,l_env)
| Just(env,exp) ->
resolve_outcome (interp_main t_level env emem exp)
- (fun ret lm le -> (Value ret,l_mem,l_env))
- (fun a -> update_stack a
- (fun stack -> (Frame (Id_aux (Id "0") l)
- (E_aux (E_id (Id_aux (Id "0") l)) (l,annot)) l_env l_mem stack)))
- end)
- end)
- end))
+ (fun ret lm le -> (Value ret,l_mem,l_env))
+ (fun a -> update_stack a
+ (fun stack -> (Frame (Id_aux (Id "0") l)
+ (E_aux (E_id (Id_aux (Id "0") l)) (l,annot)) l_env l_mem stack)))
+ end)end)
+ | Tag_spec ->
+ (match find_function defs op with
+ | Nothing -> (Error l (String.stringAppend "No function definition found for " name),lm,le)
+ | Just (funcls) ->
+ (match find_funcl funcls (V_tuple [lv;rv]) with
+ | Nothing -> (Error l (String.stringAppend "No matching pattern for function " name),lm,l_env)
+ | Just(env,exp) ->
+ resolve_outcome (interp_main t_level env emem exp)
+ (fun ret lm le -> (Value ret,l_mem,l_env))
+ (fun a -> update_stack a
+ (fun stack -> (Frame (Id_aux (Id "0") l)
+ (E_aux (E_id (Id_aux (Id "0") l)) (l,annot)) l_env l_mem stack)))
+ end)end)
+ | Tag_extern ext_name ->
+ let ext_name = match ext_name with Just s -> s | Nothing -> name end in
+ (Action (Call_extern ext_name (V_tuple [lv;rv]))
+ (Frame (Id_aux (Id "0") l)
+ (E_aux (E_id (Id_aux (Id "0") l)) (l,intern_annot annot)) le lm Top),lm,le) end)
(fun a -> update_stack a (add_to_top_frame (fun r ->E_aux (E_app_infix (to_exp lv) op r) (l,annot)))))
(fun a -> update_stack a (add_to_top_frame (fun lft -> (E_aux (E_app_infix lft op r) (l,annot)))))
| E_let (lbind : letbind tannot) exp ->
@@ -1020,8 +1057,7 @@ and interp_main t_level l_env l_mem (E_aux exp (l,annot)) =
and create_write_message_or_update t_level value l_env l_mem is_top_level ((LEXP_aux lexp (l,annot)):lexp tannot) =
let (Env defs externs lets regs mems ctors) = t_level in
let (typ,tag,ncs,ef) = match annot with
- | Nothing -> (T_var (Kid_aux (Var "fresh_v") Unknown),
- Tag_empty, [], (Effect_aux (Effect_set []) Unknown))
+ | Nothing -> (T_var (Kid_aux (Var "fresh_v") Unknown), Tag_empty, [], (Effect_aux (Effect_set []) Unknown))
| Just(t, tag, ncs, ef) -> (t,tag,ncs,ef) end in
match lexp with
| LEXP_id id ->
@@ -1048,8 +1084,7 @@ and create_write_message_or_update t_level value l_env l_mem is_top_level ((LEXP
let regf = Reg id typ in
let request = (Action (Write_reg regf Nothing value)
(Frame (Id_aux (Id "0") l)
- (E_aux (E_id (Id_aux (Id "0") l))
- (l,Just(typ,Tag_empty,ncs,ef))) l_env l_mem Top),l_mem,l_env) in
+ (E_aux (E_id (Id_aux (Id "0") l)) (l,intern_annot annot)) l_env l_mem Top),l_mem,l_env) in
if is_top_level then (request,Nothing) else (request,Just (fun e -> LEXP_aux (LEXP_id id) (l,annot)))
| _ -> ((Error l (String.stringAppend "Internal error: writing to id with tag other than extern or empty " (get_id id)),l_mem,l_env),Nothing)
end
@@ -1058,11 +1093,14 @@ and create_write_message_or_update t_level value l_env l_mem is_top_level ((LEXP
(fun vs -> match vs with | [] -> V_lit (L_aux L_unit Unknown) | [v] -> v | vs -> V_tuple vs end)
l_env l_mem [] exps) with
| (Value v,lm,le) ->
- let request = (Action (Write_mem id v Nothing value)
- (Frame (Id_aux (Id "0") l) (E_aux (E_id (Id_aux (Id "0") l)) (l,annot)) l_env lm Top),lm,l_env) in
- if is_top_level then (request,Nothing)
- else (request,Just (fun e ->
- (LEXP_aux (LEXP_memory id (match v with | V_tuple vs -> (List.map to_exp vs) | v -> [to_exp v]end)) (l,annot))))
+ (match tag with
+ | Tag_extern ->
+ let request = (Action (Write_mem id v Nothing value)
+ (Frame (Id_aux (Id "0") l) (E_aux (E_id (Id_aux (Id "0") l)) (l,intern_annot annot)) l_env lm Top),lm,l_env) in
+ if is_top_level then (request,Nothing)
+ else (request,Just (fun e ->
+ (LEXP_aux (LEXP_memory id (match v with | V_tuple vs -> (List.map to_exp vs) | v -> [to_exp v]end)) (l,annot))))
+ end)
| (Action a s,lm, le) -> ((Action a s,lm,le), Just (fun (E_aux (E_tuple es) _) -> (LEXP_aux (LEXP_memory id es) (l,annot))))
| e -> (e,Nothing) end
| LEXP_vector lexp exp ->