diff options
| author | Joel Martin <github@martintribe.org> | 2014-04-10 20:34:29 -0500 |
|---|---|---|
| committer | Joel Martin <github@martintribe.org> | 2014-04-10 20:34:29 -0500 |
| commit | f705f0fce151863091ad77753105f0d15270edec (patch) | |
| tree | 788691596846567abec1606131c972d24211604c | |
| parent | 712af9efbe15a9a65c25ab92ee2a49c8e749ed3d (diff) | |
| download | mal-f705f0fce151863091ad77753105f0d15270edec.tar.gz mal-f705f0fce151863091ad77753105f0d15270edec.zip | |
Ruby: step0, step1
| -rw-r--r-- | Makefile | 13 | ||||
| -rw-r--r-- | ruby/printer.rb | 23 | ||||
| -rw-r--r-- | ruby/reader.rb | 74 | ||||
| -rw-r--r-- | ruby/step0_repl.rb | 25 | ||||
| -rw-r--r-- | ruby/step1_read_print.rb | 32 | ||||
| -rw-r--r-- | ruby/types.rb | 5 |
6 files changed, 166 insertions, 6 deletions
@@ -8,7 +8,7 @@ MAL_IMPL = js # Settings # -IMPLS = bash c clojure cs java js make php python ps mal +IMPLS = bash c clojure cs java js make mal php ps python ruby step0 = step0_repl step1 = step1_read_print @@ -37,24 +37,25 @@ cs_STEP_TO_PROG = cs/$($(1)).exe java_STEP_TO_PROG = java/src/main/java/mal/$($(1)).java js_STEP_TO_PROG = js/$($(1)).js make_STEP_TO_PROG = make/$($(1)).mk +mal_STEP_TO_PROG = mal/$($(1)).mal php_STEP_TO_PROG = php/$($(1)).php -python_STEP_TO_PROG = python/$($(1)).py ps_STEP_TO_PROG = ps/$($(1)).ps -mal_STEP_TO_PROG = mal/$($(1)).mal +python_STEP_TO_PROG = python/$($(1)).py +ruby_STEP_TO_PROG = ruby/$($(1)).rb bash_RUNTEST = ../runtest.py $(4) ../$(1) -- bash ../$(2) $(5) c_RUNTEST = ../runtest.py $(4) ../$(1) -- ../$(2) $(5) clojure_RUNTEST = ../runtest.py $(4) ../$(1) -- lein with-profile +$(3) trampoline run $(5) cs_RUNTEST = ../runtest.py --redirect $(4) ../$(1) -- mono --debug ../$(2) --raw $(5) -#cs_RUNTEST = ../runtest.py --redirect $(4) ../$(1) -- mono --debug ../$(2) $(5) java_RUNTEST = ../runtest.py $(4) ../$(1) -- mvn -quiet exec:java -Dexec.mainClass="mal.$($(3))" -Dexec.args="--raw$(if $(5), $(5),)" js_RUNTEST = ../runtest.py $(4) ../$(1) -- node ../$(2) $(5) make_RUNTEST = ../runtest.py $(4) ../$(1) -- make -f ../$(2) $(5) +mal_RUNTEST = $(call $(MAL_IMPL)_RUNTEST,$(1),$(call $(MAL_IMPL)_STEP_TO_PROG,stepA),stepA,--start-timeout 30 --test-timeout 120,../$(2)) php_RUNTEST = ../runtest.py $(4) ../$(1) -- php ../$(2) $(5) -python_RUNTEST = ../runtest.py $(4) ../$(1) -- python ../$(2) $(5) ps_RUNTEST = ../runtest.py $(4) ../$(1) -- gs -q -dNODISPLAY ../$(2) $(5) -mal_RUNTEST = $(call $(MAL_IMPL)_RUNTEST,$(1),$(call $(MAL_IMPL)_STEP_TO_PROG,stepA),stepA,--start-timeout 30 --test-timeout 120,../$(2)) +python_RUNTEST = ../runtest.py $(4) ../$(1) -- python ../$(2) $(5) +ruby_RUNTEST = ../runtest.py $(4) ../$(1) -- ruby ../$(2) $(5) # Derived lists diff --git a/ruby/printer.rb b/ruby/printer.rb new file mode 100644 index 0000000..2d46e07 --- /dev/null +++ b/ruby/printer.rb @@ -0,0 +1,23 @@ +require "types" + +def _pr_str(obj, print_readably=true) + _r = print_readably + return case obj + when List + "(" + obj.map{|x| _pr_str(x, _r)}.join(" ") + ")" + when Vector + "[" + obj.map{|x| _pr_str(x, _r)}.join(" ") + "]" + when String + if _r + "\"" + obj.gsub(/\\/, "\\\\") \ + .gsub(/"/, "\\\\\"") \ + .gsub(/\n/, "\\\\n") + "\"" + else + obj + end + when nil + "nil" + else + obj.to_s + end +end diff --git a/ruby/reader.rb b/ruby/reader.rb new file mode 100644 index 0000000..d224e9c --- /dev/null +++ b/ruby/reader.rb @@ -0,0 +1,74 @@ +require "types" + +class Reader + def initialize(tokens) + @position = 0 + @tokens = tokens + end + def peek + return @tokens[@position] + end + def next + @position += 1 + return @tokens[@position-1] + end +end + + +def tokenize(str) + re = /[\s,]*(~@|[\[\]{}()'`~^@]|"(?:\\.|[^\\"])*"|;.*|[^\s\[\]{}('"`,;)]*)/ + return str.scan(re).map{|m| m[0]}.select{|m| m != ""} +end + +def parse_str(t) + return t[1..-2].gsub(/\\"/, "\"").gsub(/\\n/, "\n") +end + +def read_atom(rdr) + token = rdr.next + return case token + when /^-?[0-9]+$/ then token.to_i # integer + when /^-?[0-9][0-9.]*$/ then token.to_f # float + when /^"/ then parse_str(token) # string + when "nil" then nil + when "true" then true + when "false" then false + else token.to_sym # symbol + end +end + +def read_list(rdr, klass, start="(", last =")") + ast = klass.new + token = rdr.next() + if token != start + raise "expected '" + start + "'" + end + while (token = rdr.peek) != last + if not token + raise "expected '" + last + "', got EOF" + end + ast.push(read_form(rdr)) + end + rdr.next + return ast +end + +def read_form(rdr) + token = rdr.peek + return case rdr.peek + when ";" then nil + when "(" then read_list(rdr, List, "(", ")") + when ")" then raise "unexpected ')'" + when "[" then read_list(rdr, Vector, "[", "]") + when "]" then raise "unexpected ']'" + when "{" then raise "unexpected '{'" + when "}" then raise "unexpected '}'" + else read_atom(rdr) + end +end + +def read_str(str) + tokens = tokenize(str) + return read_form(Reader.new(tokens)) +end + diff --git a/ruby/step0_repl.rb b/ruby/step0_repl.rb new file mode 100644 index 0000000..dd32b27 --- /dev/null +++ b/ruby/step0_repl.rb @@ -0,0 +1,25 @@ +require "readline" + +# read +def READ(str) + return str +end + +# eval +def EVAL(ast, env) + return ast +end + +# print +def PRINT(exp) + return exp +end + +# repl +def REP(str) + return PRINT(EVAL(READ(str), {})) +end + +while line = Readline.readline("user> ", true) + puts REP(line) +end diff --git a/ruby/step1_read_print.rb b/ruby/step1_read_print.rb new file mode 100644 index 0000000..20dd450 --- /dev/null +++ b/ruby/step1_read_print.rb @@ -0,0 +1,32 @@ +require "readline" +require "types" +require "reader" +require "printer" + +# read +def READ(str) + return read_str(str) +end + +# eval +def EVAL(ast, env) + return ast +end + +# print +def PRINT(exp) + return _pr_str(exp, true) +end + +# repl +def REP(str) + return PRINT(EVAL(READ(str), {})) +end + +while line = Readline.readline("user> ", true) + begin + puts REP(line) + rescue Exception => e + puts "Error: %{e}" + end +end diff --git a/ruby/types.rb b/ruby/types.rb new file mode 100644 index 0000000..a7ce285 --- /dev/null +++ b/ruby/types.rb @@ -0,0 +1,5 @@ +class List < Array +end + +class Vector < Array +end |
