1
1
mirror of https://github.com/kanaka/mal.git synced 2024-11-11 00:52:44 +03:00
mal/ada/types.ads
Joel Martin dd7a4f55f3 Test uncaught throw, catchless try* . Fix 46 impls.
Fixes made to: ada, c, chuck, clojure, coffee, common-lisp, cpp,
crystal, d, dart, elm, erlang, es6, factor, fsharp, gnu-smalltalk,
groovy, guile, haxe, hy, js, livescript, matlab, miniMAL, nasm, nim,
objc, objpascal, ocaml, perl, perl6, php, plsql, ps, python, r,
rpython, ruby, scheme, swift3, tcl, ts, vb, vimscript, wasm, yorick.

Catchless try* test is an optional test. Not all implementations
support catchless try* but a number were fixed so they at least don't
crash on catchless try*.
2018-12-12 14:18:26 -06:00

443 lines
13 KiB
Ada

-- 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;