A fork of Crisp for HARP
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

413 Zeilen
9.4 KiB

  1. require "time"
  2. require "./types"
  3. require "./error"
  4. require "./printer"
  5. require "./reader"
  6. require "./readline"
  7. module Mal
  8. macro calc_op(op)
  9. -> (args : Array(Mal::Type)) {
  10. x, y = args[0].unwrap, args[1].unwrap
  11. eval_error "invalid arguments for binary operator {{op.id}}" unless x.is_a?(Int32) && y.is_a?(Int32)
  12. Mal::Type.new(x {{op.id}} y)
  13. }
  14. end
  15. def self.list(args)
  16. args.to_mal
  17. end
  18. def self.list?(args)
  19. args.first.unwrap.is_a? Mal::List
  20. end
  21. def self.empty?(args)
  22. a = args.first.unwrap
  23. a.is_a?(Array) ? a.empty? : false
  24. end
  25. def self.count(args)
  26. a = args.first.unwrap
  27. case a
  28. when Array
  29. a.size as Int32
  30. when Nil
  31. 0
  32. else
  33. eval_error "invalid argument for function 'count'"
  34. end
  35. end
  36. def self.pr_str_(args)
  37. args.map{|a| pr_str(a)}.join(" ")
  38. end
  39. def self.str(args)
  40. args.map{|a| pr_str(a, false)}.join
  41. end
  42. def self.prn(args)
  43. puts self.pr_str_(args)
  44. nil
  45. end
  46. def self.println(args)
  47. puts args.map{|a| pr_str(a, false)}.join(" ")
  48. nil
  49. end
  50. def self.read_string(args)
  51. head = args.first.unwrap
  52. eval_error "argument of read-str must be string" unless head.is_a? String
  53. read_str head
  54. end
  55. def self.slurp(args)
  56. head = args.first.unwrap
  57. eval_error "argument of slurp must be string" unless head.is_a? String
  58. begin
  59. File.read head
  60. rescue e : Errno
  61. eval_error "no such file"
  62. end
  63. end
  64. def self.cons(args)
  65. head, tail = args[0] as Mal::Type, args[1].unwrap
  66. eval_error "2nd arg of cons must be list" unless tail.is_a? Array
  67. ([head] + tail).to_mal
  68. end
  69. def self.concat(args)
  70. args.each_with_object(Mal::List.new) do |arg, list|
  71. a = arg.unwrap
  72. eval_error "arguments of concat must be list" unless a.is_a?(Array)
  73. a.each{|e| list << e}
  74. end
  75. end
  76. def self.nth(args)
  77. a0, a1 = args[0].unwrap, args[1].unwrap
  78. eval_error "1st argument of nth must be list or vector" unless a0.is_a? Array
  79. eval_error "2nd argument of nth must be integer" unless a1.is_a? Int32
  80. a0[a1]
  81. end
  82. def self.first(args)
  83. a0 = args[0].unwrap
  84. return nil if a0.nil?
  85. eval_error "1st argument of first must be list or vector or nil" unless a0.is_a? Array
  86. a0.empty? ? nil : a0.first
  87. end
  88. def self.rest(args)
  89. a0 = args[0].unwrap
  90. return Mal::List.new if a0.nil?
  91. eval_error "1st argument of first must be list or vector or nil" unless a0.is_a? Array
  92. return Mal::List.new if a0.empty?
  93. a0[1..-1].to_mal
  94. end
  95. def self.apply(args)
  96. eval_error "apply must take at least 2 arguments" unless args.size >= 2
  97. head = args.first.unwrap
  98. last = args.last.unwrap
  99. eval_error "last argument of apply must be list or vector" unless last.is_a? Array
  100. case head
  101. when Mal::Closure
  102. head.fn.call(args[1..-2] + last)
  103. when Mal::Func
  104. head.call(args[1..-2] + last)
  105. else
  106. eval_error "1st argument of apply must be function or closure"
  107. end
  108. end
  109. def self.map(args)
  110. func = args.first.unwrap
  111. list = args[1].unwrap
  112. eval_error "2nd argument of map must be list or vector" unless list.is_a? Array
  113. f = case func
  114. when Mal::Closure then func.fn
  115. when Mal::Func then func
  116. else eval_error "1st argument of map must be function"
  117. end
  118. list.each_with_object(Mal::List.new) do |elem, mapped|
  119. mapped << f.call([elem])
  120. end
  121. end
  122. def self.nil?(args)
  123. args.first.unwrap.nil?
  124. end
  125. def self.true?(args)
  126. a = args.first.unwrap
  127. a.is_a?(Bool) && a
  128. end
  129. def self.false?(args)
  130. a = args.first.unwrap
  131. a.is_a?(Bool) && !a
  132. end
  133. def self.symbol?(args)
  134. args.first.unwrap.is_a?(Mal::Symbol)
  135. end
  136. def self.symbol(args)
  137. head = args.first.unwrap
  138. eval_error "1st argument of symbol function must be string" unless head.is_a? String
  139. Mal::Symbol.new head
  140. end
  141. def self.keyword(args)
  142. head = args.first.unwrap
  143. eval_error "1st argument of symbol function must be string" unless head.is_a? String
  144. "\u029e" + head
  145. end
  146. def self.keyword?(args)
  147. head = args.first.unwrap
  148. head.is_a?(String) && !head.empty? && head[0] == '\u029e'
  149. end
  150. def self.vector(args)
  151. args.to_mal(Mal::Vector)
  152. end
  153. def self.vector?(args)
  154. args.first.unwrap.is_a? Mal::Vector
  155. end
  156. def self.hash_map(args)
  157. eval_error "hash-map must take even number of arguments" unless args.size.even?
  158. map = Mal::HashMap.new
  159. args.each_slice(2) do |kv|
  160. k = kv[0].unwrap
  161. eval_error "key must be string" unless k.is_a? String
  162. map[k] = kv[1]
  163. end
  164. map
  165. end
  166. def self.map?(args)
  167. args.first.unwrap.is_a? Mal::HashMap
  168. end
  169. def self.assoc(args)
  170. head = args.first.unwrap
  171. eval_error "1st argument of assoc must be hashmap" unless head.is_a? Mal::HashMap
  172. eval_error "assoc must take a list and even number of arguments" unless (args.size - 1).even?
  173. map = Mal::HashMap.new
  174. head.each{|k, v| map[k] = v}
  175. args[1..-1].each_slice(2) do |kv|
  176. k = kv[0].unwrap
  177. eval_error "key must be string" unless k.is_a? String
  178. map[k] = kv[1]
  179. end
  180. map
  181. end
  182. def self.dissoc(args)
  183. head = args.first.unwrap
  184. eval_error "1st argument of assoc must be hashmap" unless head.is_a? Mal::HashMap
  185. map = Mal::HashMap.new
  186. head.each{|k,v| map[k] = v}
  187. args[1..-1].each do |arg|
  188. key = arg.unwrap
  189. eval_error "key must be string" unless key.is_a? String
  190. map.delete key
  191. end
  192. map
  193. end
  194. def self.get(args)
  195. a0, a1 = args[0].unwrap, args[1].unwrap
  196. return nil unless a0.is_a? Mal::HashMap
  197. eval_error "2nd argument of get must be string" unless a1.is_a? String
  198. # a0[a1]? isn't available because type ofa0[a1] is infered NoReturn
  199. a0.has_key?(a1) ? a0[a1] : nil
  200. end
  201. def self.contains?(args)
  202. a0, a1 = args[0].unwrap, args[1].unwrap
  203. eval_error "1st argument of get must be hashmap" unless a0.is_a? Mal::HashMap
  204. eval_error "2nd argument of get must be string" unless a1.is_a? String
  205. a0.has_key? a1
  206. end
  207. def self.keys(args)
  208. head = args.first.unwrap
  209. eval_error "1st argument of assoc must be hashmap" unless head.is_a? Mal::HashMap
  210. head.keys.each_with_object(Mal::List.new){|e,l| l << Mal::Type.new(e)}
  211. end
  212. def self.vals(args)
  213. head = args.first.unwrap
  214. eval_error "1st argument of assoc must be hashmap" unless head.is_a? Mal::HashMap
  215. head.values.to_mal
  216. end
  217. def self.sequential?(args)
  218. args.first.unwrap.is_a? Array
  219. end
  220. def self.readline(args)
  221. head = args.first.unwrap
  222. eval_error "1st argument of readline must be string" unless head.is_a? String
  223. my_readline head
  224. end
  225. def self.meta(args)
  226. m = args.first.meta
  227. m.nil? ? nil : m
  228. end
  229. def self.with_meta(args)
  230. t = args.first.dup
  231. t.meta = args[1]
  232. t
  233. end
  234. def self.atom(args)
  235. Mal::Atom.new args.first
  236. end
  237. def self.atom?(args)
  238. args.first.unwrap.is_a? Mal::Atom
  239. end
  240. def self.deref(args)
  241. head = args.first.unwrap
  242. eval_error "1st argument of deref must be atom" unless head.is_a? Mal::Atom
  243. head.val
  244. end
  245. def self.reset!(args)
  246. head = args.first.unwrap
  247. eval_error "1st argument of reset! must be atom" unless head.is_a? Mal::Atom
  248. head.val = args[1]
  249. end
  250. def self.swap!(args)
  251. atom = args.first.unwrap
  252. eval_error "1st argument of swap! must be atom" unless atom.is_a? Mal::Atom
  253. a = [atom.val] + args[2..-1]
  254. func = args[1].unwrap
  255. case func
  256. when Mal::Func
  257. atom.val = func.call a
  258. when Mal::Closure
  259. atom.val = func.fn.call a
  260. else
  261. eval_error "2nd argumetn of swap! must be function"
  262. end
  263. end
  264. def self.conj(args)
  265. seq = args.first.unwrap
  266. case seq
  267. when Mal::List
  268. (args[1..-1].reverse + seq).to_mal
  269. when Mal::Vector
  270. (seq + args[1..-1]).to_mal(Mal::Vector)
  271. else
  272. eval_error "1st argument of conj must be list or vector"
  273. end
  274. end
  275. def self.time_ms(args)
  276. (Time.now.to_i.to_i32) * 1000
  277. end
  278. # Note:
  279. # Simply using ->self.some_func doesn't work
  280. macro func(name)
  281. -> (args : Array(Mal::Type)) { Mal::Type.new self.{{name.id}}(args) }
  282. end
  283. macro rel_op(op)
  284. -> (args : Array(Mal::Type)) { Mal::Type.new (args[0] {{op.id}} args[1]) }
  285. end
  286. NS = {
  287. "+" => calc_op(:+)
  288. "-" => calc_op(:-)
  289. "*" => calc_op(:*)
  290. "/" => calc_op(:/)
  291. "list" => func(:list)
  292. "list?" => func(:list?)
  293. "empty?" => func(:empty?)
  294. "count" => func(:count)
  295. "=" => rel_op(:==)
  296. "<" => rel_op(:<)
  297. ">" => rel_op(:>)
  298. "<=" => rel_op(:<=)
  299. ">=" => rel_op(:>=)
  300. "pr-str" => func(:pr_str_)
  301. "str" => func(:str)
  302. "prn" => func(:prn)
  303. "println" => func(:println)
  304. "read-string" => func(:read_string)
  305. "slurp" => func(:slurp)
  306. "cons" => func(:cons)
  307. "concat" => func(:concat)
  308. "nth" => func(:nth)
  309. "first" => func(:first)
  310. "rest" => func(:rest)
  311. "throw" => -> (args : Array(Mal::Type)) { raise Mal::RuntimeException.new args[0] }
  312. "apply" => func(:apply)
  313. "map" => func(:map)
  314. "nil?" => func(:nil?)
  315. "true?" => func(:true?)
  316. "false?" => func(:false?)
  317. "symbol?" => func(:symbol?)
  318. "symbol" => func(:symbol)
  319. "keyword" => func(:keyword)
  320. "keyword?" => func(:keyword?)
  321. "vector" => func(:vector)
  322. "vector?" => func(:vector?)
  323. "hash-map" => func(:hash_map)
  324. "map?" => func(:map?)
  325. "assoc" => func(:assoc)
  326. "dissoc" => func(:dissoc)
  327. "get" => func(:get)
  328. "contains?" => func(:contains?)
  329. "keys" => func(:keys)
  330. "vals" => func(:vals)
  331. "sequential?" => func(:sequential?)
  332. "readline" => func(:readline)
  333. "meta" => func(:meta)
  334. "with-meta" => func(:with_meta)
  335. "atom" => func(:atom)
  336. "atom?" => func(:atom?)
  337. "deref" => func(:deref)
  338. "deref" => func(:deref)
  339. "reset!" => func(:reset!)
  340. "swap!" => func(:swap!)
  341. "conj" => func(:conj)
  342. "time-ms" => func(:time_ms)
  343. } of String => Mal::Func
  344. end