Skip to content

Commit

Permalink
Syntax anf chinesebear进度汇入dev (#67)
Browse files Browse the repository at this point in the history
* 创建一个Playground
开始写trans_func_impl(把AST函数定义翻译成ANF函数定义)
目前func_label和func_body都是dummy value

* [mmzk] (feat) 使用gen_label生成func_label

* Add (preprocess(pps ppx_deriving.show))

* Add [@@deriving show] for all AST types

* deriving shows

* Playground works

* [mmzk] (refactor)把ANF逻辑放到IR文件夹下

* parser bug不知怎么好像又好了(

* 把Playground中的逻辑拆进Conversion.ml

* [mmzk] (fix) 修复编译问题

* anf expr trans

* expr variable trans

* 处理trans_stmt的StmtSeq分支

* 实现StmtSeq的IR转换

* trans_expr_assign draft

* 将context改成var_table

* 将continuation换成program -> program的函数

* Can translate single return : /

* simplify ANF IR

* setup ANF conversion framework

* properly show source span

* setup test framework

* translate [let] & improve test

* translate [if]

* nicer output of ANF IR

* translate variables and binary op

* add some comments

* translate [while]

* add tag to ADT label

* basic pattern matching compiler

* hand-written pretty printer for ANF

* add index information to struct fields

* translate struct patterns

* optimize: stop matching when first row is irrefutable

* translate literal pattern

* update to nix flake

* add comment to match compiler & bugfix

* 为loop增加break label
实现continue

* fix comment typo

* 更新test文件

* trans_stmt中记录当前level的所有label

* 实现break

* 增加continue的test case

* 在注释中修改loop的形状
此前的loop形状有问题

* 修正break和continue的tests

* unop

* Implement traverse_expr

* tuple

* tuple

* tuple again

---------

Co-authored-by: chinesebear <[email protected]>
Co-authored-by: Guest0x0 <[email protected]>
  • Loading branch information
3 people authored Sep 6, 2024
1 parent ca53a73 commit ba22304
Show file tree
Hide file tree
Showing 25 changed files with 1,841 additions and 229 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ _build
.DS_Store
*.bak
*.o
flake.lock
117 changes: 101 additions & 16 deletions IR/ANF.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@

type variable = int [@@deriving show]
type label = int [@@deriving show]
type variable = int
let pp_variable fmt var = Format.fprintf fmt "$%d" var

type label = int
let pp_label fmt lbl = Format.fprintf fmt "#%d" lbl


type func_name = Syntax.ParseTree.func_name [@@deriving show]
type adt_label = Syntax.ParseTree.adt_label [@@deriving show]
Expand Down Expand Up @@ -36,7 +40,6 @@ type lvalue =
{ lv_var : variable
; lv_path : path
; lv_src : span }
[@@deriving show]

and path = path_node list
[@@deriving show]
Expand All @@ -47,22 +50,23 @@ and path = path_node list
i.e. a tuple, a struct, an ADT or a method dictionary}
{li [Deref] selects the address a pointer points to}
{li [AsTag l] selects the data associated with label [l] in an ADT}
{li [Tag] selects the tag/label of an ADT value}
{li [Method m] selects the implementation of method [m] from an interface implementation}
} *)
and path_node =
| Field of int
| Deref
| AsTag of adt_label
| AsTag of int
| Tag
| Method of string
[@@deriving show]

(** A [value] in the ANF IR is something immediately available without needing
any computation. *)
type value =
| LVal of lvalue
| Int of int
| Float of float
[@@deriving show]
| String of string

type expr =
| Val of value
Expand All @@ -72,15 +76,12 @@ type expr =
| UnOp of unary_op * value
| BinOp of binary_op * value * value
| MkData of data_kind * value list
| TagOf of value
| Fun of func_name
[@@deriving show]

type statement =
| Decl of variable * expr
| Assign of lvalue * value
| EndScope of variable list
[@@deriving show]

(** {ul
{li [Return(span, expr)] returns the result of [expr] as the result of the whole program.
Expand All @@ -95,13 +96,13 @@ type statement =
and immediately enter the block}
} *)
type program =
| Return of span * expr
| Jump of span * label * value list
| Stmt of span * statement * program
| Branch of branching
| Block of block_definition * program
| Loop of block_definition
[@@deriving show]
| Empty
| Abort

(** [branching] is a simple switch on ADT label (integer tag).
Each ADT label has an associated branch in [br_branches],
Expand All @@ -115,28 +116,112 @@ type program =
and branching =
{ br_src : span
; br_matched : value
; br_branches : (adt_label * program) list
; br_branches : (int * program) list
; br_default : program option }
[@@deriving show]

and block_definition =
{ blk_label : label
; blk_params : variable list
; blk_body : program }
[@@deriving show]

(** [func_label] represents the point {e after} the function returns *)
(** [func_label] represents the point {e after} the function returns.
Returning from the function is represented by jumping to [func_label]. *)
type function_definition =
{ func_src : span
; func_name : string
; func_params : variable list
; func_label : label
; func_body : program }
[@@deriving show]

let (gen_var, gen_label, reset_generator) =
let var_seed = ref 0 in
let label_seed = ref 0 in
( (fun () -> incr var_seed; !var_seed)
, (fun () -> incr label_seed; !label_seed)
, (fun () -> var_seed := 0; label_seed := 0) )

(* Concatenate two programs *)
let rec concat_program(p1: program)(p2: program): program =
match p1 with
| Stmt(span, stmt, body) -> Stmt(span, stmt, concat_program body p2)
| Block(def, body) -> Block(def, concat_program body p2)
| _ -> p1 (* In the other cases, the second program is unreachable *)



(* hand-writter pretty printer for easier debugging*)
let pp_lvalue fmt lv =
Format.fprintf fmt "$%d" lv.lv_var;
List.iter
(fun node ->
match node with
| Field k -> Format.fprintf fmt ".%d" k
| Deref -> Format.fprintf fmt ".*"
| AsTag t -> Format.fprintf fmt ".as(%d)" t
| Tag -> Format.fprintf fmt ".tag"
| Method m -> Format.fprintf fmt ".%s" m)
(List.rev lv.lv_path)

let pp_value fmt value =
match value with
| LVal lv -> pp_lvalue fmt lv
| Int i -> Format.fprintf fmt "%d" i
| Float f -> Format.fprintf fmt "%f" f
| String s -> Format.fprintf fmt "\"%s\"" s

let pp_values fmt values =
Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt ", ") pp_value fmt values

let pp_expr fmt expr =
let open Format in
match expr with
| Val v -> pp_value fmt v
| Copy lv -> fprintf fmt "copy(%a)" pp_lvalue lv
| Borrow (Imm, lv) -> fprintf fmt "&%a" pp_lvalue lv
| Borrow (Mut, lv) -> fprintf fmt "&mut %a" pp_lvalue lv
| App(func, args) -> fprintf fmt "%a(%a)" pp_value func pp_values args
| UnOp(op, operand) ->
fprintf fmt "%a(%a)" Syntax.ParseTree.pp_unary_op op pp_value operand
| BinOp(op, lhs, rhs) ->
fprintf fmt "%a(%a, %a)" Syntax.ParseTree.pp_binary_op op pp_value lhs pp_value rhs
| MkData(dk, values) -> fprintf fmt "mk(%a)(%a)" pp_data_kind dk pp_values values
| Fun fname -> fprintf fmt "%s" fname

let pp_vars fmt vars =
Format.pp_print_list ~pp_sep:(fun fmt () -> Format.fprintf fmt ", ")
(fun fmt var -> Format.fprintf fmt "$%d" var) fmt vars

let pp_statement fmt stmt =
match stmt with
| Decl(name, rhs) -> Format.fprintf fmt "$%d = %a" name pp_expr rhs
| Assign(lv, value) -> Format.fprintf fmt "%a := %a" pp_lvalue lv pp_value value
| EndScope vars -> Format.fprintf fmt "endScope(%a)" pp_vars vars


let rec pp_program fmt prog =
let open Format in
match prog with
| Jump(span, label, args) ->
fprintf fmt "jump #%d (%a) -- %a" label pp_values args pp_span span
| Stmt(span, stmt, rest) ->
fprintf fmt "%a -- %a@ %a" pp_statement stmt pp_span span pp_program rest
| Branch { br_src; br_matched; br_branches; br_default } ->
fprintf fmt "match %a -- %a:" pp_value br_matched pp_span br_src;
List.iter
(fun (tag, action) -> fprintf fmt "@ @[<v2>%d =>@ %a@]" tag pp_program action)
br_branches;
Option.iter
(fun action -> fprintf fmt "@ @[<v2>_ =>@ %a@]" pp_program action)
br_default
| Block ({ blk_label; blk_params; blk_body }, rest) ->
fprintf fmt "@[<v2>block #%d(%a) =@ %a@]@ in@ %a"
blk_label pp_vars blk_params pp_program blk_body pp_program rest
| Loop { blk_label; blk_params; blk_body } ->
fprintf fmt "@[<v2>loop #%d(%a):@ %a@]" blk_label pp_vars blk_params pp_program blk_body
| Empty -> fprintf fmt "empty"
| Abort -> fprintf fmt "abort!"

let pp_function_definition fmt { func_src; func_name; func_params; func_label; func_body } =
let open Format in
fprintf fmt "@[<v2>fun %s(%a) -> #%d -- %a =@ %a@]@ "
func_name pp_vars func_params func_label pp_span func_src pp_program func_body
Loading

0 comments on commit ba22304

Please sign in to comment.