Skip to content

Commit e063378

Browse files
committed
WIP: Support more expressions
1 parent 199109f commit e063378

File tree

2 files changed

+58
-14
lines changed

2 files changed

+58
-14
lines changed

lib/ClangToAst.ml

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,19 @@ let add_var env var = {vars = var :: env.vars }
1616

1717
let 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-
2119
let 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+
2532
let 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+
4177
let 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

64105
let 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

test.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include <inttypes.h>
22

33
void test(uint32_t *st, uint32_t y, uint32_t z) {
4-
uint32_t x = y;
4+
uint32_t x = y + z;
55
}
66

77

0 commit comments

Comments
 (0)