Browse Source

make pr_str() to Crisp::Printer class

master
rhysd 9 years ago
parent
commit
f2fd93beb5
5 changed files with 54 additions and 50 deletions
  1. +6
    -6
      src/crisp/core.cr
  2. +2
    -3
      src/crisp/env.cr
  3. +12
    -10
      src/crisp/interpreter.cr
  4. +33
    -30
      src/crisp/printer.cr
  5. +1
    -1
      src/crisp/types.cr

+ 6
- 6
src/crisp/core.cr View File

@ -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)

+ 2
- 3
src/crisp/env.cr View File

@ -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

+ 12
- 10
src/crisp/interpreter.cr View File

@ -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)
n">pr_str(result, true)
vi">@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

+ 33
- 30
src/crisp/printer.cr View File

@ -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 "<function>"
when Crisp::Closure then "<closure>"
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 "<function>"
when Crisp::Closure then "<closure>"
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

+ 1
- 1
src/crisp/types.cr View File

@ -65,7 +65,7 @@ module Crisp
end
def to_s
pr_str(self)
Printer.new.print(self)
end
def dup

Loading…
Cancel
Save