Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor typechecker #995

Merged
merged 23 commits into from
Nov 3, 2021
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 34 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,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) ->
WardBrian marked this conversation as resolved.
Show resolved Hide resolved
( 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
51 changes: 51 additions & 0 deletions src/frontend/Environment.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
open Middle
WardBrian marked this conversation as resolved.
Show resolved Hide resolved

(** 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
*)
WardBrian marked this conversation as resolved.
Show resolved Hide resolved

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