2021-11-19 20:32:12 -07:00
|
|
|
require_relative "errors"
|
|
|
|
|
require_relative "types"
|
|
|
|
|
|
|
|
|
|
module Mal
|
|
|
|
|
extend self
|
|
|
|
|
|
|
|
|
|
def pr_str(mal, print_readably = false)
|
|
|
|
|
case mal
|
|
|
|
|
when Types::List
|
|
|
|
|
"(#{mal.map { |m| pr_str(m, print_readably) }.join(" ")})"
|
|
|
|
|
when Types::Vector
|
|
|
|
|
"[#{mal.map { |m| pr_str(m, print_readably) }.join(" ")}]"
|
|
|
|
|
when Types::Hashmap
|
|
|
|
|
"{#{mal.map { |k, v| [pr_str(k, print_readably), pr_str(v, print_readably)].join(" ") }.join(" ")}}"
|
|
|
|
|
when Types::Keyword
|
|
|
|
|
if print_readably
|
|
|
|
|
pr_str_keyword(mal)
|
|
|
|
|
else
|
2021-11-30 20:32:59 -07:00
|
|
|
":#{mal.value}"
|
2021-11-19 20:32:12 -07:00
|
|
|
end
|
|
|
|
|
when Types::String
|
|
|
|
|
if print_readably
|
|
|
|
|
pr_str_string(mal)
|
|
|
|
|
else
|
2021-11-30 20:32:59 -07:00
|
|
|
mal.value
|
2021-11-19 20:32:12 -07:00
|
|
|
end
|
|
|
|
|
when Types::Atom
|
2021-11-30 20:32:59 -07:00
|
|
|
"(atom #{pr_str(mal.value, print_readably)})"
|
|
|
|
|
when Types::Base, Types::Callable
|
2021-11-26 17:00:10 -07:00
|
|
|
mal.inspect
|
2021-11-19 20:32:12 -07:00
|
|
|
else
|
2021-12-10 17:56:47 -07:00
|
|
|
raise InvalidTypeError, "unable to print value <#{mal.inspect}>"
|
2021-11-19 20:32:12 -07:00
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def pr_str_keyword(mal)
|
|
|
|
|
value = mal.value.dup
|
|
|
|
|
|
|
|
|
|
value.gsub!('\\','\\\\\\\\')
|
|
|
|
|
value.gsub!("\n",'\n')
|
|
|
|
|
value.gsub!('"','\"')
|
|
|
|
|
|
|
|
|
|
":#{value}"
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def pr_str_string(mal)
|
|
|
|
|
value = mal.value.dup
|
|
|
|
|
|
|
|
|
|
value.gsub!('\\','\\\\\\\\')
|
|
|
|
|
value.gsub!("\n",'\n')
|
|
|
|
|
value.gsub!('"','\"')
|
|
|
|
|
|
|
|
|
|
"\"#{value}\""
|
|
|
|
|
end
|
|
|
|
|
end
|