copied thnad to get a kickstart
This commit is contained in:
21
test/test/fake_builder.rb
Normal file
21
test/test/fake_builder.rb
Normal file
@ -0,0 +1,21 @@
|
||||
class FakeBuilder
|
||||
attr_reader :result
|
||||
|
||||
def initialize
|
||||
@result = ''
|
||||
end
|
||||
|
||||
def class_builder
|
||||
'example'
|
||||
end
|
||||
|
||||
def int
|
||||
'int'
|
||||
end
|
||||
|
||||
def method_missing(name, *args, &block)
|
||||
@result += ([name] + args.flatten).join(', ').sub(',', '')
|
||||
@result += "\n"
|
||||
block.call(self) if name.to_s == 'public_static_method'
|
||||
end
|
||||
end
|
22
test/test/graph_helper.rb
Normal file
22
test/test/graph_helper.rb
Normal file
@ -0,0 +1,22 @@
|
||||
require 'gritty'
|
||||
|
||||
def dump(obj, name)
|
||||
g = digraph do
|
||||
graph_attribs << 'bgcolor=black'
|
||||
|
||||
node_attribs << 'color=white'
|
||||
node_attribs << 'penwidth=2'
|
||||
node_attribs << 'fontcolor=white'
|
||||
node_attribs << 'labelloc=c'
|
||||
node_attribs << 'fontname="Courier New"'
|
||||
node_attribs << 'fontsize=36'
|
||||
|
||||
edge_attribs << 'color=white'
|
||||
edge_attribs << 'penwidth=2'
|
||||
|
||||
builder = Gritty::NodeBuilder.new self
|
||||
builder.build obj, 'root'
|
||||
|
||||
save name, 'pdf'
|
||||
end
|
||||
end
|
77
test/test/test_nodes.rb
Normal file
77
test/test/test_nodes.rb
Normal file
@ -0,0 +1,77 @@
|
||||
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
||||
$: << File.expand_path(File.dirname(__FILE__))
|
||||
|
||||
require 'minitest/autorun'
|
||||
require 'minitest/spec'
|
||||
require 'thnad/nodes'
|
||||
require 'fake_builder'
|
||||
|
||||
include Thnad
|
||||
|
||||
describe 'Nodes' do
|
||||
before do
|
||||
@context = Hash.new
|
||||
@builder = FakeBuilder.new
|
||||
end
|
||||
|
||||
it 'emits a number' do
|
||||
input = Thnad::Number.new 42
|
||||
expected = <<HERE
|
||||
ldc 42
|
||||
HERE
|
||||
input.eval @context, @builder
|
||||
|
||||
@builder.result.must_equal expected
|
||||
end
|
||||
|
||||
it 'emits a function call' do
|
||||
@context[:params] = ['foo']
|
||||
|
||||
input = Thnad::Funcall.new 'baz', [Thnad::Number.new(42),
|
||||
Thnad::Name.new('foo')]
|
||||
expected = <<HERE
|
||||
ldc 42
|
||||
iload 0
|
||||
invokestatic example, baz, int, int, int
|
||||
HERE
|
||||
|
||||
input.eval @context, @builder
|
||||
|
||||
@builder.result.must_equal expected
|
||||
end
|
||||
|
||||
it 'emits a conditional' do
|
||||
input = Thnad::Conditional.new \
|
||||
Thnad::Number.new(0),
|
||||
Thnad::Number.new(42),
|
||||
Thnad::Number.new(667)
|
||||
expected = <<HERE
|
||||
ldc 0
|
||||
ifeq else
|
||||
ldc 42
|
||||
goto endif
|
||||
label else
|
||||
ldc 667
|
||||
label endif
|
||||
HERE
|
||||
|
||||
input.eval @context, @builder
|
||||
@builder.result.must_equal expected
|
||||
end
|
||||
|
||||
it 'emits a function definition' do
|
||||
input = Thnad::Function.new \
|
||||
'foo',
|
||||
Thnad::Name.new('x'),
|
||||
Thnad::Number.new(5)
|
||||
|
||||
expected = <<HERE
|
||||
public_static_method foo, int, int
|
||||
ldc 5
|
||||
ireturn
|
||||
HERE
|
||||
|
||||
input.eval @context, @builder
|
||||
@builder.result.must_equal expected
|
||||
end
|
||||
end
|
72
test/test/test_parser.rb
Normal file
72
test/test/test_parser.rb
Normal file
@ -0,0 +1,72 @@
|
||||
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
||||
|
||||
require 'minitest/autorun'
|
||||
require 'minitest/spec'
|
||||
require 'thnad/parser'
|
||||
|
||||
include Thnad
|
||||
|
||||
describe Parser do
|
||||
before do
|
||||
@parser = Thnad::Parser.new
|
||||
end
|
||||
|
||||
it 'reads a number' do
|
||||
input = '42 '
|
||||
expected = {:number => '42'}
|
||||
|
||||
@parser.number.parse(input).must_equal expected
|
||||
end
|
||||
|
||||
it 'reads a name' do
|
||||
input = 'foo '
|
||||
expected = {:name => 'foo'}
|
||||
|
||||
@parser.name.parse(input).must_equal expected
|
||||
end
|
||||
|
||||
it 'reads an argument list' do
|
||||
input = '(42, foo)'
|
||||
expected = {:args => [{:arg => {:number => '42'}},
|
||||
{:arg => {:name => 'foo'}}]}
|
||||
|
||||
@parser.args.parse(input).must_equal expected
|
||||
end
|
||||
|
||||
it 'reads a function call' do
|
||||
input = 'baz(42, foo)'
|
||||
expected = {:funcall => {:name => 'baz' },
|
||||
:args => [{:arg => {:number => '42'}},
|
||||
{:arg => {:name => 'foo'}}]}
|
||||
|
||||
@parser.funcall.parse(input).must_equal expected
|
||||
end
|
||||
|
||||
it 'reads a conditional' do
|
||||
input = <<HERE
|
||||
if (0) {
|
||||
42
|
||||
} else {
|
||||
667
|
||||
}
|
||||
HERE
|
||||
|
||||
expected = {:cond => {:number => '0'},
|
||||
:if_true => {:body => {:number => '42'}},
|
||||
:if_false => {:body => {:number => '667'}}}
|
||||
|
||||
@parser.cond.parse(input).must_equal expected
|
||||
end
|
||||
|
||||
it 'reads a function definition' do
|
||||
input = <<HERE
|
||||
function foo(x) {
|
||||
5
|
||||
}
|
||||
HERE
|
||||
expected = {:func => {:name => 'foo'},
|
||||
:params => {:param => {:name => 'x'}},
|
||||
:body => {:number => '5'}}
|
||||
@parser.func.parse(input).must_equal expected
|
||||
end
|
||||
end
|
78
test/test/test_transform.rb
Normal file
78
test/test/test_transform.rb
Normal file
@ -0,0 +1,78 @@
|
||||
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
|
||||
|
||||
require 'minitest/autorun'
|
||||
require 'minitest/spec'
|
||||
require 'thnad/transform'
|
||||
|
||||
include Thnad
|
||||
|
||||
describe Transform do
|
||||
before do
|
||||
@transform = Thnad::Transform.new
|
||||
end
|
||||
|
||||
it 'transforms a number' do
|
||||
input = {:number => '42'}
|
||||
expected = Thnad::Number.new(42)
|
||||
|
||||
@transform.apply(input).must_equal expected
|
||||
end
|
||||
|
||||
it 'transforms a name' do
|
||||
input = {:name => 'foo'}
|
||||
expected = Thnad::Name.new('foo')
|
||||
|
||||
@transform.apply(input).must_equal expected
|
||||
end
|
||||
|
||||
it 'transforms an argument list' do
|
||||
input = {:args => [{:arg => {:number => '42'}},
|
||||
{:arg => {:name => 'foo'}}]}
|
||||
expected = [Thnad::Number.new(42),
|
||||
Thnad::Name.new('foo')]
|
||||
|
||||
@transform.apply(input).must_equal expected
|
||||
end
|
||||
|
||||
it 'transforms a single-argument function call' do
|
||||
input = {:funcall => {:name => 'foo'},
|
||||
:args => [{:arg => {:number => '42'}}]}
|
||||
expected = Thnad::Funcall.new 'foo', [Thnad::Number.new(42)]
|
||||
|
||||
@transform.apply(input).must_equal expected
|
||||
end
|
||||
|
||||
it 'transforms a multi-argument function call' do
|
||||
input = {:funcall => {:name => 'baz'},
|
||||
:args => [{:arg => {:number => '42'}},
|
||||
{:arg => {:name => 'foo'}}]}
|
||||
expected = Thnad::Funcall.new 'baz', [Thnad::Number.new(42),
|
||||
Thnad::Name.new('foo')]
|
||||
|
||||
@transform.apply(input).must_equal expected
|
||||
end
|
||||
|
||||
it 'transforms a conditional' do
|
||||
input = {:cond => {:number => '0'},
|
||||
:if_true => {:body => {:number => '42'}},
|
||||
:if_false => {:body => {:number => '667'}}}
|
||||
expected = Thnad::Conditional.new \
|
||||
Thnad::Number.new(0),
|
||||
Thnad::Number.new(42),
|
||||
Thnad::Number.new(667)
|
||||
|
||||
@transform.apply(input).must_equal expected
|
||||
end
|
||||
|
||||
it 'transforms a function definition' do
|
||||
input = {:func => {:name => 'foo'},
|
||||
:params => {:param => {:name => 'x'}},
|
||||
:body => {:number => '5'}}
|
||||
expected = Thnad::Function.new \
|
||||
'foo',
|
||||
[Thnad::Name.new('x')],
|
||||
Thnad::Number.new(5)
|
||||
|
||||
@transform.apply(input).must_equal expected
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user