1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-21 10:37:58 +03:00
mal/crystal/types.cr

112 lines
1.9 KiB
Crystal
Raw Normal View History

2015-05-24 21:56:23 +03:00
require "./printer"
2015-05-04 06:12:24 +03:00
module Mal
class Symbol
property :str
2016-06-06 20:17:40 +03:00
def initialize(@str : String)
2015-05-04 06:12:24 +03:00
end
2015-05-23 22:00:21 +03:00
def ==(other : Symbol)
@str == other.str
end
2015-05-04 06:12:24 +03:00
end
class List < Array(Type)
end
class Vector < Array(Type)
end
class HashMap < Hash(String, Type)
end
2015-05-28 21:16:22 +03:00
class Atom
property :val
2016-06-06 20:17:40 +03:00
def initialize(@val : Type)
2015-05-28 21:16:22 +03:00
end
def ==(rhs : Atom)
@val == rhs.val
end
end
class Closure
property :ast, :params, :env, :fn
2016-06-06 20:17:40 +03:00
def initialize(@ast : Type, @params : List | Vector, @env : Env, @fn : Func)
end
end
class Type
2015-05-12 19:42:39 +03:00
alias Func = (Array(Type) -> Type)
alias ValueType = Nil | Bool | Int64 | String | Symbol | List | Vector | HashMap | Func | Closure | Atom
2015-05-28 21:16:22 +03:00
property :is_macro, :meta
2015-05-24 21:49:53 +03:00
def initialize(@val : ValueType)
2015-05-24 21:49:53 +03:00
@is_macro = false
2016-06-06 20:17:40 +03:00
@meta = nil as Type?
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
end
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
{% 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 :<, :>, :<=, :>=
end
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
class Array
def to_mal(t = Mal::List)
each_with_object(t.new){|e, l| l << e}
end
end