5 alias Func = (Array(Type) -> Type)
7 property :is_macro, :meta
9 def initialize(@val : ValueType)
11 @meta = nil.as(Type | Nil)
14 def initialize(other : Type)
16 @is_macro = other.is_macro
33 Type.new(@val).tap do |t|
34 t.is_macro = @is_macro
45 def {{op.id}}(other : Mal::Type)
46 l, r = @val, other.unwrap
47 {% for t in [Int64, String] %}
48 if l.is_a?({{t}}) && r.is_a?({{t}})
49 return (l) {{op.id}} (r)
52 if l.is_a?(Symbol) && r.is_a?(Symbol)
53 return l.str {{op.id}} r.str
60 rel_op :<, :>, :<=, :>=
66 def initialize(@str : String)
69 def ==(other : Symbol)
74 class List < Array(Type)
77 class Vector < Array(Type)
80 class HashMap < Hash(String, Type)
86 def initialize(@val : Type)
95 property :ast, :params, :env, :fn
97 def initialize(@ast : Type, @params : Array(Mal::Type) | List | Vector, @env : Env, @fn : Func)
101 alias Type::ValueType = Nil | Bool | Int64 | String | Symbol | List | Vector | HashMap | Func | Closure | Atom
102 alias Func = Type::Func
105 macro gen_type(t, *args)
106 Mal::Type.new {{t.id}}.new({{*args}})
110 def to_mal(t = Mal::List)
111 each_with_object(t.new) { |e, l| l << e }