Skip to content

Commit 199109f

Browse files
committed
Support basic function parameters
1 parent 0a7ebaf commit 199109f

File tree

2 files changed

+43
-15
lines changed

2 files changed

+43
-15
lines changed

lib/ClangToAst.ml

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ let empty_env = {vars = []}
1414

1515
let add_var env var = {vars = var :: env.vars }
1616

17+
let find_var env var = EBound (KList.index (fun x -> x = var) env.vars)
18+
1719
let extract_width = function | TInt w -> w | _ -> failwith "not an integer type"
1820

1921
let get_id_name (dname: declaration_name) = match dname with
@@ -24,21 +26,24 @@ let translate_typ_name = function
2426
| "uint32_t" -> Helpers.uint32
2527
| _ -> failwith "unsupported name"
2628

27-
let translate_typ (typ: qual_type) = match typ.desc with
28-
| Pointer _ -> failwith "pointer type"
29+
let rec translate_typ (typ: qual_type) = match typ.desc with
30+
| Pointer typ -> TBuf (translate_typ typ, false)
2931
| Typedef {name; _} -> get_id_name name |> translate_typ_name
32+
| BuiltinType Void -> TUnit
33+
| BuiltinType _ -> failwith "builtin type"
3034
| _ -> failwith "not pointer type"
3135

32-
let translate_expr (t: typ) (e: expr) = match e.desc with
36+
let translate_expr (env: env) (t: typ) (e: expr) = match e.desc with
3337
| IntegerLiteral (Int n) -> EConstant (extract_width t, string_of_int n)
38+
| DeclRef {name; _} -> get_id_name name |> find_var env
3439
| _ -> failwith "translate_expr"
3540

3641
let translate_vardecl (env: env) (vdecl: var_decl_desc) : env * binder * Ast.expr =
3742
let name = vdecl.var_name in
3843
let typ = translate_typ vdecl.var_type in
3944
match vdecl.var_init with
4045
| None -> failwith "Variable declarations without definitions are not supported"
41-
| Some e -> add_var env name, Helpers.fresh_binder name typ, Ast.with_type typ (translate_expr typ e)
46+
| Some e -> add_var env name, Helpers.fresh_binder name typ, Ast.with_type typ (translate_expr env typ e)
4247

4348
let rec translate_stmt (env: env) (s: stmt_desc) : expr' = match s with
4449
| Compound l -> begin match l with
@@ -56,27 +61,50 @@ let rec translate_stmt (env: env) (s: stmt_desc) : expr' = match s with
5661
end
5762
| _ -> EUnit
5863

64+
let translate_param (p: parameter) : binder * string =
65+
let p = p.desc in
66+
let typ = translate_typ p.qual_type in
67+
(* Not handling default expressions for function parameters *)
68+
assert (p.default = None);
69+
Helpers.fresh_binder p.name typ, p.name
70+
5971
let translate_fundecl (fdecl: function_decl) =
6072
let name = get_id_name fdecl.name in
61-
let body = match fdecl.body with | None -> EUnit | Some s -> translate_stmt empty_env s.desc in
62-
let decl = Ast.(DFunction (None, [], 0, 0, TUnit, ([], name), [], with_type TUnit body)) in
73+
let ret_type = translate_typ fdecl.function_type.result in
74+
let args, vars = match fdecl.function_type.parameters with
75+
| None -> [], []
76+
| Some params ->
77+
(* Not handling variadic parameters *)
78+
assert (not (params.variadic));
79+
List.map translate_param params.non_variadic |> List.split
80+
in
81+
(* To adopt a DeBruijn representation, the list must be reversed to
82+
have the last binder as the first element of the environment *)
83+
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
6386
KPrint.bprintf "Resulting decl %a\n" PrintAst.pdecl decl;
64-
()
87+
decl
6588

6689

6790
let translate_decl (decl: decl) = match decl.desc with
6891
| Function fdecl ->
6992
let name = get_id_name fdecl.name in
7093
Printf.printf "Translating function %s\n" name;
71-
if name = "test" || name = "quarter_round" then
72-
translate_fundecl fdecl
73-
else ()
74-
| _ -> ()
94+
if name = "test" then (* || name = "quarter_round" then *)
95+
Some (translate_fundecl fdecl)
96+
else None
97+
| _ -> None
7598

7699
let read_file () =
77100
let ast = parse_file "test.c" in
78101
(* Format.printf "@[%a@]@." (Refl.pp [%refl: Clang.Ast.translation_unit] []) ast; *)
79102
Printf.printf "Trying file %s\n" ast.desc.filename;
80-
let _decls = List.map translate_decl ast.desc.items in
81-
()
103+
let decls = List.filter_map translate_decl ast.desc.items in
104+
let files = ["test", decls] in
105+
let files = AstToMiniRust.translate_files files in
106+
let files = OptimizeMiniRust.cleanup_minirust files in
107+
let files = OptimizeMiniRust.infer_mut_borrows files in
108+
let files = OptimizeMiniRust.simplify_minirust files in
109+
OutputRust.write_all files
82110

test.c

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

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

77

0 commit comments

Comments
 (0)