A fork of Crisp for HARP
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 

114 lignes
1.9 KiB

require "./printer"
module Mal
class Symbol
property :str
def initialize(@str)
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)
end
def ==(rhs : Atom)
@val == rhs.val
end
end
class Closure
property :ast, :params, :env, :fn
def initialize(@ast, @params, @env, @fn)
end
end
class Type
alias Func = (Array(Type) -> Type)
alias ValueType = Nil | Bool | Int32 | String | Symbol | List | Vector | HashMap | Func | Closure | Atom
is_macro :: Bool
meta :: Type
property :is_macro, :meta
def initialize(@val : ValueType)
@is_macro = false
@meta = nil
end
def initialize(other : Type)
@val = other.unwrap
@is_macro = other.is_macro
@meta = other.meta
end
def unwrap
@val
end
def macro?
@is_macro
end
def to_s
pr_str(self)
end
def dup
Type.new(@val).tap do |t|
t.is_macro = @is_macro
t.meta = @meta
end
end
def ==(other : Type)
@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 [Int32, String] %}
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
alias Func = Type::Func
end
macro gen_type(t, *args)
Mal::Type.new {{t.id}}.new({{*args}})
end
class Array
def to_mal(t = Mal::List)
each_with_object(t.new){|e, l| l << e}
end
end