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
|
(*
Copyright (c) 2000
Cambridge University Technical Services Limited
Modified David C. J. Matthews 2008
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*)
(* Signature for the basic codetree types and operations. *)
signature BaseCodeTreeSig =
sig
type machineWord
datatype inlineStatus =
NonInline
| MaybeInline
| SmallFunction
| OnlyInline;
datatype codetree =
MatchFail (* Pattern-match failure *)
| AltMatch of codetree * codetree(* Pattern-match alternative choices *)
| Declar of declarForm (* Make a local declaration or push an argument *)
| Newenv of codetree list (* Start a block *)
| Constnt of machineWord (* Load a constant *)
| Extract of loadForm (* Get a local variable, an argument or a closure value *)
| Indirect of
{ (* Load a value from a heap record *)
base: codetree,
offset: int
}
| Eval of (* Evaluate a function with an argument list. *)
{
function: codetree,
argList: codetree list,
earlyEval: bool
}
| Lambda of lambdaForm (* Lambda expressions. *)
| MutualDecs of codetree list (* Set of mutually recursive declarations. *)
| Cond of codetree * codetree * codetree (* If-statement *)
| Case of (* Case expressions *)
{
cases : (codetree * int list) list,
test : codetree,
default : codetree,
min : int,
max : int
}
| BeginLoop of codetree * codetree list(* Start of tail-recursive inline function. *)
| Loop of codetree list (* Jump back to start of tail-recursive function. *)
| Raise of codetree (* Raise an exception *)
| Ldexc (* Load the exception (used at the start of a handler) *)
| Handle of (* Exception handler *)
{ (* Exception handler. *)
exp : codetree,
taglist : codetree list,
handler : codetree
}
| Recconstr of codetree list (* Records (tuples) *)
| Container of int (* Create a container for a tuple on the stack. *)
| SetContainer of (* Copy a tuple to a container. *)
{
container: codetree,
tuple: codetree,
size: int
}
| TupleFromContainer of codetree * int (* Make a tuple from the contents of a container. *)
| Global of optVal (* Global value *)
| CodeNil
and optVal = (* Global values - Also used in the optimiser. *)
JustTheVal of codetree
| ValWithDecs of {general : codetree, decs : codetree list}
| OptVal of
{
(* Expression to load this value - always a constant in global values. *)
general : codetree,
(* If it is not CodeNil it is the code which generated the general
value - either an inline procedure, a type constructor or a tuple. *)
special : codetree,
(* Environment for the special value. *)
environ : loadForm * int * int -> optVal,
(* Declarations to precede the value - Always nil for global values. *)
decs : codetree list,
(* A reference which is used to detect recursive inline expansions. *)
recCall: bool ref
}
withtype loadForm =
{ (* Load a value. *)
addr : int,
level: int,
fpRel: bool,
lastRef: bool
}
and declarForm =
{ (* Declare a value or push an argument. *)
value: codetree,
addr: int,
references: int
}
and diadic = codetree * codetree
and triadic = codetree * codetree * codetree
and lambdaForm =
{ (* Lambda expressions. *)
body : codetree,
isInline : inlineStatus,
name : string,
closure : codetree list,
numArgs : int,
level : int,
closureRefs : int,
makeClosure : bool
};
type prettyPrinter
val pretty : codetree * prettyPrinter -> unit
val isSmall : codetree * int -> bool
end;
|