| 1 | require "readline" |
| 2 | require_relative "reader" |
| 3 | require_relative "printer" |
| 4 | |
| 5 | $core_ns = { |
| 6 | :"=" => lambda {|a,b| a == b}, |
| 7 | :throw => lambda {|a| raise MalException.new(a), "Mal Exception"}, |
| 8 | :nil? => lambda {|a| a == nil}, |
| 9 | :true? => lambda {|a| a == true}, |
| 10 | :false? => lambda {|a| a == false}, |
| 11 | :string? => lambda {|a| (a.is_a? String) && "\u029e" != a[0]}, |
| 12 | :symbol => lambda {|a| a.to_sym}, |
| 13 | :symbol? => lambda {|a| a.is_a? Symbol}, |
| 14 | :keyword => lambda {|a| (a.is_a? String) && "\u029e" == a[0] ? a : "\u029e"+a}, |
| 15 | :keyword? => lambda {|a| (a.is_a? String) && "\u029e" == a[0]}, |
| 16 | :number? => lambda {|a| a.is_a? Numeric}, |
| 17 | :fn? => lambda {|a| (a.is_a? Proc) && (!(a.is_a? Function) || !a.is_macro)}, |
| 18 | :macro? => lambda {|a| (a.is_a? Function) && a.is_macro}, |
| 19 | |
| 20 | :"pr-str" => lambda {|*a| a.map {|e| _pr_str(e, true)}.join(" ")}, |
| 21 | :str => lambda {|*a| a.map {|e| _pr_str(e, false)}.join("")}, |
| 22 | :prn => lambda {|*a| puts(a.map {|e| _pr_str(e, true)}.join(" "))}, |
| 23 | :println => lambda {|*a| puts(a.map {|e| _pr_str(e, false)}.join(" "))}, |
| 24 | :readline => lambda {|a| Readline.readline(a,true)}, |
| 25 | :"read-string" => lambda {|a| read_str(a)}, |
| 26 | :slurp => lambda {|a| File.read(a)}, |
| 27 | :< => lambda {|a,b| a < b}, |
| 28 | :<= => lambda {|a,b| a <= b}, |
| 29 | :> => lambda {|a,b| a > b}, |
| 30 | :>= => lambda {|a,b| a >= b}, |
| 31 | :+ => lambda {|a,b| a + b}, |
| 32 | :- => lambda {|a,b| a - b}, |
| 33 | :* => lambda {|a,b| a * b}, |
| 34 | :/ => lambda {|a,b| a / b}, |
| 35 | :"time-ms" => lambda {|| (Time.now.to_f * 1000).to_i}, |
| 36 | |
| 37 | :list => lambda {|*a| List.new a}, |
| 38 | :list? => lambda {|*a| a[0].is_a? List}, |
| 39 | :vector => lambda {|*a| Vector.new a}, |
| 40 | :vector? => lambda {|*a| a[0].is_a? Vector}, |
| 41 | :"hash-map" =>lambda {|*a| Hash[a.each_slice(2).to_a]}, |
| 42 | :map? => lambda {|a| a.is_a? Hash}, |
| 43 | :assoc => lambda {|*a| a[0].merge(Hash[a.drop(1).each_slice(2).to_a])}, |
| 44 | :dissoc => lambda {|*a| h = a[0].clone; a.drop(1).each{|k| h.delete k}; h}, |
| 45 | :get => lambda {|a,b| return nil if a == nil; a[b]}, |
| 46 | :contains? => lambda {|a,b| a.key? b}, |
| 47 | :keys => lambda {|a| List.new a.keys}, |
| 48 | :vals => lambda {|a| List.new a.values}, |
| 49 | |
| 50 | :sequential? => lambda {|a| sequential?(a)}, |
| 51 | :cons => lambda {|a,b| List.new(b.clone.insert(0,a))}, |
| 52 | :concat => lambda {|*a| List.new(a && a.reduce(:+) || [])}, |
| 53 | :nth => lambda {|a,b| raise "nth: index out of range" if b >= a.size; a[b]}, |
| 54 | :first => lambda {|a| a.nil? ? nil : a[0]}, |
| 55 | :rest => lambda {|a| List.new(a.nil? || a.size == 0 ? [] : a.drop(1))}, |
| 56 | :empty? => lambda {|a| a.size == 0}, |
| 57 | :count => lambda {|a| return 0 if a == nil; a.size}, |
| 58 | :apply => lambda {|*a| a[0][*a[1..-2].concat(a[-1])]}, |
| 59 | :map => lambda {|a,b| List.new(b.map {|e| a[e]})}, |
| 60 | |
| 61 | :conj => lambda {|*a| a[0].clone.conj(a.drop(1))}, |
| 62 | :seq => lambda {|a| a.nil? ? nil : a.size == 0 ? nil : a.seq}, |
| 63 | |
| 64 | :"with-meta" => lambda {|a,b| x = a.clone; x.meta = b; x}, |
| 65 | :meta => lambda {|a| a.meta}, |
| 66 | :atom => lambda {|a| Atom.new(a)}, |
| 67 | :atom? => lambda {|a| a.is_a? Atom}, |
| 68 | :deref => lambda {|a| a.val}, |
| 69 | :reset! => lambda {|a,b| a.val = b}, |
| 70 | :swap! => lambda {|*a| a[0].val = a[1][*[a[0].val].concat(a.drop(2))]}, |
| 71 | } |
| 72 | |