comparison lab4/dict.mli @ 0:bfdcc3820b32

Basis
author Mike Spivey <mike@cs.ox.ac.uk>
date Thu, 05 Oct 2017 08:04:15 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:bfdcc3820b32
1 (* lab4/dict.mli *)
2 (* Copyright (c) 2017 J. M. Spivey *)
3
4 (* This module defines the types that represent definitions and Pascal
5 types in the semantic analyser, and provides an abstract data type of
6 'environments' used in the analyser. There are also some functions that
7 operate on types. *)
8
9 (* |ident| -- type of identifiers *)
10 type ident
11
12 (* |intern| -- convert string to identifier *)
13 val intern : string -> ident
14
15 (* |spelling| -- retrieve identifier as string *)
16 val spelling : ident -> string
17
18 (* |fId| -- format identifier for printing *)
19 val fId : ident -> Print.arg
20
21 (* |location| -- runtime locations *)
22 type location =
23 Local of int (* Local (offset) *)
24 | Global of Optree.symbol (* Global (label) *)
25 | Register of int (* Register *)
26 | Nowhere (* Compile-time only *)
27
28 (* |Loc| -- printf format for locations *)
29 val fLoc: location -> Print.arg
30
31 (* |libid| -- type of picoPascal library procedures *)
32 type libid = ChrFun | OrdFun | PrintNum | PrintChar | PrintString
33 | NewLine | ReadChar | ExitProc | NewProc | ArgcFun | ArgvProc
34 | OpenIn | CloseIn | Operator of Optree.op
35
36 val fLibId : libid -> Print.arg
37
38 (* |def_kind| -- kinds of definition *)
39 type def_kind =
40 ConstDef of int (* Constant (value) *)
41 | StringDef (* String constant *)
42 | TypeDef (* Type *)
43 | VarDef (* Variable *)
44 | CParamDef (* Value parameter *)
45 | VParamDef (* Var parameter *)
46 | FieldDef (* Field of record *)
47 | ProcDef (* Procedure *)
48 | PParamDef (* Proc parameter *)
49 | LibDef of libproc (* Lib proc (data) *)
50 | HoleDef of ptype ref (* Pending type *)
51 | DummyDef (* Dummy *)
52
53 (* |def| -- definitions in environment *)
54 and def =
55 { d_tag: ident; (* Name *)
56 d_kind: def_kind; (* Kind of object *)
57 d_type: ptype; (* Type *)
58 d_level: int; (* Static level *)
59 mutable d_mem: bool; (* Whether addressible *)
60 mutable d_addr: location } (* Run-time location *)
61
62 and basic_type = VoidType | IntType | CharType | BoolType | AddrType
63
64 (* |ptype| -- picoPascal types *)
65 and ptype =
66 { t_id: int; (* Unique identifier *)
67 t_guts: type_guts; (* Shape of the type *)
68 t_rep: Mach.metrics } (* Runtime representation *)
69
70 and type_guts =
71 BasicType of basic_type
72 | ArrayType of int * ptype
73 | RecordType of def list
74 | ProcType of proc_data
75 | PointerType of ptype ref
76
77 (* |proc_data| -- data about a procedure type *)
78 and proc_data =
79 { p_fparams: def list;
80 p_pcount : int;
81 p_result: ptype }
82
83 (* |libproc| -- data about a library procedure *)
84 and libproc =
85 { q_id: libid;
86 q_nargs: int;
87 q_argtypes: ptype list }
88
89 val offset_of : def -> int
90
91 val integer : ptype
92 val character : ptype
93 val boolean : ptype
94 val voidtype : ptype
95 val addrtype : ptype
96
97 type environment
98
99 (* |new_block| -- add a new top block *)
100 val new_block : environment -> environment
101
102 (* |add_block| -- add an existing def list as top block *)
103 val add_block : def list -> environment -> environment
104
105 (* |top_block| -- return top block as a def list *)
106 val top_block : environment -> def list
107
108 (* |define| -- add a definition, raise Exit if already declared *)
109 val define : def -> environment -> environment
110
111 (* |replace| -- replace tentative definition with final definition *)
112 val replace : def -> environment -> environment
113
114 (* |find_def| -- search a def list or raise Not_found *)
115 val find_def : ident -> def list -> def
116
117 (* |lookup| -- search an environment or raise Not_found *)
118 val lookup : ident -> environment -> def
119
120 (* |empty| -- empty environment *)
121 val empty : environment
122
123
124 (* Here are some functions that operate on types. The chief one is the
125 function |same_type| that tests whether two types are the same; it
126 uses name equivalence.
127
128 |match_args| checks two formal paramter lists for 'congurence', i.e.,
129 that corresponding parameters have the same types, and that value
130 parameters are not confused with var parameters. This test is used
131 for procedures that take other procedures as parameters. *)
132
133 (* |row| -- construct array type *)
134 val row : int -> ptype -> ptype
135
136 (* |mk_type| -- construct new (uniquely labelled) type *)
137 val mk_type : type_guts -> Mach.metrics -> ptype
138
139 (* |discrete| -- test if a type has discrete values *)
140 val discrete : ptype -> bool
141
142 (* |scalar| -- test if a type is simple *)
143 val scalar : ptype -> bool
144
145 (* |is_string| -- test if a type is 'array N of char' *)
146 val is_string : ptype -> bool
147
148 (* |bound| -- get bound of array type *)
149 val bound : ptype -> int
150
151 (* |is_pointer| -- test if a type is 'pointer to T' *)
152 val is_pointer : ptype -> bool
153
154 (* |base_type| -- get base type of pointer or array *)
155 val base_type : ptype -> ptype
156
157 (* |get_proc| -- get data from procedure type *)
158 val get_proc : ptype -> proc_data
159
160 (* |same_type| -- test two types for equality (name equivalence) *)
161 val same_type : ptype -> ptype -> bool
162
163 (* |match_args| -- test two formal parameter lists for congruence *)
164 val match_args : def list -> def list -> bool
165