SIGN IN SIGN UP
2021-11-19 20:32:12 -07:00
module Mal
module Types
class Args < ::Array
end
2021-12-01 14:33:46 -07:00
class List < ::Array
def meta
@meta ||= Types::Nil.instance
end
def meta=(value)
@meta = value
end
2021-12-01 14:33:46 -07:00
def to_list
self
end
end
class Vector < ::Array
def meta
@meta ||= Types::Nil.instance
end
def meta=(value)
@meta = value
end
2021-12-01 14:33:46 -07:00
def to_list
List.new(self)
end
end
class Hashmap < ::Hash
def meta
@meta ||= Types::Nil.instance
end
def meta=(value)
@meta = value
end
end
2021-11-19 20:32:12 -07:00
class Base < ::Struct.new(:value)
2021-11-26 17:00:10 -07:00
def inspect
value.inspect
2021-11-26 17:00:10 -07:00
end
end
2021-11-22 11:34:21 -07:00
class String < Base; end
class Atom < Base
def inspect
"Atom<#{value.inspect}>"
end
end
class Keyword < Base
2021-11-22 11:34:21 -07:00
def self.for(value)
@_keywords ||= {}
if @_keywords.key?(value)
@_keywords[value]
else
@_keywords[value] = new(value)
end
end
end
2021-11-21 15:57:26 -07:00
class Number < Base
2021-11-21 15:57:26 -07:00
def +(other)
self.class.new(value + other.value)
end
def -(other)
self.class.new(value - other.value)
end
def *(other)
self.class.new(value * other.value)
end
def /(other)
self.class.new(value / other.value)
end
end
class Symbol < Base
2021-11-22 11:34:21 -07:00
def self.for(value)
@_symbols ||= {}
if @_symbols.key?(value)
@_symbols[value]
else
@_symbols[value] = new(value)
end
end
def inspect
value
end
2021-11-22 11:34:21 -07:00
end
2021-11-19 20:32:12 -07:00
class Nil < Base
2021-11-22 11:34:21 -07:00
def self.instance
2021-11-26 17:00:10 -07:00
@_instance ||= new(nil)
2021-11-22 11:34:21 -07:00
end
2021-11-26 17:00:10 -07:00
def inspect
"nil"
2021-11-19 20:32:12 -07:00
end
end
class True < Base
2021-11-22 11:34:21 -07:00
def self.instance
2021-11-26 17:00:10 -07:00
@_instance ||= new(true)
2021-11-19 20:32:12 -07:00
end
end
class False < Base
2021-11-22 11:34:21 -07:00
def self.instance
2021-11-26 17:00:10 -07:00
@_instance ||= new(false)
end
end
class Callable
def initialize(&block)
@fn = block
end
def call(args = nil)
args = Types::Args.new if args.nil?
raise unless args.is_a?(Types::Args)
@fn.call(*args)
2021-11-26 17:00:10 -07:00
end
def inspect
raise NotImplementedError, "invalid callable"
2021-11-26 17:00:10 -07:00
end
2021-12-01 14:33:46 -07:00
def is_mal_fn?
false
end
def is_macro?
false
end
def meta
@meta ||= Types::Nil.instance
end
def meta=(value)
@meta = value
end
2021-11-26 17:00:10 -07:00
end
class Builtin < Callable
attr_reader :name
def initialize(name, &block)
@name = name
@fn = block
end
2021-11-26 17:00:10 -07:00
def inspect
"#<builtin '#{name}'>"
2021-11-26 17:00:10 -07:00
end
2021-12-01 14:33:46 -07:00
end
class Function < Callable
attr_reader :ast, :params, :env
def initialize(ast, params, env, &block)
@ast = ast
@params = params
@env = env
@fn = block
end
def inspect
"#<function>"
end
2021-11-26 17:00:10 -07:00
def is_mal_fn?
2021-12-01 14:33:46 -07:00
true
end
def to_macro
Macro.new(ast, params, env, &@fn)
2021-11-26 17:00:10 -07:00
end
end
2021-12-01 14:33:46 -07:00
class Macro < Callable
2021-11-26 17:00:10 -07:00
attr_reader :ast, :params, :env
def initialize(ast, params, env, &block)
@ast = ast
@params = params
@env = env
@fn = block
end
def inspect
2021-12-01 14:33:46 -07:00
"#<macro>"
2021-11-22 11:34:21 -07:00
end
2021-11-26 17:00:10 -07:00
def is_mal_fn?
true
2021-11-19 20:32:12 -07:00
end
2021-12-01 14:33:46 -07:00
def is_macro?
true
end
2021-11-19 20:32:12 -07:00
end
end
end