Defining a new intermediate representation

This commit is contained in:
Denis Merigoux 2021-06-22 16:01:57 +02:00
parent fffd0ffb63
commit 1313183353
No known key found for this signature in database
GPG Key ID: EE99DCFA365C3EE3
9 changed files with 155 additions and 5 deletions

View File

@ -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

View File

@ -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

View File

@ -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:

48
compiler/scalc/ast.ml Normal file
View File

@ -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
<denis.merigoux@inria.fr>
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 }

View File

@ -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
<denis.merigoux@inria.fr>
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);
}

8
compiler/scalc/dune Normal file
View File

@ -0,0 +1,8 @@
(library
(name scalc)
(public_name catala.scalc)
(libraries bindlib lcalc runtime))
(documentation
(package catala)
(mld_files scalc))

29
compiler/scalc/scalc.mld Normal file
View File

@ -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}

View File

@ -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

View File

@ -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] *)