Skip to content
This repository
tag: v1559
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 193 lines (149 sloc) 7.385 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
(*
Copyright © 2011 MLstate

This file is part of OPA.

OPA is free software: you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License, version 3, as published by
the Free Software Foundation.

OPA is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
more details.

You should have received a copy of the GNU Affero General Public License
along with OPA. If not, see <http://www.gnu.org/licenses/>.
*)
(**
Explicit instantiation adds type abstractions and type applications
throughout the code to resolve the \@typeof directive

Only the necessary part of the code is instrumented in this way
(when you don't use (transitively) \@typeof, your code is not
rewritten)

Preconditions: the code is typed

Directives removed: \@typeof
*)


(* Hack: 2 global refs instead of function arguments; TODO: unhack *)

(** A map of top-level expressions published between client and server *)
type published_map = (Annot.label * Ident.t * [`one_lambda | `two_lambdas]) option IdentMap.t
val published_ref : published_map ref

(** The link between current identifiers and the ones before slicing *)
val renaming_map : QmlRenamingMap.t ref


(** Building representation of types in OPA *)

(**
The type of type representations
See stdlib/package/stdlib/core/opatype.opa
*)
val opatype_type : QmlAst.ty
val oparow_type : QmlAst.ty
val opacol_type : QmlAst.ty

(** [ty_to_opaty ~side annotmap gamma ty] represents a type [ty] in OPA,
as an OPA expression. The type of these OPA expressions is defined
in the OPA standard library.

@param side on which side we are, meaningless when memoization is off
@param annotmap the annotmap for, e.g., creating new OPA expressions
@param gamma the environment with type definitions
@param ty type to be represented in OPA.

@return Updated annotmap, and an OPA representation of [ty].
*)
val ty_to_opaty :
  side:[ `server | `client ] -> ?memoize:bool -> ?normalize:bool
  -> QmlAst.annotmap -> QmlTypes.gamma -> QmlAst.ty -> val_:(?side:[`client|`server] -> string -> Ident.t)
  -> QmlAst.annotmap * QmlAst.expr

(** [get_memoized_definitions gamma side] adds to gamma type schemes
of the new top level definitions visible at [side], generated
as a side effect by [ty_to_opaty]. *)
val get_memoized_definitions :
  QmlTypes.gamma -> [ `server | `client ]
  -> QmlTypes.gamma * QmlAst.code

(** A dummy representation of type that can be inserted when [process_code]
will not be called on a given expression, e.g., because
Explicit Instantiation is disabled by a compilation option. *)
val dummy_opaty :
  QmlAst.annotmap -> QmlAstCons.TypedExpr.gamma
  -> QmlAst.annotmap * QmlAst.expr

(**
A specialized version of [ty_to_opaty] for opadoc.
Scopes of variables are passed for normalization
keeping names, and the function is returned for
limiting object creation.
*)
val ty_to_opaty_for_opadoc :
  val_:(?side:[`client|`server] -> string -> Ident.t) ->
  gamma:QmlTypes.gamma ->
  annotmap:QmlAst.annotmap ->
  (
    QmlTypeVars.TypeVarPrint.scope ->
    QmlTypeVars.RowVarPrint.scope ->
    QmlTypeVars.ColVarPrint.scope ->
    QmlAst.ty -> QmlAst.expr
  )

(** Building representation of type schemes in OPA *)

(** The type of representation of type schemes. *)
val opatsc_type : QmlAst.ty

(** [tsc_to_opatsc ~side (annotmap, gamma) tsc] represents a type scheme [tsc]
in OPA, as OPA expression (of type [QmlAst.expr]). The OPA type of this
OPA expression is defined in file "specialisation.opa" as [OpaTsc.t].

@param side on which side we are
@param annotmap the annotmap for, e.g., creating new OPA expressions
@param gamma the environment with type definitions
@param tsc type scheme to be represented in OPA

@return Updated annotmap, and an OPA expression that represents
[tsc] in OPA.
*)
val tsc_to_opatsc :
  side:[ `server | `client ] -> val_:(?side:[`client|`server] -> string -> Ident.t) -> ?memoize:bool ->
  QmlAst.annotmap * QmlTypes.gamma -> QmlTypes.typescheme
  -> QmlAst.annotmap * QmlAst.expr


(** Transforming code to enable run-time explicit instantiation *)

(** [have_typeof ?set gamma annotmap qmlAst] extends [set] with with type
variables that are used to compute the results of sll [\@typeof] directives
within [qmlAst].

@param set initial set of variables, empty if not given
@param gamma the environment with type definitions
@param annotmap the annotmap for, e.g., looking up types of expressions
@param qmlAst the syntax tree to scan

@return Extended set, with all variables meaningful for [\@typeof].
*)
val have_typeof :
  QmlTypes.gamma -> QmlAst.annotmap -> QmlAst.code
  -> QmlTypeVars.FreeVars.t

(** [process_code have_typeof gamma annotmap _published qmlAst] inserts
directives for Explicit Instantiation into the code of [qmlAst].

@param have_typeof set of type variables to be considered meaningful for [\@typeof]
@param gamma the environment with type definitions
@param annotmap the annotmap for, e.g., looking up types of expressions
@param _published unused; currently [published_ref] is used instead
@param qmlAst the syntax tree to transform

@return Transformed syntax tree, with extra type arguments represented by directives. Also, updated annotmap and environment with changed types for top level definitions.
*)
val process_code :
  QmlTypeVars.FreeVars.t
  -> QmlTypes.gamma -> QmlAst.annotmap -> IdentSet.t -> QmlAst.code
  -> QmlAst.annotmap * QmlTypes.gamma * QmlAst.code


(**
Takes the gamma of the current compilation unit after being modified by process_code
and returns the gamma of the standard library after modification by process_code
*)
val get_stdlib_gamma : QmlTypes.gamma -> QmlTypes.gamma


(** [unprocess_code gamma annotmap qmlAst] eliminates Explicit Instantiation
directives in code [qmlAst], replacing them with standard OPA code.

@param gamma the environment with type and value definitions
@param annotmap the annotmap for, e.g., looking up types of expressions
@param qmlAst the syntax tree to transform

@return Updated annotmap and updated code with extra type arguments
abstracted and applied using standard OPA code and with [\@typeof]
directives implemented using the extra type arguments.
*)
val unprocess_code :
  val_:(?side:[`client|`server] -> string -> Ident.t) -> side:[ `server | `client ] ->
  QmlTypes.gamma -> QmlAst.annotmap -> QmlAst.code
  -> QmlAst.annotmap * QmlAst.code


(** Inserts code generating type definition environment accessible
from within OPA code (for runtime explicit instantiation).

@param gamma the environment with type definitions
@param annotmap the annotmap for creating new OPA expressions

@return Updated annotmap and code building the OPA representation
of the type environment.
*)
val generate_tsc_map_updates :
  val_:(?side:[`client|`server] -> string -> Ident.t) -> side:[ `server | `client ] ->
  ?memoize:bool -> local_typedefs:QmlAst.TypeIdentSet.t -> QmlTypes.gamma -> QmlAst.annotmap
  -> QmlAst.annotmap * QmlAst.code_elt
Something went wrong with that request. Please try again.