diff --git a/compiler/driver.ml b/compiler/driver.ml index 579341cd..db64b509 100644 --- a/compiler/driver.ml +++ b/compiler/driver.ml @@ -277,7 +277,7 @@ let driver (source_file : Pos.input_file) (debug : bool) (unstyled : bool) Cli.debug_print (Printf.sprintf "Writing to %s..." output_file); let oc = open_out output_file in let fmt = Format.formatter_of_out_channel oc in - Lcalc.To_python.format_program fmt prgm type_ordering; + Scalc.To_python.format_program fmt prgm type_ordering; close_out oc | _ -> assert false (* should not happen *)); 0 diff --git a/compiler/dune b/compiler/dune index 0207553d..d192291b 100644 --- a/compiler/dune +++ b/compiler/dune @@ -1,7 +1,7 @@ (library (name driver) (public_name catala.driver) - (libraries utils surface desugared literate dcalc lcalc runtime) + (libraries utils surface desugared literate dcalc lcalc scalc runtime) (modules driver)) (library diff --git a/compiler/lcalc/lcalc.mld b/compiler/lcalc/lcalc.mld index da659037..0ce51c56 100644 --- a/compiler/lcalc/lcalc.mld +++ b/compiler/lcalc/lcalc.mld @@ -2,7 +2,7 @@ This representation is the fifth in the compilation chain (see {{: index.html#architecture} Architecture}). Its main difference -with the previous {{: Lcalc.html} default calculus} is the absence of the +with the previous {{: Dcalc.html} default calculus} is the absence of the default term, which has been eliminated through diverse compilation schemes. The module describing the abstract syntax tree is: diff --git a/compiler/scalc/ast.ml b/compiler/scalc/ast.ml new file mode 100644 index 00000000..aaafb96b --- /dev/null +++ b/compiler/scalc/ast.ml @@ -0,0 +1,48 @@ +(* This file is part of the Catala compiler, a specification language for tax and social benefits + computation rules. Copyright (C) 2021 Inria, contributor: Denis Merigoux + + + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + in compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under the License + is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the License for the specific language governing permissions and limitations under + the License. *) + +open Utils +module D = Dcalc.Ast +module L = Lcalc.Ast + +module FuncName = Uid.Make (Uid.MarkedString) () + +module LocalVarName = Uid.Make (Uid.MarkedString) () + +type expr = + | EVar of LocalVarName.t + | EStruct of expr Pos.marked list * D.StructName.t + | EStructFieldAccess of expr Pos.marked * D.StructFieldName.t * D.StructName.t + | EInj of expr Pos.marked * D.EnumConstructor.t * D.EnumName.t + | EArray of expr Pos.marked list + | ELit of L.lit + | EApp of expr Pos.marked * expr Pos.marked list + | EOp of Dcalc.Ast.operator + +type stmt = + | SInnerFuncDef of func + | SLocalDef of LocalVarName.t Pos.marked * expr Pos.marked + | STryExcept of block Pos.marked * L.except * block Pos.marked + | SRaise of L.except + | SIfThenElse of expr Pos.marked * block Pos.marked * block Pos.marked + | SSwitch of expr Pos.marked * D.EnumName.t * block Pos.marked list + (** Each block corresponds to one case of the enum *) + | SReturn of expr Pos.marked + | SAssert of expr Pos.marked + +and block = stmt Pos.marked list + +and func = FuncName.t * (LocalVarName.t Pos.marked * D.typ Pos.marked) list * block Pos.marked + +type program = { decl_ctx : D.decl_ctx; scopes : func list } diff --git a/compiler/scalc/compile_from_lambda.ml b/compiler/scalc/compile_from_lambda.ml new file mode 100644 index 00000000..bf427bbb --- /dev/null +++ b/compiler/scalc/compile_from_lambda.ml @@ -0,0 +1,64 @@ +(* This file is part of the Catala compiler, a specification language for tax and social benefits + computation rules. Copyright (C) 2021 Inria, contributor: Denis Merigoux + + + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + in compliance with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under the License + is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the License for the specific language governing permissions and limitations under + the License. *) + +open Utils +module A = Ast +module L = Lcalc.Ast +module D = Dcalc.Ast + +type ctxt = { + func_dict : A.FuncName.t L.VarMap.t; + var_dict : A.LocalVarName.t L.VarMap.t; + inside_definition_of : A.LocalVarName.t list; +} + +let translate_block (ctxt : ctxt) (block_expr : L.expr Pos.marked) : A.block Pos.marked = + assert false + +let translate_scope (func_dict : A.FuncName.t L.VarMap.t) (scope_expr : L.expr Pos.marked) : + (A.LocalVarName.t Pos.marked * D.typ Pos.marked) list * A.block Pos.marked = + match Pos.unmark scope_expr with + | L.EAbs ((binder, binder_pos), typs) -> + let vars, body = Bindlib.unmbind binder in + let var_dict = + Array.fold_left + (fun var_dict var -> + L.VarMap.add var (A.LocalVarName.fresh (Bindlib.name_of var, binder_pos)) var_dict) + L.VarMap.empty vars + in + let param_list = + List.map2 + (fun var typ -> ((L.VarMap.find var var_dict, binder_pos), typ)) + (Array.to_list vars) typs + in + let new_body = translate_block { func_dict; var_dict } body in + (param_list, new_body) + | _ -> assert false +(* should not happen *) + +let translate_program (p : L.program) : A.program = + { + decl_ctx = p.L.decl_ctx; + scopes = + (let _, new_scopes = + List.fold_left + (fun (func_dict, new_scopes) (scope_name, scope_expr) -> + let new_scope_params, new_scope_body = translate_scope func_dict scope_expr in + let func_id = A.FuncName.fresh (Bindlib.name_of scope_name, Pos.no_pos) in + let func_dict = L.VarMap.add scope_name func_id func_dict in + (func_dict, (func_id, new_scope_params, new_scope_body) :: new_scopes)) + (L.VarMap.empty, []) p.L.scopes + in + List.rev new_scopes); + } diff --git a/compiler/scalc/dune b/compiler/scalc/dune new file mode 100644 index 00000000..75f842e1 --- /dev/null +++ b/compiler/scalc/dune @@ -0,0 +1,8 @@ +(library + (name scalc) + (public_name catala.scalc) + (libraries bindlib lcalc runtime)) + +(documentation + (package catala) + (mld_files scalc)) diff --git a/compiler/scalc/scalc.mld b/compiler/scalc/scalc.mld new file mode 100644 index 00000000..aaf72fd3 --- /dev/null +++ b/compiler/scalc/scalc.mld @@ -0,0 +1,29 @@ +{0 Statement calculus} + +This representation is the sixth in the compilation chain +(see {{: index.html#architecture} Architecture}). Its main difference +with the previous {{: Lcalc.html} default calculus} is the switch to a +statement-based language. This representation does not assume any scoping +rules in the language, every local variable has a unique id. + +The module describing the abstract syntax tree is: + +{!modules: Dcalc.Ast} + + +{1 Compilation from lambda calculus } + +Related modules: + +{!modules: Scalc.Compile_from_lambda} + +{!module: Scalc.Compile_from_lambda} Performs the classical translation +from an expression-based language to a statement-based language. Union types +are eliminated in favor of tagged unions. + +{1 Backends} + +Related modules: + +{!modules: Lcalc.To_python} + diff --git a/compiler/lcalc/to_python.ml b/compiler/scalc/to_python.ml similarity index 99% rename from compiler/lcalc/to_python.ml rename to compiler/scalc/to_python.ml index 5e64ab79..84b8757a 100644 --- a/compiler/lcalc/to_python.ml +++ b/compiler/scalc/to_python.ml @@ -11,7 +11,7 @@ is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. *) - +open Lcalc open Utils open Ast open Backends diff --git a/compiler/lcalc/to_python.mli b/compiler/scalc/to_python.mli similarity index 89% rename from compiler/lcalc/to_python.mli rename to compiler/scalc/to_python.mli index 59e6b925..b41a655d 100644 --- a/compiler/lcalc/to_python.mli +++ b/compiler/scalc/to_python.mli @@ -14,5 +14,6 @@ (** Formats a lambda calculus program into a valid Python program *) -val format_program : Format.formatter -> Ast.program -> Scopelang.Dependency.TVertex.t list -> unit +val format_program : + Format.formatter -> Lcalc.Ast.program -> Scopelang.Dependency.TVertex.t list -> unit (** Usage [format_program fmt p type_dependencies_ordering] *)