2021-11-19 20:32:12 -07:00
|
|
|
module Mal
|
|
|
|
|
module Types
|
2021-12-10 17:56:47 -07:00
|
|
|
class Args < ::Array
|
|
|
|
|
end
|
|
|
|
|
|
2021-12-01 14:33:46 -07:00
|
|
|
class List < ::Array
|
2021-12-10 17:56:47 -07:00
|
|
|
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
|
2021-12-10 17:56:47 -07:00
|
|
|
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
|
|
|
|
|
|
2021-12-10 17:56:47 -07:00
|
|
|
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
|
|
|
|
2021-11-30 20:32:59 -07:00
|
|
|
class Base < ::Struct.new(:value)
|
2021-11-26 17:00:10 -07:00
|
|
|
def inspect
|
2021-11-30 20:32:59 -07:00
|
|
|
value.inspect
|
2021-11-26 17:00:10 -07:00
|
|
|
end
|
|
|
|
|
end
|
2021-11-22 11:34:21 -07:00
|
|
|
|
2021-11-30 20:32:59 -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
|
|
|
|
2021-11-30 20:32:59 -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
|
|
|
|
|
|
2021-11-30 20:32:59 -07:00
|
|
|
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
|
2021-11-30 20:32:59 -07:00
|
|
|
|
|
|
|
|
def inspect
|
|
|
|
|
value
|
|
|
|
|
end
|
2021-11-22 11:34:21 -07:00
|
|
|
end
|
2021-11-19 20:32:12 -07:00
|
|
|
|
2021-11-30 20:32:59 -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
|
|
|
|
|
|
2021-11-30 20:32:59 -07:00
|
|
|
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
|
|
|
|
|
|
2021-11-30 20:32:59 -07:00
|
|
|
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
|
|
|
|
|
|
2021-12-10 17:56:47 -07:00
|
|
|
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
|
2021-12-10 17:56:47 -07:00
|
|
|
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
|
2021-12-10 17:56:47 -07:00
|
|
|
|
|
|
|
|
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
|
2021-12-10 17:56:47 -07:00
|
|
|
attr_reader :name
|
|
|
|
|
|
|
|
|
|
def initialize(name, &block)
|
|
|
|
|
@name = name
|
|
|
|
|
@fn = block
|
|
|
|
|
end
|
|
|
|
|
|
2021-11-26 17:00:10 -07:00
|
|
|
def inspect
|
2021-12-10 17:56:47 -07:00
|
|
|
"#<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
|