Skip to content

Commit 70dea64

Browse files
committed
Add items for variable assignment and brackets
1 parent afc2da1 commit 70dea64

3 files changed

Lines changed: 99 additions & 50 deletions

File tree

lib/code_breaker/parser.rb

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,29 @@ def run
1919
private
2020

2121
def parse(input)
22-
parsed_ast = ::Parser::CurrentRuby.parse(input)
23-
nodes = parsed_ast.loc.node.children[1].children
22+
ast = ::Parser::CurrentRuby.parse(input)
23+
24+
if variable_assignment?(ast)
25+
parse_variable_assignment(ast)
26+
else
27+
parse_statement(ast)
28+
end
29+
end
30+
31+
def variable_assignment?(ast)
32+
ast.loc.node.type == :lvasgn
33+
end
34+
35+
def parse_variable_assignment(ast)
36+
nodes = ast.loc.node.children[1].children
2437
result = parse_nodes(nodes)
25-
cleanup(result)
38+
cleanup(result).flatten(1).unshift(ast.loc.node.children[0], :'=')
39+
end
40+
41+
def parse_statement(ast)
42+
nodes = ast.loc.node.children
43+
result = parse_nodes(nodes)
44+
cleanup(result).flatten(1)
2645
end
2746

2847
def parse_nodes(nodes)
@@ -32,17 +51,21 @@ def parse_nodes(nodes)
3251
end
3352

3453
def cleanup(nodes)
35-
result = nodes.map do |node|
54+
nodes.map do |node|
3655
if node.kind_of?(Symbol)
3756
node
38-
elsif node.kind_of?(Array) && node.length == 1
39-
node[0].class
4057
elsif node.kind_of?(Array)
41-
node[0].nil? ? node[1].to_s.constantize : cleanup(node)
58+
if node.length > 1
59+
node[0].nil? ? node[1].to_s.constantize : cleanup(node)
60+
elsif node[0].kind_of?(Array)
61+
cleanup(node)
62+
else
63+
node[0].class
64+
end
65+
else
66+
node.class
4267
end
4368
end
44-
45-
result.flatten
4669
end
4770
end
4871
end

spec/code_breaker/parser_spec.rb

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
require 'spec_helper'
2+
3+
describe CodeBreaker::Parser do
4+
5+
let(:code_snippet) { 'sum = "2".to_i + 3' }
6+
let(:output) { [:sum, :'=', String, :to_i, :+, Fixnum] }
7+
8+
subject { CodeBreaker::Parser.new(code_snippet) }
9+
10+
it { is_expected.to respond_to :run }
11+
it { is_expected.to respond_to :input }
12+
it { is_expected.to respond_to :output }
13+
14+
describe 'input' do
15+
it 'returns the code snippet the parser was instanciated with' do
16+
expect(subject.input).to eq code_snippet
17+
end
18+
end
19+
20+
describe 'output' do
21+
it 'is an alias method for #run' do
22+
expect(subject.method(:output)).to eq subject.method(:run)
23+
end
24+
end
25+
26+
describe '#run' do
27+
it 'returns an Array' do
28+
expect(subject.run).to be_an Array
29+
end
30+
31+
context 'for code snippets defining a variable' do
32+
it 'returns the called classes and methods of the right hand side' do
33+
code_snippet = 'number = 1 + 2.3 - Rational(2,3) * Complex(0.4, 0.2)'
34+
expected_result = [:number, :'=', Fixnum, :+, Float, :-, Rational, :*, Complex]
35+
36+
actual_result = CodeBreaker::Parser.new(code_snippet).run
37+
expect(actual_result).to eq expected_result
38+
end
39+
40+
it 'returns a single item Array for only one statement' do
41+
code_snippet = '"3.14159265359"'
42+
expected_result = [String]
43+
44+
actual_result = CodeBreaker::Parser.new(code_snippet).run
45+
expect(actual_result).to eq expected_result
46+
end
47+
48+
it 'returns a nested Array for nested statements' do
49+
code_snippet = 'number = 1.2 * (Rational(2) - 1)'
50+
expected_result = [:number, :'=', Float, :*, [Rational, :-, Fixnum]]
51+
52+
actual_result = CodeBreaker::Parser.new(code_snippet).run
53+
expect(actual_result).to eq expected_result
54+
end
55+
end
56+
57+
context 'for code snippets not assigning a variable' do
58+
it 'returns the called classes and methods' do
59+
code_snippet = '1.2 * (Rational(2) - 1)'
60+
expected_result = [Float, :*, [Rational, :-, Fixnum]]
61+
62+
actual_result = CodeBreaker::Parser.new(code_snippet).run
63+
expect(actual_result).to eq expected_result
64+
end
65+
end
66+
end
67+
end

spec/parser_spec.rb

Lines changed: 0 additions & 41 deletions
This file was deleted.

0 commit comments

Comments
 (0)