From ebd767a57d7c5603f0bc88be4b724699ca0f5d49 Mon Sep 17 00:00:00 2001 From: rhysd Date: Thu, 4 Jun 2015 14:31:45 +0900 Subject: [PATCH] fix code style and missing module specification --- src/crisp/core.cr | 72 +++++++-------- src/crisp/env.cr | 10 +-- src/crisp/error.cr | 4 +- src/crisp/interpreter.cr | 186 +++++++++++++++++++-------------------- src/crisp/printer.cr | 37 ++++---- src/crisp/reader.cr | 22 ++--- 6 files changed, 165 insertions(+), 166 deletions(-) diff --git a/src/crisp/core.cr b/src/crisp/core.cr index aaaa01c..b1845ca 100644 --- a/src/crisp/core.cr +++ b/src/crisp/core.cr @@ -12,7 +12,7 @@ module Crisp macro calc_op(op) -> (args : Array(Crisp::Type)) { x, y = args[0].unwrap, args[1].unwrap - eval_error "invalid arguments for binary operator {{op.id}}" unless x.is_a?(Int32) && y.is_a?(Int32) + Crisp.eval_error "invalid arguments for binary operator {{op.id}}" unless x.is_a?(Int32) && y.is_a?(Int32) Crisp::Type.new(x {{op.id}} y) } end @@ -38,7 +38,7 @@ module Crisp when Nil 0 else - eval_error "invalid argument for function 'count'" + Crisp.eval_error "invalid argument for function 'count'" end end @@ -62,38 +62,38 @@ module Crisp def read_string(args) head = args.first.unwrap - eval_error "argument of read-str must be string" unless head.is_a? String + Crisp.eval_error "argument of read-str must be string" unless head.is_a? String read_str head end def slurp(args) head = args.first.unwrap - eval_error "argument of slurp must be string" unless head.is_a? String + Crisp.eval_error "argument of slurp must be string" unless head.is_a? String begin File.read head rescue e : Errno - eval_error "no such file" + Crisp.eval_error "no such file" end end def cons(args) head, tail = args[0] as Crisp::Type, args[1].unwrap - eval_error "2nd arg of cons must be list" unless tail.is_a? Array + Crisp.eval_error "2nd arg of cons must be list" unless tail.is_a? Array ([head] + tail).to_crisp_value end def concat(args) args.each_with_object(Crisp::List.new) do |arg, list| a = arg.unwrap - eval_error "arguments of concat must be list" unless a.is_a?(Array) + Crisp.eval_error "arguments of concat must be list" unless a.is_a?(Array) a.each{|e| list << e} end end def nth(args) a0, a1 = args[0].unwrap, args[1].unwrap - eval_error "1st argument of nth must be list or vector" unless a0.is_a? Array - eval_error "2nd argument of nth must be integer" unless a1.is_a? Int32 + Crisp.eval_error "1st argument of nth must be list or vector" unless a0.is_a? Array + Crisp.eval_error "2nd argument of nth must be integer" unless a1.is_a? Int32 a0[a1] end @@ -101,7 +101,7 @@ module Crisp a0 = args[0].unwrap return nil if a0.nil? - eval_error "1st argument of first must be list or vector or nil" unless a0.is_a? Array + Crisp.eval_error "1st argument of first must be list or vector or nil" unless a0.is_a? Array a0.empty? ? nil : a0.first end @@ -109,18 +109,18 @@ module Crisp a0 = args[0].unwrap return Crisp::List.new if a0.nil? - eval_error "1st argument of first must be list or vector or nil" unless a0.is_a? Array + Crisp.eval_error "1st argument of first must be list or vector or nil" unless a0.is_a? Array return Crisp::List.new if a0.empty? a0[1..-1].to_crisp_value end def apply(args) - eval_error "apply must take at least 2 arguments" unless args.size >= 2 + Crisp.eval_error "apply must take at least 2 arguments" unless args.size >= 2 head = args.first.unwrap last = args.last.unwrap - eval_error "last argument of apply must be list or vector" unless last.is_a? Array + Crisp.eval_error "last argument of apply must be list or vector" unless last.is_a? Array case head when Crisp::Closure @@ -128,7 +128,7 @@ module Crisp when Crisp::Func head.call(args[1..-2] + last) else - eval_error "1st argument of apply must be function or closure" + Crisp.eval_error "1st argument of apply must be function or closure" end end @@ -136,12 +136,12 @@ module Crisp func = args.first.unwrap list = args[1].unwrap - eval_error "2nd argument of map must be list or vector" unless list.is_a? Array + Crisp.eval_error "2nd argument of map must be list or vector" unless list.is_a? Array f = case func when Crisp::Closure then func.fn when Crisp::Func then func - else eval_error "1st argument of map must be function" + else Crisp.eval_error "1st argument of map must be function" end list.each_with_object(Crisp::List.new) do |elem, mapped| @@ -169,13 +169,13 @@ module Crisp def symbol(args) head = args.first.unwrap - eval_error "1st argument of symbol function must be string" unless head.is_a? String + Crisp.eval_error "1st argument of symbol function must be string" unless head.is_a? String Crisp::Symbol.new head end def keyword(args) head = args.first.unwrap - eval_error "1st argument of symbol function must be string" unless head.is_a? String + Crisp.eval_error "1st argument of symbol function must be string" unless head.is_a? String "\u029e" + head end @@ -193,11 +193,11 @@ module Crisp end def hash_map(args) - eval_error "hash-map must take even number of arguments" unless args.size.even? + Crisp.eval_error "hash-map must take even number of arguments" unless args.size.even? map = Crisp::HashMap.new args.each_slice(2) do |kv| k = kv[0].unwrap - eval_error "key must be string" unless k.is_a? String + Crisp.eval_error "key must be string" unless k.is_a? String map[k] = kv[1] end map @@ -209,15 +209,15 @@ module Crisp def assoc(args) head = args.first.unwrap - eval_error "1st argument of assoc must be hashmap" unless head.is_a? Crisp::HashMap - eval_error "assoc must take a list and even number of arguments" unless (args.size - 1).even? + Crisp.eval_error "1st argument of assoc must be hashmap" unless head.is_a? Crisp::HashMap + Crisp.eval_error "assoc must take a list and even number of arguments" unless (args.size - 1).even? map = Crisp::HashMap.new head.each{|k, v| map[k] = v} args[1..-1].each_slice(2) do |kv| k = kv[0].unwrap - eval_error "key must be string" unless k.is_a? String + Crisp.eval_error "key must be string" unless k.is_a? String map[k] = kv[1] end @@ -226,14 +226,14 @@ module Crisp def dissoc(args) head = args.first.unwrap - eval_error "1st argument of assoc must be hashmap" unless head.is_a? Crisp::HashMap + Crisp.eval_error "1st argument of assoc must be hashmap" unless head.is_a? Crisp::HashMap map = Crisp::HashMap.new head.each{|k,v| map[k] = v} args[1..-1].each do |arg| key = arg.unwrap - eval_error "key must be string" unless key.is_a? String + Crisp.eval_error "key must be string" unless key.is_a? String map.delete key end @@ -243,7 +243,7 @@ module Crisp def get(args) a0, a1 = args[0].unwrap, args[1].unwrap return nil unless a0.is_a? Crisp::HashMap - eval_error "2nd argument of get must be string" unless a1.is_a? String + Crisp.eval_error "2nd argument of get must be string" unless a1.is_a? String # a0[a1]? isn't available because type ofa0[a1] is infered NoReturn a0.has_key?(a1) ? a0[a1] : nil @@ -251,20 +251,20 @@ module Crisp def contains?(args) a0, a1 = args[0].unwrap, args[1].unwrap - eval_error "1st argument of get must be hashmap" unless a0.is_a? Crisp::HashMap - eval_error "2nd argument of get must be string" unless a1.is_a? String + Crisp.eval_error "1st argument of get must be hashmap" unless a0.is_a? Crisp::HashMap + Crisp.eval_error "2nd argument of get must be string" unless a1.is_a? String a0.has_key? a1 end def keys(args) head = args.first.unwrap - eval_error "1st argument of assoc must be hashmap" unless head.is_a? Crisp::HashMap + Crisp.eval_error "1st argument of assoc must be hashmap" unless head.is_a? Crisp::HashMap head.keys.each_with_object(Crisp::List.new){|e,l| l << Crisp::Type.new(e)} end def vals(args) head = args.first.unwrap - eval_error "1st argument of assoc must be hashmap" unless head.is_a? Crisp::HashMap + Crisp.eval_error "1st argument of assoc must be hashmap" unless head.is_a? Crisp::HashMap head.values.to_crisp_value end @@ -274,7 +274,7 @@ module Crisp def readline(args) head = args.first.unwrap - eval_error "1st argument of readline must be string" unless head.is_a? String + Crisp.eval_error "1st argument of readline must be string" unless head.is_a? String Readline.readline head end @@ -299,19 +299,19 @@ module Crisp def deref(args) head = args.first.unwrap - eval_error "1st argument of deref must be atom" unless head.is_a? Crisp::Atom + Crisp.eval_error "1st argument of deref must be atom" unless head.is_a? Crisp::Atom head.val end def reset!(args) head = args.first.unwrap - eval_error "1st argument of reset! must be atom" unless head.is_a? Crisp::Atom + Crisp.eval_error "1st argument of reset! must be atom" unless head.is_a? Crisp::Atom head.val = args[1] end def swap!(args) atom = args.first.unwrap - eval_error "1st argument of swap! must be atom" unless atom.is_a? Crisp::Atom + Crisp.eval_error "1st argument of swap! must be atom" unless atom.is_a? Crisp::Atom a = [atom.val] + args[2..-1] @@ -322,7 +322,7 @@ module Crisp when Crisp::Closure atom.val = func.fn.call a else - eval_error "2nd argumetn of swap! must be function" + Crisp.eval_error "2nd argumetn of swap! must be function" end end @@ -334,7 +334,7 @@ module Crisp when Crisp::Vector (seq + args[1..-1]).to_crisp_value(Crisp::Vector) else - eval_error "1st argument of conj must be list or vector" + Crisp.eval_error "1st argument of conj must be list or vector" end end diff --git a/src/crisp/env.cr b/src/crisp/env.cr index b3f940d..244c48c 100644 --- a/src/crisp/env.cr +++ b/src/crisp/env.cr @@ -13,18 +13,18 @@ module Crisp def initialize(@outer, binds, exprs : Array(Crisp::Type)) @data = {} of String => Crisp::Type - eval_error "binds must be list or vector" unless binds.is_a? Array + Crisp.eval_error "binds must be list or vector" unless binds.is_a? Array # Note: # Array#zip() can't be used because overload resolution failed (0...binds.size).each do |idx| sym = binds[idx].unwrap - eval_error "bind name must be symbol" unless sym.is_a? Crisp::Symbol + Crisp.eval_error "bind name must be symbol" unless sym.is_a? Crisp::Symbol if sym.str == "&" - eval_error "missing variable parameter name" if binds.size == idx + Crisp.eval_error "missing variable parameter name" if binds.size == idx next_param = binds[idx+1].unwrap - eval_error "bind name must be symbol" unless next_param.is_a? Crisp::Symbol + Crisp.eval_error "bind name must be symbol" unless next_param.is_a? Crisp::Symbol var_args = Crisp::List.new exprs[idx..-1].each{|e| var_args << e} if idx < exprs.size @data[next_param.str] = Crisp::Type.new var_args @@ -59,7 +59,7 @@ module Crisp def get(key) e = find key - eval_error "'#{key}' not found" unless e + Crisp.eval_error "'#{key}' not found" unless e e.data[key] end end diff --git a/src/crisp/error.cr b/src/crisp/error.cr index 5d02374..c715676 100644 --- a/src/crisp/error.cr +++ b/src/crisp/error.cr @@ -14,11 +14,11 @@ module Crisp end end - def self.eval_error(msg) + def eval_error(msg) raise Crisp::EvalException.new msg end - def self.parse_error(msg) + def parse_error(msg) raise Crisp::ParseException.new msg end end diff --git a/src/crisp/interpreter.cr b/src/crisp/interpreter.cr index 93931a6..52e6108 100644 --- a/src/crisp/interpreter.cr +++ b/src/crisp/interpreter.cr @@ -40,90 +40,90 @@ module Crisp end def func_of(env, binds, body) - -> (args : Array(Crisp::Type)) { - new_env = Crisp::Env.new(env, binds, args) - eval(body, new_env) - } as Crisp::Func + -> (args : Array(Crisp::Type)) { + new_env = Crisp::Env.new(env, binds, args) + eval(body, new_env) + } as Crisp::Func end def eval_ast(ast, env) - return ast.map{|n| eval(n, env) as Crisp::Type} if ast.is_a? Array + return ast.map{|n| eval(n, env) as Crisp::Type} if ast.is_a? Array - val = ast.unwrap + val = ast.unwrap - Crisp::Type.new case val - when Crisp::Symbol + Crisp::Type.new case val + when Crisp::Symbol if e = env.get(val.str) e else - eval_error "'#{val.str}' not found" + Crisp.eval_error "'#{val.str}' not found" end - when Crisp::List + when Crisp::List val.each_with_object(Crisp::List.new){|n, l| l << eval(n, env)} - when Crisp::Vector + when Crisp::Vector val.each_with_object(Crisp::Vector.new){|n, l| l << eval(n, env)} - when Crisp::HashMap + when Crisp::HashMap new_map = Crisp::HashMap.new val.each{|k, v| new_map[k] = eval(v, env)} new_map - else + else val - end + end end def read(str) - read_str str + read_str str end macro pair?(list) - {{list}}.is_a?(Array) && !{{list}}.empty? + {{list}}.is_a?(Array) && !{{list}}.empty? end def quasiquote(ast) - list = ast.unwrap + list = ast.unwrap - unless pair?(list) - return Crisp::Type.new( - Crisp::List.new << gen_type(Crisp::Symbol, "quote") << ast - ) - end + unless pair?(list) + return Crisp::Type.new( + Crisp::List.new << gen_type(Crisp::Symbol, "quote") << ast + ) + end - head = list.first.unwrap + head = list.first.unwrap - case - # ("unquote" ...) - when head.is_a?(Crisp::Symbol) && head.str == "unquote" + case + # ("unquote" ...) + when head.is_a?(Crisp::Symbol) && head.str == "unquote" list[1] - # (("splice-unquote" ...) ...) - when pair?(head) && (arg0 = head.first.unwrap).is_a?(Crisp::Symbol) && arg0.str == "splice-unquote" + # (("splice-unquote" ...) ...) + when pair?(head) && (arg0 = head.first.unwrap).is_a?(Crisp::Symbol) && arg0.str == "splice-unquote" tail = Crisp::Type.new list[1..-1].to_crisp_value Crisp::Type.new( - Crisp::List.new << gen_type(Crisp::Symbol, "concat") << head[1] << quasiquote(tail) + Crisp::List.new << gen_type(Crisp::Symbol, "concat") << head[1] << quasiquote(tail) ) - else + else tail = Crisp::Type.new list[1..-1].to_crisp_value Crisp::Type.new( - Crisp::List.new << gen_type(Crisp::Symbol, "cons") << quasiquote(list.first) << quasiquote(tail) + Crisp::List.new << gen_type(Crisp::Symbol, "cons") << quasiquote(list.first) << quasiquote(tail) ) - end + end end def macro_call?(ast, env) - list = ast.unwrap - return false unless list.is_a? Crisp::List - return false if list.empty? + list = ast.unwrap + return false unless list.is_a? Crisp::List + return false if list.empty? - sym = list.first.unwrap - return false unless sym.is_a? Crisp::Symbol + sym = list.first.unwrap + return false unless sym.is_a? Crisp::Symbol - func = env.find(sym.str).try(&.data[sym.str]) - return false unless func && func.macro? + func = env.find(sym.str).try(&.data[sym.str]) + return false unless func && func.macro? - true + true end def macroexpand(ast, env) - while macro_call?(ast, env) + while macro_call?(ast, env) # Already checked in macro_call? list = ast.unwrap as Crisp::List @@ -132,41 +132,41 @@ module Crisp case func when Crisp::Func - ast = func.call(list[1..-1]) + ast = func.call(list[1..-1]) when Crisp::Closure - ast = func.fn.call(list[1..-1]) + ast = func.fn.call(list[1..-1]) else - eval_error "macro '#{func_sym.str}' must be function: #{ast}" - end + Crisp.eval_error "macro '#{func_sym.str}' must be function: #{ast}" end + end - ast + ast end macro invoke_list(l, env) - f = eval({{l}}.first, {{env}}).unwrap - args = eval_ast({{l}}[1..-1], {{env}}) as Array + f = eval({{l}}.first, {{env}}).unwrap + args = eval_ast({{l}}[1..-1], {{env}}) as Array - case f - when Crisp::Closure + case f + when Crisp::Closure ast = f.ast {{env}} = Crisp::Env.new(f.env, f.params, args) next # TCO - when Crisp::Func + when Crisp::Func return f.call args - else - eval_error "expected function as the first argument: #{f}" - end + else + Crisp.eval_error "expected function as the first argument: #{f}" + end end def debug(ast) - puts print(ast).colorize.red + puts print(ast).colorize.red end def eval(ast, env) - # 'next' in 'do...end' has a bug in crystal 0.7.1 - # https://github.com/manastech/crystal/issues/659 - while true + # 'next' in 'do...end' has a bug in crystal 0.7.1 + # https://github.com/manastech/crystal/issues/659 + while true return eval_ast(ast, env) unless ast.unwrap.is_a? Crisp::List ast = macroexpand(ast, env) @@ -181,63 +181,63 @@ module Crisp return invoke_list(list, env) unless head.is_a? Crisp::Symbol return Crisp::Type.new case head.str - when "def!" - eval_error "wrong number of argument for 'def!'" unless list.size == 3 + when "def!" + Crisp.eval_error "wrong number of argument for 'def!'" unless list.size == 3 a1 = list[1].unwrap - eval_error "1st argument of 'def!' must be symbol: #{a1}" unless a1.is_a? Crisp::Symbol + Crisp.eval_error "1st argument of 'def!' must be symbol: #{a1}" unless a1.is_a? Crisp::Symbol env.set(a1.str, eval(list[2], env)) - when "let*" - eval_error "wrong number of argument for 'def!'" unless list.size == 3 + when "let*" + Crisp.eval_error "wrong number of argument for 'def!'" unless list.size == 3 bindings = list[1].unwrap - eval_error "1st argument of 'let*' must be list or vector" unless bindings.is_a? Array - eval_error "size of binding list must be even" unless bindings.size.even? + Crisp.eval_error "1st argument of 'let*' must be list or vector" unless bindings.is_a? Array + Crisp.eval_error "size of binding list must be even" unless bindings.size.even? new_env = Crisp::Env.new env bindings.each_slice(2) do |binding| - key, value = binding - name = key.unwrap - eval_error "name of binding must be specified as symbol #{name}" unless name.is_a? Crisp::Symbol - new_env.set(name.str, eval(value, new_env)) + key, value = binding + name = key.unwrap + Crisp.eval_error "name of binding must be specified as symbol #{name}" unless name.is_a? Crisp::Symbol + new_env.set(name.str, eval(value, new_env)) end ast, env = list[2], new_env next # TCO - when "do" + when "do" if list.empty? - ast = Crisp::Type.new nil - next + ast = Crisp::Type.new nil + next end eval_ast(list[1..-2].to_crisp_value, env) ast = list.last next # TCO - when "if" + when "if" ast = unless eval(list[1], env).unwrap - list.size >= 4 ? list[3] : Crisp::Type.new(nil) + list.size >= 4 ? list[3] : Crisp::Type.new(nil) else - list[2] + list[2] end next # TCO - when "fn*" + when "fn*" params = list[1].unwrap unless params.is_a? Array - eval_error "'fn*' parameters must be list or vector: #{params}" + Crisp.eval_error "'fn*' parameters must be list or vector: #{params}" end Crisp::Closure.new(list[2], params, env, func_of(env, params, list[2])) - when "quote" + when "quote" list[1] - when "quasiquote" + when "quasiquote" ast = quasiquote list[1] next # TCO - when "defmacro!" - eval_error "wrong number of argument for 'defmacro!'" unless list.size == 3 + when "defmacro!" + Crisp.eval_error "wrong number of argument for 'defmacro!'" unless list.size == 3 a1 = list[1].unwrap - eval_error "1st argument of 'defmacro!' must be symbol: #{a1}" unless a1.is_a? Crisp::Symbol + Crisp.eval_error "1st argument of 'defmacro!' must be symbol: #{a1}" unless a1.is_a? Crisp::Symbol env.set(a1.str, eval(list[2], env).tap{|n| n.is_macro = true}) - when "macroexpand" + when "macroexpand" macroexpand(list[1], env) - when "try*" + when "try*" catch_list = list[2].unwrap return eval(list[1], env) unless catch_list.is_a? Crisp::List @@ -246,22 +246,22 @@ module Crisp return eval(list[1], env) unless catch_head.str == "catch*" begin - eval(list[1], env) + eval(list[1], env) rescue e : Crisp::RuntimeException - new_env = Crisp::Env.new(env, [catch_list[1]], [e.thrown]) - eval(catch_list[2], new_env) + new_env = Crisp::Env.new(env, [catch_list[1]], [e.thrown]) + eval(catch_list[2], new_env) rescue e - new_env = Crisp::Env.new(env, [catch_list[1]], [Crisp::Type.new e.message]) - eval(catch_list[2], new_env) + new_env = Crisp::Env.new(env, [catch_list[1]], [Crisp::Type.new e.message]) + eval(catch_list[2], new_env) end - else + else invoke_list(list, env) - end - end + end + end end def print(result) - @printer.print(result) + @printer.print(result) end def eval_string(str) diff --git a/src/crisp/printer.cr b/src/crisp/printer.cr index 1b0716e..20fe031 100644 --- a/src/crisp/printer.cr +++ b/src/crisp/printer.cr @@ -6,36 +6,35 @@ module Crisp end def print(value) - case value - when Nil then "nil" - when Bool then value.to_s - when Int32 then value.to_s - when Crisp::List then "(#{value.map{|v| print(v) as String}.join(" ")})" - when Crisp::Vector then "[#{value.map{|v| print(v) as String}.join(" ")}]" - when Crisp::Symbol then value.str.to_s - when Crisp::Func then "" - when Crisp::Closure then "" - when Crisp::HashMap - # step1_read_print.cr requires specifying type + case value + when Nil then "nil" + when Bool then value.to_s + when Int32 then value.to_s + when Crisp::List then "(#{value.map{|v| print(v) as String}.join(" ")})" + when Crisp::Vector then "[#{value.map{|v| print(v) as String}.join(" ")}]" + when Crisp::Symbol then value.str.to_s + when Crisp::Func then "" + when Crisp::Closure then "" + when Crisp::HashMap "{#{value.map{|k, v| "#{print(k)} #{print(v)}"}.join(" ")}}" - when String + when String case when value.empty?() - @print_readably ? value.inspect : value + @print_readably ? value.inspect : value when value[0] == '\u029e' - ":#{value[1..-1]}" + ":#{value[1..-1]}" else - @print_readably ? value.inspect : value + @print_readably ? value.inspect : value end - when Crisp::Atom + when Crisp::Atom "(atom #{print(value.val)})" - else + else raise "invalid CrispType: #{value.to_s}" - end + end end def print(t : Crisp::Type) - print(t.unwrap) + (t.macro? ? " (macro)" : "") + print(t.unwrap) + (t.macro? ? " (macro)" : "") end end end diff --git a/src/crisp/reader.cr b/src/crisp/reader.cr index 9dcdb1f..4fc5ef0 100644 --- a/src/crisp/reader.cr +++ b/src/crisp/reader.cr @@ -32,12 +32,12 @@ module Crisp def read_sequence(init, open, close) token = self.next - parse_error "expected '#{open}', got EOF" unless token - parse_error "expected '#{open}', got #{token}" unless token[0] == open + Crisp.parse_error "expected '#{open}', got EOF" unless token + Crisp.parse_error "expected '#{open}', got #{token}" unless token[0] == open loop do token = peek - parse_error "expected '#{close}', got EOF" unless token + Crisp.parse_error "expected '#{close}', got EOF" unless token break if token[0] == close init << read_form @@ -59,7 +59,7 @@ module Crisp def read_hashmap types = read_sequence([] of Crisp::Type, '{', '}') - parse_error "odd number of elements for hash-map: #{types.size}" if types.size.odd? + Crisp.parse_error "odd number of elements for hash-map: #{types.size}" if types.size.odd? map = Crisp::HashMap.new types.each_slice(2) do |kv| @@ -68,7 +68,7 @@ module Crisp when String map[k] = v else - parse_error("key of hash-map must be string or keyword") + Crisp.parse_error("key of hash-map must be string or keyword") end end @@ -77,7 +77,7 @@ module Crisp def read_atom token = self.next - parse_error "expected Atom but got EOF" unless token + Crisp.parse_error "expected Atom but got EOF" unless token Crisp::Type.new case when token =~ /^-?\d+$/ then token.to_i @@ -97,16 +97,16 @@ module Crisp def read_form token = peek - parse_error "unexpected EOF" unless token - parse_error "unexpected comment" if token[0] == ';' + Crisp.parse_error "unexpected EOF" unless token + Crisp.parse_error "unexpected comment" if token[0] == ';' Crisp::Type.new case token when "(" then read_list - when ")" then parse_error "unexpected ')'" + when ")" then Crisp.parse_error "unexpected ')'" when "[" then read_vector - when "]" then parse_error "unexpected ']'" + when "]" then Crisp.parse_error "unexpected ']'" when "{" then read_hashmap - when "}" then parse_error "unexpected '}'" + when "}" then Crisp.parse_error "unexpected '}'" when "'" then self.next; list_of("quote") when "`" then self.next; list_of("quasiquote") when "~" then self.next; list_of("unquote")