spec/front_end/parser_spec.rb in loxxy-0.0.6 vs spec/front_end/parser_spec.rb in loxxy-0.0.7
- old
+ new
@@ -8,10 +8,22 @@
module Loxxy
module FrontEnd
describe Parser do
subject { Parser.new }
+ # Utility method to walk towards deeply nested node
+ # @param aNTNode [Rley::PTree::NonTerminalNode]
+ # @param subnodePath[Array<Integer>] An Array of subnode indices
+ def walk_subnodes(aNTNode, subnodePath)
+ curr_node = aNTNode
+ subnodePath.each do |index|
+ curr_node = curr_node.subnodes[index]
+ end
+
+ curr_node
+ end
+
context 'Initialization:' do
it 'should be initialized without argument' do
expect { Parser.new }.not_to raise_error
end
@@ -23,15 +35,11 @@
context 'Parsing blank files:' do
def check_empty_input_result(aParseTree)
# Parse results MUST to comply to grammar rule:
# program => declaration_star EOF
# where the declaration_star MUST be empty
- expect(aParseTree.root.symbol.name).to eq('program')
- expect(aParseTree.root.subnodes.size).to eq(1)
- eof = aParseTree.root.subnodes[0]
- expect(eof).to be_kind_of(Rley::PTree::TerminalNode)
- expect(eof.symbol.name).to eq('EOF')
+ expect(aParseTree.root.symbol.name).to eq('EOF')
end
it 'should cope with an empty input' do
ptree = subject.parse('')
check_empty_input_result(ptree)
@@ -50,47 +58,94 @@
ptree = subject.parse(input)
check_empty_input_result(ptree)
end
end # context
- context 'Parsing expressions:' do
- # Utility method to walk towards deeply nested node
- # @param aNTNode [Rley::PTree::NonTerminalNode]
- # @param subnodePath[Array<Integer>] An Array of subnode indices
- def walk_subnodes(aNTNode, subnodePath)
- curr_node = aNTNode
- subnodePath.each do |index|
- curr_node = curr_node.subnodes[index]
+ context 'Parsing literals:' do
+ it 'should parse a false literal' do
+ input = 'false;'
+ ptree = subject.parse(input)
+ leaf = walk_subnodes(ptree.root, [0, 0])
+ expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
+ expect(leaf.literal).to be_equal(Datatype::False.instance)
+ end
+
+ it 'should parse a true literal' do
+ input = 'true;'
+ ptree = subject.parse(input)
+ leaf = walk_subnodes(ptree.root, [0, 0])
+ expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
+ expect(leaf.literal).to be_equal(Datatype::True.instance)
+ end
+
+ it 'should parse number literals' do
+ inputs = %w[1234; 12.34;]
+ inputs.each do |source|
+ ptree = subject.parse(source)
+ leaf = walk_subnodes(ptree.root, [0, 0])
+ expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
+ expect(leaf.literal).to be_kind_of(Datatype::Number)
+ expect(leaf.literal.value).to eq(source.to_f)
end
+ end
- curr_node
+ it 'should parse string literals' do
+ inputs = [
+ '"I am a string";',
+ '"";',
+ '"123";'
+ ]
+ inputs.each do |source|
+ ptree = subject.parse(source)
+ leaf = walk_subnodes(ptree.root, [0, 0])
+ expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
+ expect(leaf.literal).to be_kind_of(Datatype::LXString)
+ expect(leaf.literal.value).to eq(source.gsub(/(^")|(";$)/, ''))
+ end
end
+
+ it 'should parse a nil literal' do
+ input = 'nil;'
+ ptree = subject.parse(input)
+ leaf = walk_subnodes(ptree.root, [0, 0])
+ expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
+ expect(leaf.literal).to be_equal(Datatype::Nil.instance)
+ end
+ end
+
+ context 'Parsing expressions:' do
it 'should parse a hello world program' do
program = <<-LOX_END
// Your first Lox program!
print "Hello, world!";
LOX_END
ptree = subject.parse(program)
root = ptree.root
expect(root.symbol.name).to eq('program')
- (decls, eof) = root.subnodes
- expect(decls).to be_kind_of(Rley::PTree::NonTerminalNode)
- expect(decls.symbol.name).to eq('declaration_star')
- prnt_stmt = decls.subnodes[0]
+ (prnt_stmt, eof) = root.subnodes
expect(prnt_stmt).to be_kind_of(Rley::PTree::NonTerminalNode)
+ expect(prnt_stmt.symbol.name).to eq('printStmt')
expect(prnt_stmt.subnodes.size).to eq(3)
expect(prnt_stmt.subnodes[0]).to be_kind_of(Rley::PTree::TerminalNode)
expect(prnt_stmt.subnodes[0].symbol.name).to eq('PRINT')
- expect(prnt_stmt.subnodes[1]).to be_kind_of(Rley::PTree::NonTerminalNode)
- # leaf_node = walk_subnodes(prnt_stmt, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
- # expect(leaf_node).to be_kind_of(Rley::PTree::TerminalNode)
- # expect(leaf_node.symbol.name).to eq('STRING')
- # expect(leaf_node.token.value).to eq('Hello, world!')
+ expect(prnt_stmt.subnodes[1]).to be_kind_of(Loxxy::Ast::LoxLiteralExpr)
+ expect(prnt_stmt.subnodes[1].literal).to be_kind_of(Loxxy::Datatype::LXString)
+ expect(prnt_stmt.subnodes[1].literal.value).to eq('Hello, world!')
expect(prnt_stmt.subnodes[2]).to be_kind_of(Rley::PTree::TerminalNode)
expect(prnt_stmt.subnodes[2].symbol.name).to eq('SEMICOLON')
expect(eof).to be_kind_of(Rley::PTree::TerminalNode)
expect(eof.symbol.name).to eq('EOF')
end
- end
+ end # context
+
+ context 'Parsing literals:' do
+ it 'should parse the addition of two number literals' do
+ # input = '123 + 456;'
+ # ptree = subject.parse(input)
+ # term = walk_subnodes(ptree.root, [0, 0, 0, 0, 0, 0, 0])
+ # expect(leaf).to be_kind_of(Ast::LoxBinaryExpr)
+ # expect(leaf.literal).to be_equal(Datatype::False.instance)
+ end
+ end # context
end # describe
end # module
end # module