2015-05-24 21:56:23 +03:00
|
|
|
require "./printer"
|
|
|
|
|
2015-05-04 06:12:24 +03:00
|
|
|
module Mal
|
2015-05-11 19:47:58 +03:00
|
|
|
class Type
|
2015-05-12 19:42:39 +03:00
|
|
|
alias Func = (Array(Type) -> Type)
|
2015-05-11 19:47:58 +03:00
|
|
|
|
2015-05-28 21:16:22 +03:00
|
|
|
property :is_macro, :meta
|
2015-05-24 21:49:53 +03:00
|
|
|
|
2015-05-11 19:47:58 +03:00
|
|
|
def initialize(@val : ValueType)
|
2015-05-24 21:49:53 +03:00
|
|
|
@is_macro = false
|
2018-10-27 23:20:36 +03:00
|
|
|
@meta = nil.as(Type | Nil)
|
2015-05-11 19:47:58 +03:00
|
|
|
end
|
|
|
|
|
|
|
|
def initialize(other : Type)
|
2015-05-12 19:42:39 +03:00
|
|
|
@val = other.unwrap
|
2015-05-28 21:16:22 +03:00
|
|
|
@is_macro = other.is_macro
|
|
|
|
@meta = other.meta
|
2015-05-11 19:47:58 +03:00
|
|
|
end
|
2015-05-04 13:57:20 +03:00
|
|
|
|
2015-05-12 05:33:03 +03:00
|
|
|
def unwrap
|
|
|
|
@val
|
|
|
|
end
|
2015-05-12 19:42:39 +03:00
|
|
|
|
2015-05-24 21:49:53 +03:00
|
|
|
def macro?
|
|
|
|
@is_macro
|
|
|
|
end
|
|
|
|
|
2015-05-24 21:56:23 +03:00
|
|
|
def to_s
|
|
|
|
pr_str(self)
|
|
|
|
end
|
|
|
|
|
2015-05-28 21:16:22 +03:00
|
|
|
def dup
|
|
|
|
Type.new(@val).tap do |t|
|
|
|
|
t.is_macro = @is_macro
|
|
|
|
t.meta = @meta
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-05-23 22:00:21 +03:00
|
|
|
def ==(other : Type)
|
2015-05-12 19:42:39 +03:00
|
|
|
@val == other.unwrap
|
|
|
|
end
|
|
|
|
|
|
|
|
macro rel_op(*ops)
|
|
|
|
{% for op in ops %}
|
|
|
|
def {{op.id}}(other : Mal::Type)
|
|
|
|
l, r = @val, other.unwrap
|
2016-06-25 02:21:36 +03:00
|
|
|
{% for t in [Int64, String] %}
|
2015-05-12 19:42:39 +03:00
|
|
|
if l.is_a?({{t}}) && r.is_a?({{t}})
|
|
|
|
return (l) {{op.id}} (r)
|
|
|
|
end
|
|
|
|
{% end %}
|
|
|
|
if l.is_a?(Symbol) && r.is_a?(Symbol)
|
|
|
|
return l.str {{op.id}} r.str
|
|
|
|
end
|
|
|
|
false
|
|
|
|
end
|
|
|
|
{% end %}
|
|
|
|
end
|
|
|
|
|
|
|
|
rel_op :<, :>, :<=, :>=
|
2015-05-04 13:57:20 +03:00
|
|
|
end
|
2015-05-04 22:23:12 +03:00
|
|
|
|
2018-10-27 23:20:36 +03:00
|
|
|
class Symbol
|
|
|
|
property :str
|
|
|
|
|
|
|
|
def initialize(@str : String)
|
|
|
|
end
|
|
|
|
|
|
|
|
def ==(other : Symbol)
|
|
|
|
@str == other.str
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class List < Array(Type)
|
|
|
|
end
|
|
|
|
|
|
|
|
class Vector < Array(Type)
|
|
|
|
end
|
|
|
|
|
|
|
|
class HashMap < Hash(String, Type)
|
|
|
|
end
|
|
|
|
|
|
|
|
class Atom
|
|
|
|
property :val
|
|
|
|
|
|
|
|
def initialize(@val : Type)
|
|
|
|
end
|
|
|
|
|
|
|
|
def ==(rhs : Atom)
|
|
|
|
@val == rhs.val
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
class Closure
|
|
|
|
property :ast, :params, :env, :fn
|
|
|
|
|
|
|
|
def initialize(@ast : Type, @params : Array(Mal::Type) | List | Vector, @env : Env, @fn : Func)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
alias Type::ValueType = Nil | Bool | Int64 | String | Symbol | List | Vector | HashMap | Func | Closure | Atom
|
2015-05-12 19:42:39 +03:00
|
|
|
alias Func = Type::Func
|
2015-05-04 06:12:24 +03:00
|
|
|
end
|
2015-05-13 17:03:03 +03:00
|
|
|
|
2015-05-23 22:00:21 +03:00
|
|
|
macro gen_type(t, *args)
|
|
|
|
Mal::Type.new {{t.id}}.new({{*args}})
|
2015-05-13 17:03:03 +03:00
|
|
|
end
|
2015-05-28 18:32:16 +03:00
|
|
|
|
|
|
|
class Array
|
|
|
|
def to_mal(t = Mal::List)
|
2018-10-27 23:20:36 +03:00
|
|
|
each_with_object(t.new) { |e, l| l << e }
|
2015-05-28 18:32:16 +03:00
|
|
|
end
|
|
|
|
end
|