From 3dc017c83c8cfb39c6beda9240c3ae3f9100de45 Mon Sep 17 00:00:00 2001 From: Wonho Shin Date: Tue, 16 Jul 2024 14:17:54 +0900 Subject: [PATCH] Add InvCallE --- spectec/src/al/ast.ml | 1 + spectec/src/al/eq.ml | 4 ++++ spectec/src/al/free.ml | 1 + spectec/src/al/print.ml | 13 ++++++++++++ spectec/src/al/walk.ml | 1 + .../src/backend-interpreter/interpreter.ml | 7 +++++++ spectec/src/backend-prose/render.ml | 20 +++++++++++++++++++ 7 files changed, 47 insertions(+) diff --git a/spectec/src/al/ast.ml b/spectec/src/al/ast.ml index 93fb299a69..e75e82bdb4 100644 --- a/spectec/src/al/ast.ml +++ b/spectec/src/al/ast.ml @@ -90,6 +90,7 @@ and expr' = | TupE of expr list (* `(` (expr `,`)* `)` *) | CaseE of atom * expr list (* atom `(` expr* `)` -- MixE/CaseE *) | CallE of id * expr list (* id `(` expr* `)` *) + | InvCallE of id * int list * expr list (* id`_`int*`^-1(` expr* `)` *) | IterE of expr * id list * iter (* expr (`{` id* `}`)* *) | OptE of expr option (* expr? *) | ListE of expr list (* `[` expr* `]` *) diff --git a/spectec/src/al/eq.ml b/spectec/src/al/eq.ml index 8c05a5ba3b..f36c209ebf 100644 --- a/spectec/src/al/eq.ml +++ b/spectec/src/al/eq.ml @@ -41,6 +41,10 @@ let rec eq_expr e1 e2 = | CallE (i1, el1), CallE (i2, el2) -> i1 = i2 && eq_exprs el1 el2 + | InvCallE (i1, nl1, el1), InvCallE (i2, nl2, el2) -> + i1 = i2 && + List.for_all2 (=) nl1 nl2 && + eq_exprs el1 el2 | IterE (e1, il1, it1), IterE (e2, il2, it2) -> eq_expr e1 e2 && il1 = il2 && diff --git a/spectec/src/al/free.ml b/spectec/src/al/free.ml index 78c95e22f6..11d43341e9 100644 --- a/spectec/src/al/free.ml +++ b/spectec/src/al/free.ml @@ -33,6 +33,7 @@ let rec free_expr expr = | LabelE (e1, e2) -> free_expr e1 @ free_expr e2 | FrameE (e_opt, e) -> free_opt free_expr e_opt @ free_expr e | CallE (_, el) + | InvCallE (_, _, el) | TupE el | ListE el | CaseE (_, el) -> free_list free_expr el diff --git a/spectec/src/al/print.ml b/spectec/src/al/print.ml index 77fe81258a..43eb0811d7 100644 --- a/spectec/src/al/print.ml +++ b/spectec/src/al/print.ml @@ -143,6 +143,16 @@ and string_of_expr expr = sprintf "(%s %s %s)" (string_of_expr e1) (string_of_binop op) (string_of_expr e2) | TupE el -> "(" ^ string_of_exprs ", " el ^ ")" | CallE (id, el) -> sprintf "$%s(%s)" id (string_of_exprs ", " el) + | InvCallE (id, nl, el) -> + let id' = + if List.length nl = 0 then id + else + nl + |> List.map string_of_int + |> List.fold_left (^) "" + |> sprintf "%s_%s" id + in + sprintf "$%s^-1(%s)" id' (string_of_exprs ", " el) | CatE (e1, e2) -> sprintf "%s ++ %s" (string_of_expr e1) (string_of_expr e2) | MemE (e1, e2) -> @@ -422,6 +432,9 @@ and structured_string_of_expr expr = ^ ")" | TupE el -> "TupE (" ^ structured_string_of_exprs el ^ ")" | CallE (id, el) -> "CallE (" ^ id ^ ", [ " ^ structured_string_of_exprs el ^ " ])" + | InvCallE (id, nl, el) -> + sprintf "InvCallE (%s, [%s], [%s])" + id (string_of_list string_of_int "" nl) (structured_string_of_exprs el) | CatE (e1, e2) -> "CatE (" ^ structured_string_of_expr e1 diff --git a/spectec/src/al/walk.ml b/spectec/src/al/walk.ml index b5d85a9977..81503b8165 100644 --- a/spectec/src/al/walk.ml +++ b/spectec/src/al/walk.ml @@ -41,6 +41,7 @@ let rec walk_expr f e = | UnE (op, e') -> UnE (op, new_ e') | BinE (op, e1, e2) -> BinE (op, new_ e1, new_ e2) | CallE (id, el) -> CallE (id, List.map new_ el) + | InvCallE (id, nl, el) -> InvCallE (id, nl, List.map new_ el) (* TODO: Implement walker for iter *) | ListE el -> ListE (List.map new_ el) | CatE (e1, e2) -> CatE (new_ e1, new_ e2) diff --git a/spectec/src/backend-interpreter/interpreter.ml b/spectec/src/backend-interpreter/interpreter.ml index c0f8413ca1..92d4f4867e 100644 --- a/spectec/src/backend-interpreter/interpreter.ml +++ b/spectec/src/backend-interpreter/interpreter.ml @@ -161,6 +161,13 @@ and eval_expr env expr = | Some v -> v | _ -> raise (Exception.MissingReturnValue fname) ) + | InvCallE (fname, _, el) -> + (* TODO: refactor numerics function name *) + let args = List.map (eval_expr env) el in + (match call_func ("inverse_of_"^fname) args with + | Some v -> v + | _ -> raise (Exception.MissingReturnValue fname) + ) (* Data Structure *) | ListE el -> List.map (eval_expr env) el |> listV_of_list | CatE (e1, e2) -> diff --git a/spectec/src/backend-prose/render.ml b/spectec/src/backend-prose/render.ml index 153128f6df..7436eeb456 100644 --- a/spectec/src/backend-prose/render.ml +++ b/spectec/src/backend-prose/render.ml @@ -105,6 +105,26 @@ and al_to_el_expr expr = elel in Some (El.Ast.CallE (elid, elel)) + | Al.Ast.InvCallE (id, nl, el) -> + let ($~) at it = it $ at in + let elid = + if List.length nl = 0 then + (id^"^-1") $ no_region + else + nl + |> List.map string_of_int + |> List.fold_left (^) "" + |> sprintf "%s_%s^-1" id + |> ($~) no_region + in + let* elel = al_to_el_exprs el in + let elel = List.map + (fun ele -> + let elarg = El.Ast.ExpA ele in + (ref elarg) $ no_region) + elel + in + Some (El.Ast.CallE (elid, elel)) | Al.Ast.CatE (e1, e2) -> let* ele1 = al_to_el_expr e1 in let* ele2 = al_to_el_expr e2 in