From d89ab8f1b1b28a166592c349157966f74061caf4 Mon Sep 17 00:00:00 2001 From: sjs Date: Sun, 24 May 2009 13:01:45 -0700 Subject: [PATCH] [NEW] test dir and better tests --- build.rb | 82 +++++++++++++++++++++++++++++++++++++++++++ test/Makefile | 53 ++++++++++++++++++++++++++++ test/test.rb | 16 +++++++++ test/test_big.code | 65 ++++++++++++++++++++++++++++++++++ test/test_break.code | 10 ++++++ test/test_do.code | 5 +++ test/test_eq.code | 13 +++++++ test/test_for.code | 7 ++++ test/test_ge.code | 19 ++++++++++ test/test_gt.code | 19 ++++++++++ test/test_if.code | 13 +++++++ test/test_le.code | 19 ++++++++++ test/test_lt.code | 19 ++++++++++ test/test_neq.code | 13 +++++++ test/test_print.code | 8 +++++ test/test_repeat.code | 11 ++++++ test/test_until.code | 5 +++ test/test_while.code | 6 ++++ test/testi.code | 1 + test/testi.rb | 25 +++++++++++++ 20 files changed, 409 insertions(+) create mode 100755 build.rb create mode 100644 test/Makefile create mode 100755 test/test.rb create mode 100644 test/test_big.code create mode 100644 test/test_break.code create mode 100644 test/test_do.code create mode 100644 test/test_eq.code create mode 100644 test/test_for.code create mode 100644 test/test_ge.code create mode 100644 test/test_gt.code create mode 100644 test/test_if.code create mode 100644 test/test_le.code create mode 100644 test/test_lt.code create mode 100644 test/test_neq.code create mode 100644 test/test_print.code create mode 100644 test/test_repeat.code create mode 100644 test/test_until.code create mode 100644 test/test_while.code create mode 100644 test/testi.code create mode 100644 test/testi.rb diff --git a/build.rb b/build.rb new file mode 100755 index 0000000..231a931 --- /dev/null +++ b/build.rb @@ -0,0 +1,82 @@ +#!/usr/bin/env ruby + +ROOT = __FILE__.sub(/\/build\.rb$/, '') unless defined? ROOT + +require 'compiler' + +def main + filename = ARGV[0].to_s + raise "can't read #{filename}" unless File.readable?(filename) +end + + +def error(msg) STDERR.puts(msg) end + +# name part (filename minus extension) +def base(filename) + filename.sub(/\.[^.]*$/, '') +end + +def interpolate(templatefile, data) + template = File.read(templatefile) + data.inject(template) do |template, mapping| + token, replacement = *mapping + template.sub("{#{token}}", replacement) + end +end + +# input: filename +# output: filename +def compile(filename) + data, bss, code = nil + File.open(filename, 'r') do |input| + compiler = Compiler.new(input) + data, bss, code = compiler.compile + end + asm = interpolate("#{ROOT}/template.asm", + :data => data, :bss => bss, :code => code) + outfile = "#{base(filename)}.asm" + File.open(outfile, 'w') { |out| out.puts(asm) } + return outfile + +rescue ParseError => e + error("[error] #{e.message}") + error("[context] #{e.context}") + # error("Aborting!") + error(e.caller) + exit(1) +end + +# assemble using nasm, return resulting filename. +def asm(filename) + f = base(filename) + outfile = "#{f}.o" + output = `nasm -f elf -g -o #{outfile} #{filename}` + if $?.exitstatus != 0 + raise "nasm failed: #{$?.exitstatus}", output + end + return outfile +end + +# link with ld, return resulting filename. +def link(filename) + f = base(filename) + output = `ld -o #{f} #{filename}` + if $?.exitstatus != 0 + raise "ld failed: #{$?.exitstatus}", output + end + `chmod +x #{f}` + return f +end + +def build(filename) + link( asm( compile(filename) ) ) +end + +def run(filename) + filename = "./#{filename}" unless filename.include?('/') + system(filename) + return $?.exitstatus +end + +main if $0 == __FILE__ diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..474d305 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,53 @@ +all: lt gt ge le eq neq if while until repeat for do break print + @echo -n + +lt: test.rb test_lt.code + @./test.rb lt + +gt: test.rb test_gt.code + @./test.rb gt + +ge: test.rb test_ge.code + @./test.rb ge + +le: test.rb test_le.code + @./test.rb le + +eq: test.rb test_eq.code + @./test.rb eq + +neq: test.rb test_neq.code + @./test.rb neq + +if: test.rb test_if.code + @./test.rb if + +while: test.rb test_while.code + @./test.rb while + +until: test.rb test_until.code + @./test.rb until + +repeat: test.rb test_repeat.code + @./test.rb repeat + +for: test.rb test_for.code + @./test.rb for + +do: test.rb test_do.code + @./test.rb do + +break: test.rb test_break.code + @./test.rb break + +print: test.rb test_print.code + @./test.rb print + +big_test: test.rb big_test.code + @./test.rb big + +clean: + @rm -f test*.asm test*.o + @rm -f test_big test_lt test_gt test_ge test_le test_eq test_neq + @rm -f test_while test_if test_until test_repeat test_do + @rm -f test_for test_break test_print diff --git a/test/test.rb b/test/test.rb new file mode 100755 index 0000000..16cf0ef --- /dev/null +++ b/test/test.rb @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby + +ROOT = Dir.pwd.sub(/\/test.*$/, '') +$LOAD_PATH << ROOT + +require 'build' + +def main + func = ARGV[0].to_s + print "testing #{func} ... " + success = run( build("test_#{func}.code") ) + puts success == 0 ? "pass" : "FAIL! (#{success})" + exit(success) +end + +main if $0 == __FILE__ diff --git a/test/test_big.code b/test/test_big.code new file mode 100644 index 0000000..02135a3 --- /dev/null +++ b/test/test_big.code @@ -0,0 +1,65 @@ +a=1 +print a +aa=10 +print aa +somethinglong=65536 +print somethinglong +x=5*(3-5) +print x +c=1- -a +print c +g=1* -1 +print g +h=x*2+2 +print h +j=h-27/9 +k=j-8/2 +m=k-4*(5+5+5) +n=m+85 + +if 1 + x=3 + if 1 c=4 + end +end +if 1x=3 if 1c=4 end end + +if 1 > 2 + x=3 + if 1 c=4 + end +else + x=2 +end + +while 0 + while a < 10 + a = a + 1 + end +end + +until a == 0 + a = a - 1 + if -1 + break + end +end + +cc = c +repeat + cc = cc * 2 + if cc == 32 + break + end +end + +s=0 +for x = 1 to 5 + s = s + x +end + +do 10 + a = a * a +end + +xitcode=a-a diff --git a/test/test_break.code b/test/test_break.code new file mode 100644 index 0000000..247a747 --- /dev/null +++ b/test/test_break.code @@ -0,0 +1,10 @@ +a=10 +b=0 +repeat + a=a-5 + b=b+1 + if b == 2 + break + end +end +c=a+b-2 diff --git a/test/test_do.code b/test/test_do.code new file mode 100644 index 0000000..79633e9 --- /dev/null +++ b/test/test_do.code @@ -0,0 +1,5 @@ +a=10 +do 10 + a=a-1 +end +a=a \ No newline at end of file diff --git a/test/test_eq.code b/test/test_eq.code new file mode 100644 index 0000000..90d68fd --- /dev/null +++ b/test/test_eq.code @@ -0,0 +1,13 @@ +if 1 == 0 + a=1 +else + a=0 +end + +if 1 == 1 + b=0 +else + b=1 +end + +c=a+b diff --git a/test/test_for.code b/test/test_for.code new file mode 100644 index 0000000..ab33b73 --- /dev/null +++ b/test/test_for.code @@ -0,0 +1,7 @@ +i=0 +a=10 +for i = 0 to 10 + a=a-1 +end +a=a + \ No newline at end of file diff --git a/test/test_ge.code b/test/test_ge.code new file mode 100644 index 0000000..431a103 --- /dev/null +++ b/test/test_ge.code @@ -0,0 +1,19 @@ +if 1 >= 0 + a=0 +else + a=1 +end + +if 1 >= 1 + b=0 +else + b=1 +end + +if 1 >= 2 + c=1 +else + c=0 +end + +d=a+b+c diff --git a/test/test_gt.code b/test/test_gt.code new file mode 100644 index 0000000..bc610c1 --- /dev/null +++ b/test/test_gt.code @@ -0,0 +1,19 @@ +if 1 > 0 + a=0 +else + a=1 +end + +if 1 > 1 + b=1 +else + b=0 +end + +if 1 > 2 + c=1 +else + c=0 +end + +d=a+b+c diff --git a/test/test_if.code b/test/test_if.code new file mode 100644 index 0000000..0635810 --- /dev/null +++ b/test/test_if.code @@ -0,0 +1,13 @@ +if 0 + a=1 +else + a=0 +end + +if 1 + b=0 +else + b=1 +end + +c=a+b diff --git a/test/test_le.code b/test/test_le.code new file mode 100644 index 0000000..1b75e62 --- /dev/null +++ b/test/test_le.code @@ -0,0 +1,19 @@ +if 1 <= 0 + a=1 +else + a=0 +end + +if 1 <= 1 + b=0 +else + b=1 +end + +if 1 <= 2 + c=0 +else + c=1 +end + +d=a+b+c diff --git a/test/test_lt.code b/test/test_lt.code new file mode 100644 index 0000000..fa7c852 --- /dev/null +++ b/test/test_lt.code @@ -0,0 +1,19 @@ +if 1 < 0 + a=1 +else + a=0 +end + +if 1 < 1 + b=1 +else + b=0 +end + +if 1 < 2 + c=0 +else + c=1 +end + +d=a+b+c diff --git a/test/test_neq.code b/test/test_neq.code new file mode 100644 index 0000000..6f64b93 --- /dev/null +++ b/test/test_neq.code @@ -0,0 +1,13 @@ +if 1 != 0 + a=0 +else + a=1 +end + +if 1 != 1 + b=1 +else + b=0 +end + +c=a+b diff --git a/test/test_print.code b/test/test_print.code new file mode 100644 index 0000000..3475498 --- /dev/null +++ b/test/test_print.code @@ -0,0 +1,8 @@ +print 0 +print 1 +print -1 +print 123 +print -123 +print 4096 +print -4096 +exitcode=0 diff --git a/test/test_repeat.code b/test/test_repeat.code new file mode 100644 index 0000000..c0fad82 --- /dev/null +++ b/test/test_repeat.code @@ -0,0 +1,11 @@ +a=10 +b=0 +repeat + a=a-5 + b=b+1 + if b == 2 + break + end +end +c=a+b-2 + \ No newline at end of file diff --git a/test/test_until.code b/test/test_until.code new file mode 100644 index 0000000..2921853 --- /dev/null +++ b/test/test_until.code @@ -0,0 +1,5 @@ +a=10 +until a <= 0 + a=a-1 +end +a=a \ No newline at end of file diff --git a/test/test_while.code b/test/test_while.code new file mode 100644 index 0000000..d463b56 --- /dev/null +++ b/test/test_while.code @@ -0,0 +1,6 @@ +a=0 +while a < 5 + a=a+1 +end + +b=a-5 diff --git a/test/testi.code b/test/testi.code new file mode 100644 index 0000000..d1bd085 --- /dev/null +++ b/test/testi.code @@ -0,0 +1 @@ +(5*(3 - 5)*2 - 33 - 9/3 - 8/2 + 4*(5 + 5 + 5)) + (4*5 - 21/2 - 15 + 5) diff --git a/test/testi.rb b/test/testi.rb new file mode 100644 index 0000000..dbd2dc6 --- /dev/null +++ b/test/testi.rb @@ -0,0 +1,25 @@ +require 'interpreter' +require 'stringio' + +def error(msg) STDERR.puts(msg) end + +def eval(input) + interpreter = Interpreter.new(input) + interpreter.run + +rescue ParseError => e + error("[error] #{e.message}") + error("Aborting!") + exit(1) +end + +def main(arg) + input = if File.readable?(arg) + File.open(arg) + else + STDIN + end + puts(eval(input)) +end + +main(ARGV[0].to_s)