@@ -16,12 +16,19 @@ let add_var env var = {vars = var :: env.vars }
1616
1717let find_var env var = EBound (KList. index (fun x -> x = var) env.vars)
1818
19- let extract_width = function | TInt w -> w | _ -> failwith " not an integer type"
20-
2119let get_id_name (dname : declaration_name ) = match dname with
2220 | IdentifierName s -> s
2321 | _ -> failwith " only supporting identifiers"
2422
23+ let translate_binop (kind : Clang__Clang__ast.binary_operator_kind ) : K.op = match kind with
24+ | Add -> Add
25+ (* TODO: How to distinguish between Xor and BXor? Likely need typing info from operands *)
26+ | Xor -> BXor
27+ | Or -> BOr
28+ | Shl -> BShiftL
29+ | Shr -> BShiftR
30+ | _ -> failwith " translate_binop"
31+
2532let translate_typ_name = function
2633 | "uint32_t" -> Helpers. uint32
2734 | _ -> failwith " unsupported name"
@@ -33,33 +40,67 @@ let rec translate_typ (typ: qual_type) = match typ.desc with
3340 | BuiltinType _ -> failwith " builtin type"
3441 | _ -> failwith " not pointer type"
3542
36- let translate_expr (env : env ) (t : typ ) (e : expr ) = match e.desc with
37- | IntegerLiteral (Int n ) -> EConstant (extract_width t, string_of_int n)
43+ (* Translate expression [e], with expected type [t] *)
44+ let rec translate_expr ' (env : env ) (t : typ ) (e : expr ) : expr' = match e.desc with
45+ | IntegerLiteral (Int n ) -> EConstant (Helpers. assert_tint t, string_of_int n)
46+ | BoolLiteral _ -> failwith " translate_expr: bool literal"
47+ | UnaryOperator _ -> failwith " translate_expr: unary operator"
48+
49+ | BinaryOperator {lhs; kind = Assign ; rhs} ->
50+ (* TODO: Fix types *)
51+ let _lhs = translate_expr env Helpers. uint32 lhs in
52+ let _rhs = translate_expr env Helpers. uint32 rhs in
53+
54+ failwith " translate_expr: assignment"
55+
56+ | BinaryOperator {lhs; kind; rhs} ->
57+ (* TODO: Should infer/retrieve type of operands *)
58+ let lhs = translate_expr env Helpers. uint32 lhs in
59+ let rhs = translate_expr env Helpers. uint32 rhs in
60+ let kind = translate_binop kind in
61+ let op : Ast.expr = with_type TAny (EOp (kind, UInt32 )) in
62+ (* TODO: Retrieve correct type for operator *)
63+ EApp (op, [lhs; rhs])
64+
3865 | DeclRef {name; _} -> get_id_name name |> find_var env
66+ | ArraySubscript {base; index} ->
67+ let base = translate_expr env (TBuf (t, false )) base in
68+ let index = translate_expr env (TInt SizeT ) index in
69+ (* Is this only called on rvalues? Otherwise, might need EBufWrite *)
70+ EBufRead (base, index)
71+
3972 | _ -> failwith " translate_expr"
4073
74+ and translate_expr (env : env ) (t : typ ) (e : expr ) : Ast.expr =
75+ Ast. with_type t (translate_expr' env t e)
76+
4177let translate_vardecl (env : env ) (vdecl : var_decl_desc ) : env * binder * Ast.expr =
4278 let name = vdecl.var_name in
4379 let typ = translate_typ vdecl.var_type in
4480 match vdecl.var_init with
4581 | None -> failwith " Variable declarations without definitions are not supported"
46- | Some e -> add_var env name, Helpers. fresh_binder name typ, Ast. with_type typ ( translate_expr env typ e)
82+ | Some e -> add_var env name, Helpers. fresh_binder name typ, translate_expr env typ e
4783
48- let rec translate_stmt (env : env ) (s : stmt_desc ) : expr' = match s with
84+ let rec translate_stmt ' (env : env ) ( t : typ ) (s : stmt_desc ) : expr' = match s with
4985 | Compound l -> begin match l with
5086 | [] -> EUnit
5187 | hd :: tl -> match hd.desc with
5288 | Decl [{desc = Var vdecl; _ }] ->
5389 let env', b, e = translate_vardecl env vdecl in
54- ELet (b, e, Ast. with_type TUnit ( translate_stmt env' (Compound tl) ))
90+ ELet (b, e, translate_stmt env' t (Compound tl))
5591 | Decl [_] -> failwith " This decl is not a var declaration"
5692 | Decl _ -> failwith " multiple decls"
5793 | stmt -> ELet (
5894 Helpers. sequence_binding () ,
59- Ast. with_type TUnit ( translate_stmt env stmt) ,
60- Ast. with_type TUnit ( translate_stmt (add_var env " _" ) (Compound tl) ))
95+ translate_stmt env TUnit stmt,
96+ translate_stmt (add_var env " _" ) t (Compound tl))
6197 end
62- | _ -> EUnit
98+ | Decl _ -> failwith " translate_stmt: decl"
99+ | Expr e -> translate_expr' env t e
100+ | _ -> failwith " translate_stmt"
101+
102+ and translate_stmt (env : env ) (t : typ ) (s : stmt_desc ) : Ast.expr =
103+ Ast. with_type t (translate_stmt' env t s)
63104
64105let translate_param (p : parameter ) : binder * string =
65106 let p = p.desc in
@@ -81,8 +122,11 @@ let translate_fundecl (fdecl: function_decl) =
81122 (* To adopt a DeBruijn representation, the list must be reversed to
82123 have the last binder as the first element of the environment *)
83124 let env = {vars = List. rev vars} in
84- let body = match fdecl.body with | None -> EUnit | Some s -> translate_stmt env s.desc in
85- let decl = Ast. (DFunction (None , [] , 0 , 0 , ret_type, ([] , name), args, with_type ret_type body)) in
125+ let body = match fdecl.body with
126+ | None -> Helpers. eunit
127+ | Some s -> translate_stmt env ret_type s.desc
128+ in
129+ let decl = Ast. (DFunction (None , [] , 0 , 0 , ret_type, ([] , name), args, body)) in
86130 KPrint. bprintf " Resulting decl %a\n " PrintAst. pdecl decl;
87131 decl
88132
@@ -91,7 +135,7 @@ let translate_decl (decl: decl) = match decl.desc with
91135 | Function fdecl ->
92136 let name = get_id_name fdecl.name in
93137 Printf. printf " Translating function %s\n " name;
94- if name = " test" then (* || name = "quarter_round" then *)
138+ if name = " test" || name = " quarter_round" then
95139 Some (translate_fundecl fdecl)
96140 else None
97141 | _ -> None
0 commit comments