From f2fd93beb56c76e6e053666b51f886e5619061df Mon Sep 17 00:00:00 2001 From: rhysd Date: Thu, 4 Jun 2015 12:27:28 +0900 Subject: [PATCH] make pr_str() to Crisp::Printer class --- src/crisp/core.cr | 12 ++++---- src/crisp/env.cr | 5 ++-- src/crisp/interpreter.cr | 22 +++++++------- src/crisp/printer.cr | 63 +++++++++++++++++++++------------------- src/crisp/types.cr | 2 +- 5 files changed, 54 insertions(+), 50 deletions(-) diff --git a/src/crisp/core.cr b/src/crisp/core.cr index 337fe40..5ad38a3 100644 --- a/src/crisp/core.cr +++ b/src/crisp/core.cr @@ -42,21 +42,21 @@ module Crisp end end - def pr_str_(args) - args.map{|a| pr_str(a)}.join(" ") + def pr_str(args) + args.map{|a| Priter.new.print(a)}.join(" ") end def str(args) - args.map{|a| pr_str(a, false)}.join + args.map{|a| Printer.new(false).print(a)}.join end def prn(args) - puts self.pr_str_(args) + puts self.pr_str(args) nil end def println(args) - puts args.map{|a| pr_str(a, false)}.join(" ") + puts args.map{|a| Printer.new(false).print(a)}.join(" ") nil end @@ -366,7 +366,7 @@ module Crisp ">" => rel_op(:>) "<=" => rel_op(:<=) ">=" => rel_op(:>=) - "pr-str" => func(:pr_str_) + "pr-str" => func(:pr_str) "str" => func(:str) "prn" => func(:prn) "println" => func(:println) diff --git a/src/crisp/env.cr b/src/crisp/env.cr index bed7e36..b3f940d 100644 --- a/src/crisp/env.cr +++ b/src/crisp/env.cr @@ -6,7 +6,7 @@ module Crisp class Env property data - def initialize(@outer) + def initialize(@outer = nil) @data = {} of String => Crisp::Type end @@ -50,8 +50,7 @@ module Crisp def find(key) return self if @data.has_key? key - o = @outer - if o + if o = @outer o.find key else nil diff --git a/src/crisp/interpreter.cr b/src/crisp/interpreter.cr index 1df9418..c9ad86c 100644 --- a/src/crisp/interpreter.cr +++ b/src/crisp/interpreter.cr @@ -15,16 +15,16 @@ module Crisp class Interpreter def initialize(args) - @env = Crisp::Env.new nil + @env = Crisp::Env.new Crisp::NameSpace.each{|k,v| @curent_env.set(k, Crisp::Type.new(v))} @env.set("eval", Crisp::Type.new -> (args: Array(Crisp::Type)){ eval(args[0], @env) }) - rep "(def! not (fn* (a) (if a false true)))" - rep "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" - rep "(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))" - rep "(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))" - rep "(def! *host-language* \"crystal\")" + eval_string "(def! not (fn* (a) (if a false true)))" + eval_string "(def! load-file (fn* (f) (eval (read-string (str \"(do \" (slurp f) \")\")))))" + eval_string "(defmacro! cond (fn* (& xs) (if (> (count xs) 0) (list 'if (first xs) (if (> (count xs) 1) (nth xs 1) (throw \"odd number of forms to cond\")) (cons 'cond (rest (rest xs)))))))" + eval_string "(defmacro! or (fn* (& xs) (if (empty? xs) nil (if (= 1 (count xs)) (first xs) `(let* (or_FIXME ~(first xs)) (if or_FIXME or_FIXME (or ~@(rest xs))))))))" + eval_string "(def! *host-language* \"crystal\")" argv = Crisp::List.new @@ -35,6 +35,8 @@ module Crisp end @env.set("*ARGV*", Crisp::Type.new argv) + + @printer = Printer.new end def func_of(env, binds, body) @@ -259,22 +261,22 @@ module Crisp end def print(result) - pr_str(result, true) + @printer.print(result) end - private def rep(str) + def eval_string(str) print(eval(read(str), @env)) end def run(filename = nil) if filename - rep "(load-file \"#{filename}\")" + eval_string "(load-file \"#{filename}\")" return end while line = Readline.readline("Crisp> ", true) begin - puts rep(line) + puts eval_string(line) rescue e STDERR.puts e end diff --git a/src/crisp/printer.cr b/src/crisp/printer.cr index 8b7b742..237afea 100644 --- a/src/crisp/printer.cr +++ b/src/crisp/printer.cr @@ -1,38 +1,41 @@ require "./types" module Crisp - extend self + class Printer + def initialize(@print_readably = true) + end - def pr_str(value, print_readably = true) - 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| pr_str(v, print_readably) as String}.join(" ")})" - when Crisp::Vector then "[#{value.map{|v| pr_str(v, print_readably) 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 - "{#{value.map{|k, v| "#{pr_str(k, print_readably)} #{pr_str(v, print_readably)}" as String}.join(" ")}}" - when String - case - when value.empty?() - print_readably ? value.inspect : value - when value[0] == '\u029e' - ":#{value[1..-1]}" - else - print_readably ? value.inspect : value - end - when Crisp::Atom - "(atom #{pr_str(value.val, print_readably)})" - else - raise "invalid CrispType: #{value.to_s}" + 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| pr_str(v, @print_readably) as String}.join(" ")})" + when Crisp::Vector then "[#{value.map{|v| pr_str(v, @print_readably) 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 + "{#{value.map{|k, v| "#{pr_str(k, @print_readably)} #{pr_str(v, @print_readably)}" as String}.join(" ")}}" + when String + case + when value.empty?() + @print_readably ? value.inspect : value + when value[0] == '\u029e' + ":#{value[1..-1]}" + else + @print_readably ? value.inspect : value + end + when Crisp::Atom + "(atom #{pr_str(value.val, @print_readably)})" + else + raise "invalid CrispType: #{value.to_s}" + end end - end - def pr_str(t : Crisp::Type, print_readably = true) - pr_str(t.unwrap, print_readably) + (t.macro? ? " (macro)" : "") + def print(t : Crisp::Type) + print(t.unwrap, @print_readably) + (t.macro? ? " (macro)" : "") + end end end diff --git a/src/crisp/types.cr b/src/crisp/types.cr index 79a4d60..b96dac9 100644 --- a/src/crisp/types.cr +++ b/src/crisp/types.cr @@ -65,7 +65,7 @@ module Crisp end def to_s - pr_str(self) + Printer.new.print(self) end def dup