forked from kanaka/mal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtypes.ads
442 lines (271 loc) · 12.9 KB
/
types.ads
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
-- This started out as a simple public variant record.
-- Then smart pointers were added. They were part of the Mal_Type and
-- were required to be public because of the dependencies and
-- how the variant record was public. Not very Ada-like.
-- The third version bites the bullet and delares Mal_Type as tagged.
-- Smart pointers are an OO version in a separate package.
-- The Doubly_Linked_Lists have been replaced with a tree-like list instead...
-- The tree-like list has been replaced with a singly linked list. Sigh.
-- WARNING! This code contains:
-- Recursive data structures.
-- Object-based smart pointers.
-- Object-oriented code.
-- And strong-typing!
-- Chris M Moore 25/03/2015
with Ada.Strings.Unbounded;
with Smart_Pointers;
with Envs;
package Types is
-- Some simple types. Not supposed to use the standard types directly.
subtype Mal_Float is Float;
subtype Mal_Integer is Integer;
subtype Mal_String is String;
-- Start off with the top-level abstract type.
subtype Mal_Handle is Smart_Pointers.Smart_Pointer;
function "=" (A, B : Mal_Handle) return Mal_Handle;
function "=" (A, B : Mal_Handle) return Boolean;
type Sym_Types is (Nil, Bool, Int, Floating, Str, Sym, Atom, Node,
List, Func, Lambda, Error);
type Mal_Type is abstract new Smart_Pointers.Base_Class with private;
function Sym_Type (T : Mal_Type) return Sym_Types is abstract;
function Get_Meta (T : Mal_Type) return Mal_Handle;
procedure Set_Meta (T : in out Mal_Type'Class; SP : Mal_Handle);
function Copy (M : Mal_Handle) return Mal_Handle;
function To_String (T : Mal_Type'Class; Print_Readably : Boolean := True)
return Mal_String;
function Is_Macro_Call (T : Mal_Type'Class; Env : Envs.Env_Handle) return Boolean;
type Mal_Ptr is access all Mal_Type'Class;
-- A helper function that just view converts the smart pointer to
-- a Mal_Type'Class pointer.
function Deref (S : Mal_Handle) return Mal_Ptr;
-- A helper function to detect null smart pointers.
function Is_Null (S : Mal_Handle) return Boolean;
-- Derived types. All boilerplate from here.
type Nil_Mal_Type is new Mal_Type with private;
function New_Nil_Mal_Type return Mal_Handle;
overriding function Sym_Type (T : Nil_Mal_Type) return Sym_Types;
type Int_Mal_Type is new Mal_Type with private;
function New_Int_Mal_Type (Int : Mal_Integer) return Mal_Handle;
overriding function Sym_Type (T : Int_Mal_Type) return Sym_Types;
function Get_Int_Val (T : Int_Mal_Type) return Mal_Integer;
type Int_Ptr is access all Int_Mal_Type;
function Deref_Int (SP : Mal_Handle) return Int_Ptr;
type Float_Mal_Type is new Mal_Type with private;
function New_Float_Mal_Type (Floating : Mal_Float) return Mal_Handle;
overriding function Sym_Type (T : Float_Mal_Type) return Sym_Types;
function Get_Float_Val (T : Float_Mal_Type) return Mal_Float;
type Float_Ptr is access all Float_Mal_Type;
function Deref_Float (SP : Mal_Handle) return Float_Ptr;
type Bool_Mal_Type is new Mal_Type with private;
function New_Bool_Mal_Type (Bool : Boolean) return Mal_Handle;
overriding function Sym_Type (T : Bool_Mal_Type) return Sym_Types;
function Get_Bool (T : Bool_Mal_Type) return Boolean;
type Bool_Ptr is access all Bool_Mal_Type;
function Deref_Bool (SP : Mal_Handle) return Bool_Ptr;
type String_Mal_Type is new Mal_Type with private;
function New_String_Mal_Type (Str : Mal_String) return Mal_Handle;
overriding function Sym_Type (T : String_Mal_Type) return Sym_Types;
function Get_String (T : String_Mal_Type) return Mal_String;
type String_Ptr is access all String_Mal_Type;
function Deref_String (SP : Mal_Handle) return String_Ptr;
type Symbol_Mal_Type is new Mal_Type with private;
function New_Symbol_Mal_Type (Str : Mal_String) return Mal_Handle;
overriding function Sym_Type (T : Symbol_Mal_Type) return Sym_Types;
function Get_Sym (T : Symbol_Mal_Type) return Mal_String;
type Sym_Ptr is access all Symbol_Mal_Type;
function Deref_Sym (S : Mal_Handle) return Sym_Ptr;
type Atom_Mal_Type is new Mal_Type with private;
function New_Atom_Mal_Type (MH : Mal_Handle) return Mal_Handle;
overriding function Sym_Type (T : Atom_Mal_Type) return Sym_Types;
function Get_Atom (T : Atom_Mal_Type) return Mal_Handle;
procedure Set_Atom (T : in out Atom_Mal_Type; New_Val : Mal_Handle);
type Atom_Ptr is access all Atom_Mal_Type;
function Deref_Atom (S : Mal_Handle) return Atom_Ptr;
type Error_Mal_Type is new Mal_Type with private;
function New_Error_Mal_Type (Str : Mal_String) return Mal_Handle;
overriding function Sym_Type (T : Error_Mal_Type) return Sym_Types;
-- Lists.
type List_Types is (List_List, Vector_List, Hashed_List);
function Opening (LT : List_Types) return Character;
function Closing (LT : List_Types) return Character;
type List_Mal_Type is new Mal_Type with private;
function "=" (A, B : List_Mal_Type) return Boolean;
function New_List_Mal_Type
(List_Type : List_Types;
The_First_Node : Mal_Handle := Smart_Pointers.Null_Smart_Pointer)
return Mal_Handle;
function New_List_Mal_Type
(The_List : List_Mal_Type)
return Mal_Handle;
type Handle_Lists is array (Positive range <>) of Mal_Handle;
-- Make a new list of the form: (Handle_List(1), Handle_List(2)...)
function Make_New_List (Handle_List : Handle_Lists) return Mal_Handle;
overriding function Sym_Type (T : List_Mal_Type) return Sym_Types;
function Get_List_Type (L : List_Mal_Type) return List_Types;
function Prepend (Op : Mal_Handle; To_List : List_Mal_Type)
return Mal_Handle;
procedure Append (To_List : in out List_Mal_Type; Op : Mal_Handle);
function Length (L : List_Mal_Type) return Natural;
function Nth (L : List_Mal_Type; N : Natural) return Mal_Handle;
procedure Add_Defs (Defs : List_Mal_Type; Env : Envs.Env_Handle);
-- Get the first item in the list:
function Car (L : List_Mal_Type) return Mal_Handle;
-- Get the rest of the list (second item onwards)
function Cdr (L : List_Mal_Type) return Mal_Handle;
type Func_Access is access
function (Elem : Mal_Handle)
return Mal_Handle;
function Map
(Func_Ptr : Func_Access;
L : List_Mal_Type)
return Mal_Handle;
type Binary_Func_Access is access
function (A, B : Mal_Handle)
return Mal_Handle;
function Reduce
(Func_Ptr : Binary_Func_Access;
L : List_Mal_Type)
return Mal_Handle;
function Is_Null (L : List_Mal_Type) return Boolean;
function Null_List (L : List_Types) return List_Mal_Type;
function Pr_Str (T : List_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
function Cat_Str (T : List_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
function Concat (Rest_Handle : List_Mal_Type)
return Types.Mal_Handle; -- a new list
-- Duplicate copies the list (logically). This is to allow concatenation,
-- The result is always a List_List.
function Duplicate (The_List : List_Mal_Type) return Mal_Handle;
type List_Ptr is access all List_Mal_Type;
function Deref_List (SP : Mal_Handle) return List_Ptr;
type List_Class_Ptr is access all List_Mal_Type'Class;
function Deref_List_Class (SP : Mal_Handle) return List_Class_Ptr;
type Func_Mal_Type is new Mal_Type with private;
type Builtin_Func is access
function (MH : Mal_Handle) return Mal_Handle;
function New_Func_Mal_Type (Str : Mal_String; F : Builtin_Func)
return Mal_Handle;
overriding function Sym_Type (T : Func_Mal_Type) return Sym_Types;
function Get_Func_Name (T : Func_Mal_Type) return Mal_String;
function Call_Func
(FMT : Func_Mal_Type; Rest_List : Mal_Handle)
return Mal_Handle;
type Func_Ptr is access all Func_Mal_Type;
function Deref_Func (S : Mal_Handle) return Func_Ptr;
type Lambda_Mal_Type is new Mal_Type with private;
function New_Lambda_Mal_Type
(Params : Mal_Handle; Expr : Mal_Handle; Env : Envs.Env_Handle)
return Mal_Handle;
overriding function Sym_Type (T : Lambda_Mal_Type) return Sym_Types;
function Get_Env (L : Lambda_Mal_Type) return Envs.Env_Handle;
procedure Set_Env (L : in out Lambda_Mal_Type; Env : Envs.Env_Handle);
function Get_Params (L : Lambda_Mal_Type) return Mal_Handle;
function Get_Expr (L : Lambda_Mal_Type) return Mal_Handle;
function Get_Is_Macro (L : Lambda_Mal_Type) return Boolean;
procedure Set_Is_Macro (L : in out Lambda_Mal_Type; B : Boolean);
function Apply
(L : Lambda_Mal_Type;
Param_List : Mal_Handle) return Mal_Handle;
type Lambda_Ptr is access all Lambda_Mal_Type;
function Get_Macro (T : Mal_Handle; Env : Envs.Env_Handle) return Lambda_Ptr;
function Deref_Lambda (SP : Mal_Handle) return Lambda_Ptr;
generic
with function Int_Op (A, B : Mal_Integer) return Mal_Integer;
with function Float_Op (A, B : Mal_Float) return Mal_Float;
function Arith_Op (A, B : Mal_Handle) return Mal_Handle;
generic
with function Int_Rel_Op (A, B : Mal_Integer) return Boolean;
with function Float_Rel_Op (A, B : Mal_Float) return Boolean;
function Rel_Op (A, B : Mal_Handle) return Mal_Handle;
Runtime_Exception : exception;
Mal_Exception : exception; -- So tempting to call this Mal_Function but...
Mal_Exception_Value : Mal_Handle; -- Used by mal's throw command
private
type Mal_Type is abstract new Smart_Pointers.Base_Class with record
Meta : Mal_Handle;
end record;
-- Not allowed to be abstract and private. RM 3.9.3(10)
-- So if you call this it'll just raise an exception.
function To_Str (T : Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
type Nil_Mal_Type is new Mal_Type with null record;
overriding function To_Str (T : Nil_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
type Int_Mal_Type is new Mal_Type with record
Int_Val : Mal_Integer;
end record;
overriding function To_Str (T : Int_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
type Float_Mal_Type is new Mal_Type with record
Float_Val : Mal_Float;
end record;
overriding function To_Str (T : Float_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
type Bool_Mal_Type is new Mal_Type with record
Bool_Val : Boolean;
end record;
overriding function To_Str (T : Bool_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
type String_Mal_Type is new Mal_Type with record
The_String : Ada.Strings.Unbounded.Unbounded_String;
end record;
overriding function To_Str (T : String_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
type Symbol_Mal_Type is new Mal_Type with record
The_Symbol : Ada.Strings.Unbounded.Unbounded_String;
end record;
overriding function To_Str (T : Symbol_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
type Atom_Mal_Type is new Mal_Type with record
The_Atom : Mal_Handle;
end record;
overriding function To_Str (T : Atom_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
type Func_Mal_Type is new Mal_Type with record
Func_Name : Ada.Strings.Unbounded.Unbounded_String;
Func_P : Builtin_Func;
end record;
overriding function To_Str (T : Func_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
type Error_Mal_Type is new Mal_Type with record
Error_Msg : Ada.Strings.Unbounded.Unbounded_String;
end record;
overriding function To_Str (T : Error_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
-- Nodes have to be a differnt type from a List;
-- otherwise how do you represent a list within a list?
type Node_Mal_Type is new Mal_Type with record
Data : Mal_Handle;
Next : Mal_Handle; -- This is always a Node_Mal_Type handle
end record;
function New_Node_Mal_Type
(Data : Mal_Handle;
Next : Mal_Handle := Smart_Pointers.Null_Smart_Pointer)
return Mal_Handle;
overriding function Sym_Type (T : Node_Mal_Type) return Sym_Types;
overriding function To_Str
(T : Node_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
type Node_Ptr is access all Node_Mal_Type;
function Deref_Node (SP : Mal_Handle) return Node_Ptr;
type List_Mal_Type is new Mal_Type with record
List_Type : List_Types;
The_List : Mal_Handle;
Last_Elem : Mal_Handle;
end record;
overriding function To_Str
(T : List_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
type Container_Cursor is tagged record
The_Node : Node_Ptr := null;
end record;
type Lambda_Mal_Type is new Mal_Type with record
Params, Expr : Mal_Handle;
Env : Envs.Env_Handle;
Is_Macro : Boolean;
end record;
overriding function To_Str
(T : Lambda_Mal_Type; Print_Readably : Boolean := True)
return Mal_String;
end Types;