Skip to content

Commit af895aa

Browse files
committed
Filter definitions of current file, support do statement, preliminary support for assign ops
1 parent a5653b6 commit af895aa

File tree

2 files changed

+148
-10
lines changed

2 files changed

+148
-10
lines changed

lib/ClangToAst.ml

Lines changed: 130 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ let empty_env = {vars = []}
1414

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

17-
(* TODO: Handle fully qualified names/namespaces/different files *)
17+
(* TODO: Handle fully qualified names/namespaces/different files. *)
1818
let find_var env var =
1919
try EBound (KList.index (fun x -> x = var) env.vars) with
2020
(* This variable is not a local var *)
21+
(* TODO: More robust check, likely need env for top-level decls *)
2122
| Not_found -> EQualified ([], var)
2223

2324
let get_id_name (dname: declaration_name) = match dname with
@@ -30,16 +31,61 @@ let get_id_name (dname: declaration_name) = match dname with
3031
| LiteralOperatorName _ -> failwith "literal operator name"
3132
| UsingDirectiveName -> failwith "using directive"
3233

34+
let is_assign_op (kind: Clang__Clang__ast.binary_operator_kind) = match kind with
35+
| Assign | AddAssign | MulAssign | DivAssign | RemAssign
36+
| SubAssign | ShlAssign | ShrAssign | AndAssign
37+
| XorAssign | OrAssign -> true
38+
| _ -> false
39+
40+
let assign_to_bop (kind: Clang__Clang__ast.binary_operator_kind) : Ast.expr =
41+
let op = match kind with
42+
(* TODO: Might need to disambiguate for pointer arithmetic *)
43+
| AddAssign -> K.Add
44+
| MulAssign -> Mult
45+
| DivAssign -> Div
46+
| RemAssign -> Mod
47+
| SubAssign -> Sub
48+
| ShlAssign -> BShiftL
49+
| ShrAssign -> BShiftR
50+
| AndAssign -> BAnd
51+
(* TODO: Disambiguate *)
52+
| XorAssign -> BXor
53+
| OrAssign -> BOr
54+
| _ -> failwith "not an assign op"
55+
in
56+
(* TODO: Infer width and type from types of operands *)
57+
Ast.with_type Helpers.uint32 (EOp (op, UInt32))
58+
3359
let translate_binop (kind: Clang__Clang__ast.binary_operator_kind) : K.op = match kind with
60+
| PtrMemD | PtrMemI -> failwith "translate_binop: ptr mem"
61+
| Mul | Div | Rem -> failwith " translate_binop: arith expr"
62+
63+
(* TODO: Might need to disambiguate for pointer arithmetic *)
3464
| Add -> Add
65+
| Sub -> Sub
66+
67+
| Shl -> BShiftL
68+
| Shr -> BShiftR
69+
70+
| Cmp | LT | GT | LE | GE | EQ | NE -> failwith "translate_binop: boolcomp"
71+
72+
| And -> BAnd
3573
(* TODO: How to distinguish between Xor and BXor? Likely need typing info from operands *)
3674
| Xor -> BXor
3775
| Or -> BOr
38-
| Shl -> BShiftL
39-
| Shr -> BShiftR
40-
| _ -> failwith "translate_binop"
76+
77+
| LAnd | LOr -> failwith "translate_binop: logical ops"
78+
79+
| Assign | AddAssign | MulAssign | DivAssign | RemAssign
80+
| SubAssign | ShlAssign | ShrAssign | AndAssign
81+
| XorAssign | OrAssign ->
82+
failwith "Assign operators should have been previously rewritten"
83+
84+
| Comma -> failwith "translate_binop: comma"
85+
| InvalidBinaryOperator -> failwith "translate_binop: invalid binop"
4186

4287
let translate_typ_name = function
88+
| "size_t" -> Helpers.usize
4389
| "uint32_t" -> Helpers.uint32
4490
| s ->
4591
Printf.printf "type name %s is unsupported\n" s;
@@ -48,6 +94,17 @@ let translate_typ_name = function
4894
let translate_builtin_typ (t: Clang__Clang__ast.builtin_type) = match t with
4995
| Void -> TUnit
5096
| UInt -> TInt UInt32 (* TODO: How to retrieve exact width? *)
97+
| UShort -> failwith "translate_builtin_typ: ushort"
98+
| ULong -> TInt UInt32
99+
| ULongLong -> failwith "translate_builtin_typ: ulonglong"
100+
| UInt128 -> failwith "translate_builtin_typ: uint128"
101+
102+
| Short
103+
| Int
104+
| Long
105+
| LongLong
106+
| Int128 -> failwith "translate_builtin_typ: signed int"
107+
51108
| Pointer -> failwith "translate_builtin_typ: pointer"
52109
| _ -> failwith "translate_builtin_typ: unsupported builtin type"
53110

@@ -107,6 +164,17 @@ let rec translate_expr' (env: env) (t: typ) (e: expr) : expr' = match e.desc wit
107164
| _ -> EAssign (lhs, rhs)
108165
end
109166

167+
| BinaryOperator {lhs; kind; rhs} when is_assign_op kind ->
168+
let lhs_ty = typ_of_expr lhs in
169+
let lhs = translate_expr env (typ_of_expr lhs) lhs in
170+
let rhs = translate_expr env (typ_of_expr rhs) rhs in
171+
let rhs = Ast.with_type TUnit (EAssign (lhs, Ast.with_type lhs_ty (EApp (assign_to_bop kind, [lhs; rhs])))) in
172+
begin match lhs.node with
173+
(* Special-case rewriting for buffer assignments *)
174+
| EBufRead (base, index) -> EBufWrite (base, index, rhs)
175+
| _ -> EAssign (lhs, rhs)
176+
end
177+
110178
| BinaryOperator {lhs; kind; rhs} ->
111179
let lhs_ty = typ_of_expr lhs in
112180
let lhs = translate_expr env lhs_ty lhs in
@@ -128,7 +196,11 @@ let rec translate_expr' (env: env) (t: typ) (e: expr) : expr' = match e.desc wit
128196
let args = List.map (fun x -> translate_expr env (typ_of_expr x) x) args in
129197
EApp (callee, args)
130198

131-
| Cast _ -> failwith "translate_expr: cast"
199+
| Cast {qual_type; operand; _} ->
200+
(* Format.printf "Cast %a@." Clang.Expr.pp e; *)
201+
let typ = translate_typ qual_type in
202+
let e = translate_expr env (typ_of_expr operand) operand in
203+
ECast (e, typ)
132204

133205
| ArraySubscript {base; index} ->
134206
let base = translate_expr env (TBuf (t, false)) base in
@@ -137,6 +209,8 @@ let rec translate_expr' (env: env) (t: typ) (e: expr) : expr' = match e.desc wit
137209
EBufRead (base, index)
138210

139211
| ConditionalOperator _ -> failwith "translate_expr: conditional operator"
212+
| Paren _ -> failwith "translate_expr: paren"
213+
| SizeOfPack _ -> failwith "translate_expr: size_of"
140214

141215
| _ -> failwith "translate_expr: unsupported expression"
142216

@@ -151,6 +225,8 @@ let translate_vardecl (env: env) (vdecl: var_decl_desc) : env * binder * Ast.exp
151225
| Some e -> add_var env name, Helpers.fresh_binder name typ, translate_expr env typ e
152226

153227
let rec translate_stmt' (env: env) (t: typ) (s: stmt_desc) : expr' = match s with
228+
| Null -> failwith "translate_stmt: null"
229+
154230
| Compound l -> begin match l with
155231
| [] -> EUnit
156232
| hd :: tl -> match hd.desc with
@@ -164,9 +240,42 @@ let rec translate_stmt' (env: env) (t: typ) (s: stmt_desc) : expr' = match s wit
164240
translate_stmt env TUnit stmt,
165241
translate_stmt (add_var env "_") t (Compound tl))
166242
end
243+
244+
| For _ -> failwith "translate_stmt: for"
245+
| ForRange _ -> failwith "translate_stmt: for range"
246+
| If _ -> failwith "translate_stmt: if"
247+
248+
| Switch _ -> failwith "translate_stmt: switch"
249+
| Case _ -> failwith "translate_stmt: case"
250+
| Default _ -> failwith "translate_stmt: default"
251+
252+
| While _ -> failwith "translate_stmt: while"
253+
| Do { body; cond } ->
254+
(* The do statements first executes the body before behaving as a while loop.
255+
We thus translate it as a sequence of the body and the corresponding while loop *)
256+
let body = translate_stmt env t body.desc in
257+
let cond = translate_expr env TBool cond in
258+
ELet (
259+
Helpers.sequence_binding (),
260+
body,
261+
Ast.with_type TUnit (EWhile (cond, body))
262+
)
263+
264+
| Label _ -> failwith "translate_stmt: label"
265+
| Goto _ -> failwith "translate_stmt: goto"
266+
| IndirectGoto _ -> failwith "translate_stmt: indirect goto"
267+
268+
| Continue -> failwith "translate_stmt: continue"
269+
| Break -> failwith "translate_stmt: break"
270+
| Asm _ -> failwith "translate_stmt: asm"
271+
| Return _ -> failwith "translate_stmt: return"
272+
167273
| Decl _ -> failwith "translate_stmt: decl"
168274
| Expr e -> translate_expr' env t e
169-
| _ -> failwith "translate_stmt"
275+
276+
| Try _ -> failwith "translate_stmt: try"
277+
| AttributedStmt _ -> failwith "translate_stmt: AttributedStmt"
278+
| UnknownStmt _ -> failwith "translate_stmt: UnknownStmt"
170279

171280
and translate_stmt (env: env) (t: typ) (s: stmt_desc) : Ast.expr =
172281
Ast.with_type t (translate_stmt' env t s)
@@ -199,18 +308,29 @@ let translate_fundecl (fdecl: function_decl) =
199308
(* KPrint.bprintf "Resulting decl %a\n" PrintAst.pdecl decl; *)
200309
decl
201310

202-
311+
(* TODO: Builtins might not be needed with a cleaner support for multiple files *)
203312
let builtins = [
204313
(* Functions from inttypes.h *)
205-
"imaxabs"; "imaxdiv"; "strtoimax"; "strtoumax"; "wcstoimax"; "wcstoumax"
314+
"imaxabs"; "imaxdiv"; "strtoimax"; "strtoumax"; "wcstoimax"; "wcstoumax";
315+
(* From string.h *)
316+
"__sputc"; "_OSSwapInt16"; "_OSSwapInt32"; "_OSSwapInt64";
317+
(* Krml functions. TODO: Should be handled as multifile *)
318+
"krml_time";
206319
]
207320

321+
(* Returning an option is only a hack to make progress.
322+
TODO: Proper handling of decls *)
208323
let translate_decl (decl: decl) = match decl.desc with
209324
| Function fdecl ->
210325
let name = get_id_name fdecl.name in
211-
Printf.printf "Translating function %s\n" name;
212326
(* TODO: How to handle libc? *)
213-
if List.mem name builtins then None else Some (translate_fundecl fdecl)
327+
let loc = Clang.Ast.location_of_node decl |> Clang.Ast.concrete_of_source_location File in
328+
let file_loc = loc.filename in
329+
(* TODO: Support multiple files *)
330+
if file_loc = "test.c" then (
331+
Printf.printf "Translating function %s\n" name;
332+
Some (translate_fundecl fdecl)
333+
) else None
214334
| _ -> None
215335

216336
let read_file () =

test.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include <inttypes.h>
2+
#include <string.h>
3+
#include "include/krml/internal/target.h"
24

35
void test(uint32_t *st, uint32_t y, uint32_t z) {
46
uint32_t x = y + z;
@@ -66,3 +68,19 @@ static inline void rounds(uint32_t *st)
6668
double_round(st);
6769
double_round(st);
6870
}
71+
72+
static inline void chacha20_core(uint32_t *k, uint32_t *ctx, uint32_t ctr)
73+
{
74+
memcpy(k, ctx, 16U * sizeof (uint32_t));
75+
uint32_t ctr_u32 = ctr;
76+
k[12U] = k[12U] + ctr_u32;
77+
rounds(k);
78+
KRML_MAYBE_FOR16(i,
79+
0U,
80+
16U,
81+
1U,
82+
uint32_t x = k[i] + ctx[i];
83+
uint32_t *os = k;
84+
os[i] = x;);
85+
k[12U] = k[12U] + ctr_u32;
86+
}

0 commit comments

Comments
 (0)