mirror of
https://github.com/kanaka/mal.git
synced 2024-11-11 00:52:44 +03:00
dd7a4f55f3
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*.
443 lines
13 KiB
Ada
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;
|