Skip to content

Commit

Permalink
Merge pull request #995 from WardBrian/rewrite-typechecker
Browse files Browse the repository at this point in the history
Refactor typechecker
  • Loading branch information
WardBrian authored Nov 3, 2021
2 parents ca8b4dd + cc4cf50 commit 69b60a1
Show file tree
Hide file tree
Showing 47 changed files with 1,848 additions and 2,455 deletions.
36 changes: 34 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,44 @@ The entrypoint for the compiler is in `src/stanc/stanc.ml` which sequences the v
### Distinct stanc Phases

The phases of stanc are summarized in the following information flowchart and list.

<!---
digraph G {
rankdir=TB;
ranksep=.25;
bgcolor=white;
size=5;
node [shape="box"];
origin[style=invis];
stanc[label="stanc/stanc.ml"];
lexer[label="frontend/lexer.mll"];
parser[label="frontend/parser.mly"];
type[label="frontend/Typechecker.ml"];
lower[label="frontend/Ast_to_Mir.ml"];
transform[label="*_backend/Transform_Mir.ml"];
optimize[label="analysis_and_optimization/Optimize.ml"];
codegen[label="*_backend/*_code_gen.ml"];
output[shape="oval" label=".hpp file"]
origin -> stanc[label=" .stan file path"];
stanc -> lexer[label=" string"];
lexer -> parser[label=" tokens"];
parser -> type[label=" untyped AST"];
type -> lower[label=" typed AST"];
lower -> transform[label=" MIR"];
transform -> optimize[label=" transformed MIR"];
transform -> codegen[label=" "];
optimize -> codegen[headlabel="optimized MIR "];
codegen -> output[label=" C++ code"];
}
--->
![stanc3 information flow](docs/img/information-flow.png)

1. [Lex](src/frontend/lexer.mll) the Stan language into tokens.
1. [Parse](src/frontend/parser.mly) Stan language into AST that represents the syntax quite closely and aides in development of pretty-printers and linters. `stanc --debug-ast` to print this out.
1. Typecheck & add type information [Semantic_check.ml](src/frontend/Semantic_check.ml). `stanc --debug-decorated-ast`
1. Typecheck & add type information [Typechecker.ml](src/frontend/Typechecker.ml). `stanc --debug-decorated-ast`
1. [Lower](src/frontend/Ast_to_Mir.ml) into [Middle Intermediate Representation](src/middle/Mir.ml) (AST -> MIR) `stanc --debug-mir` (or `--debug-mir-pretty`)
1. Analyze & optimize (MIR -> MIR)
1. Backend MIR transform (MIR -> MIR) [Transform_Mir.ml](src/stan_math_backend/Transform_Mir.ml) `stanc --debug-transformed-mir`
Expand Down
Binary file modified docs/img/information-flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion src/common/Common.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
module Foldable = Foldable

(* Other signatures *)
module Validation = Validation
module Pretty = Pretty

(* 'Two-level type' signatures and functors *)
Expand Down
1 change: 0 additions & 1 deletion src/common/Common.mli
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ module Foldable : module type of Foldable

(** Other signatures *)

module Validation : module type of Validation
module Pretty : module type of Pretty

(** 'Two-level type' signatures and functors *)
Expand Down
167 changes: 0 additions & 167 deletions src/common/Validation.ml

This file was deleted.

38 changes: 0 additions & 38 deletions src/common/Validation.mli

This file was deleted.

2 changes: 1 addition & 1 deletion src/frontend/Ast_to_Mir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -878,5 +878,5 @@ let trans_prog filename (p : Ast.typed_program) : Program.Typed.t =
; generate_quantities
; transform_inits
; output_vars
; prog_name= normalize_prog_name !Semantic_check.model_name
; prog_name= normalize_prog_name !Typechecker.model_name
; prog_path= filename }
2 changes: 1 addition & 1 deletion src/frontend/Deprecation_analysis.mli
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
open Core_kernel
open Ast

type t = Middle.Warnings.t
type t = Warnings.t

val find_udf_log_suffix :
typed_statement -> (string * Middle.UnsizedType.t) option
Expand Down
48 changes: 48 additions & 0 deletions src/frontend/Environment.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
open Core_kernel
open Middle

type originblock =
| MathLibrary
| Functions
| Data
| TData
| Param
| TParam
| Model
| GQuant
[@@deriving sexp]

type varinfo = {origin: originblock; global: bool; readonly: bool}
[@@deriving sexp]

type info =
{ type_: UnsizedType.t
; kind:
[ `Variable of varinfo
| `UserDeclared of Location_span.t
| `StanMath
| `UserDefined ] }
[@@deriving sexp]

type t = info list String.Map.t

let create () =
let functions =
Hashtbl.to_alist Stan_math_signatures.stan_math_signatures
|> List.map ~f:(fun (key, values) ->
( key
, List.map values ~f:(fun (rt, args, mem) ->
let type_ =
UnsizedType.UFun
(args, rt, Fun_kind.suffix_from_name key, mem)
in
{type_; kind= `StanMath} ) ) )
|> String.Map.of_alist_exn
in
functions

let add env key type_ kind = Map.add_multi env ~key ~data:{type_; kind}
let set_raw env key data = Map.set env ~key ~data
let find env key = Map.find_multi env key
let mem env key = Map.mem env key
let iter env f = Map.iter env ~f
53 changes: 53 additions & 0 deletions src/frontend/Environment.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
(** Type environments used during typechecking. Maps from strings to function or variable information *)

open Middle

(** Origin blocks, to keep track of where variables are declared *)
type originblock =
| MathLibrary
| Functions
| Data
| TData
| Param
| TParam
| Model
| GQuant
[@@deriving sexp]

(** Information available for each variable *)
type varinfo = {origin: originblock; global: bool; readonly: bool}
[@@deriving sexp]

type info =
{ type_: UnsizedType.t
; kind:
[ `Variable of varinfo
| `UserDeclared of Location_span.t
| `StanMath
| `UserDefined ] }
[@@deriving sexp]

type t

val create : unit -> t
(** Return a new type environment which contains the Stan math library functions
*)

val find : t -> string -> info list

val add :
t
-> string
-> Middle.UnsizedType.t
-> [ `UserDeclared of Location_span.t
| `StanMath
| `UserDefined
| `Variable of varinfo ]
-> t
(** Add a new item to the type environment. Does not overwrite existing, but shadows *)

val set_raw : t -> string -> info list -> t
(** Overwrite the existing items bound to a name *)

val mem : t -> string -> bool
val iter : t -> (info list -> unit) -> unit
Loading

0 comments on commit 69b60a1

Please sign in to comment.