basic101 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -0
  3. data/Changelog.md +9 -1
  4. data/Gemfile +9 -8
  5. data/Gemfile.lock +66 -53
  6. data/README.md +8 -6
  7. data/VERSION +1 -1
  8. data/basic101.gemspec +688 -0
  9. data/lib/basic101/parser.rb +28 -457
  10. data/lib/basic101/parser/data_statement.rb +20 -0
  11. data/lib/basic101/parser/define_function_statement.rb +18 -0
  12. data/lib/basic101/parser/dim_statement.rb +16 -0
  13. data/lib/basic101/parser/end_statement.rb +11 -0
  14. data/lib/basic101/parser/expression.rb +100 -0
  15. data/lib/basic101/parser/for_statement.rb +17 -0
  16. data/lib/basic101/parser/function_call.rb +13 -0
  17. data/lib/basic101/parser/gosub_statement.rb +12 -0
  18. data/lib/basic101/parser/goto_statement.rb +11 -0
  19. data/lib/basic101/parser/identifier.rb +87 -0
  20. data/lib/basic101/parser/if_statement.rb +20 -0
  21. data/lib/basic101/parser/input_statement.rb +19 -0
  22. data/lib/basic101/parser/let_statement.rb +13 -0
  23. data/lib/basic101/parser/next_statement.rb +16 -0
  24. data/lib/basic101/parser/numeric.rb +34 -0
  25. data/lib/basic101/parser/on_goto_statement.rb +20 -0
  26. data/lib/basic101/parser/print_statement.rb +19 -0
  27. data/lib/basic101/parser/program.rb +17 -0
  28. data/lib/basic101/parser/randomize_statement.rb +11 -0
  29. data/lib/basic101/parser/read_statement.rb +12 -0
  30. data/lib/basic101/parser/reference.rb +36 -0
  31. data/lib/basic101/parser/remark_statement.rb +11 -0
  32. data/lib/basic101/parser/restore_statement.rb +12 -0
  33. data/lib/basic101/parser/return_statement.rb +11 -0
  34. data/lib/basic101/parser/space.rb +23 -0
  35. data/lib/basic101/parser/statements.rb +36 -0
  36. data/lib/basic101/parser/stop_statement.rb +11 -0
  37. data/lib/basic101/parser/string.rb +17 -0
  38. data/test/spec/basic_float_spec.rb +2 -2
  39. data/test/spec/basic_object_spec.rb +1 -1
  40. data/test/spec/basic_string_spec.rb +2 -2
  41. data/test/spec/input_reader_spec.rb +11 -11
  42. data/test/spec/input_spec.rb +5 -5
  43. data/test/spec/output_spec.rb +3 -3
  44. data/test/spec/spec_helper.rb +2 -1
  45. data/test/spec/support/basic_numeric_helpers.rb +3 -3
  46. metadata +82 -34
@@ -0,0 +1,19 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ rule(:print_statement) do
6
+ str('PRINT').as(:print) >> print_arguments.as(:print_arguments)
7
+ end
8
+
9
+ rule(:print_arguments) do
10
+ (space? >> (expression | print_separator)).repeat(0)
11
+ end
12
+
13
+ rule(:print_separator) do
14
+ match('[;,]').as(:print_separator)
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,17 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ root(:program)
6
+
7
+ rule(:program) do
8
+ ((line >> (new_line >> line).repeat(0) >> new_line.maybe).maybe).as(:program)
9
+ end
10
+
11
+ rule(:line) do
12
+ (integer >> space? >> statements.as(:statements))
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,11 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ rule(:randomize_statement) do
6
+ str('RANDOMIZE').as(:randomize)
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,12 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ rule(:read_statement) do
6
+ str('READ').as(:read) >>
7
+ space? >> reference_list.as(:references)
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,36 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ rule(:scalar_reference_list) do
6
+ scalar_reference >>
7
+ (space? >> str(',') >>
8
+ space? >> scalar_reference).repeat(0)
9
+ end
10
+
11
+ rule(:reference_list) do
12
+ reference >> (space? >> str(',') >> space? >> reference).repeat(0)
13
+ end
14
+
15
+ rule(:reference) do
16
+ array_reference | scalar_reference
17
+ end
18
+
19
+ rule(:array_reference) do
20
+ identifier.as(:subscript_base) >> space? >>
21
+ str('(') >> space? >> argument_list.as(:argument_list) >>
22
+ space? >> str(')')
23
+ end
24
+
25
+ rule(:scalar_reference) do
26
+ identifier.as(:scalar_reference)
27
+ end
28
+
29
+ rule(:argument_list) do
30
+ expression >> (space? >> str(',') >> space? >> expression).repeat(0)
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+
@@ -0,0 +1,11 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ rule(:remark_statement) do
6
+ (str('REM') >> printable.repeat(0)).as(:remark)
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,12 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ rule(:restore_statement) do
6
+ str('RESTORE').as(:restore) >>
7
+ (space? >> integer).maybe.as(:line_number)
8
+ end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,11 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ rule(:return_statement) do
6
+ str('RETURN').as(:return)
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,23 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ rule(:space) do
6
+ match(' ').repeat(1)
7
+ end
8
+
9
+ rule(:new_line) do
10
+ str("\r").maybe >> str("\n")
11
+ end
12
+
13
+ rule(:space?) do
14
+ space.maybe
15
+ end
16
+
17
+ rule(:printable) do
18
+ match('[[:print:]]')
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,36 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ rule(:statements) do
6
+ statement >>
7
+ (space? >> str(':') >>
8
+ space? >> statement).repeat(0) >>
9
+ space? >> str(':').maybe
10
+ end
11
+
12
+ rule(:statement) do
13
+ (goto_statement |
14
+ remark_statement |
15
+ print_statement |
16
+ if_statement |
17
+ randomize_statement |
18
+ input_statement |
19
+ end_statement |
20
+ dim_statement |
21
+ for_statement |
22
+ next_statement |
23
+ on_goto_statement |
24
+ data_statement |
25
+ read_statement |
26
+ gosub_statement |
27
+ return_statement |
28
+ stop_statement |
29
+ restore_statement |
30
+ define_function_statement |
31
+ let_statement)
32
+ end
33
+
34
+ end
35
+
36
+ end
@@ -0,0 +1,11 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ rule(:stop_statement) do
6
+ str('STOP').as(:stop)
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,17 @@
1
+ module Basic101
2
+
3
+ class Parser < Parslet::Parser
4
+
5
+ rule(:unquoted_string) do
6
+ match('(?=[[:print:]])[^,": ]').repeat(0).as(:string)
7
+ end
8
+
9
+ rule(:quoted_string) do
10
+ str('"') >>
11
+ match('(?=[[:print:]])[^"]').repeat(0).maybe.as(:string) >>
12
+ str('"')
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -12,7 +12,7 @@ module Basic101
12
12
  it 'should return a basic integer' do
13
13
  a = described_class.new(12.0)
14
14
  b = a.simplest
15
- b.should eq BasicInteger.new(12)
15
+ expect(b).to eq BasicInteger.new(12)
16
16
  end
17
17
  end
18
18
 
@@ -20,7 +20,7 @@ module Basic101
20
20
  it 'should return itself' do
21
21
  a = described_class.new(12.34)
22
22
  b = a.simplest
23
- b.should eq a
23
+ expect(b).to eq a
24
24
  end
25
25
  end
26
26
 
@@ -13,7 +13,7 @@ module Basic101
13
13
  describe '#eval' do
14
14
  let(:runtime) {double Runtime}
15
15
  it 'should return itself' do
16
- subject.eval(runtime).should eq subject
16
+ expect(subject.eval(runtime)).to eq subject
17
17
  end
18
18
  end
19
19
 
@@ -240,14 +240,14 @@ module Basic101
240
240
 
241
241
  describe '#print_string' do
242
242
  specify do
243
- output.should_receive(:print).with('123')
243
+ expect(output).to receive(:print).with('123')
244
244
  subject.print_string(output)
245
245
  end
246
246
  end
247
247
 
248
248
  describe '#print_new_line' do
249
249
  specify do
250
- output.should_receive(:print).with("\n")
250
+ expect(output).to receive(:print).with("\n")
251
251
  subject.print_new_line(output)
252
252
  end
253
253
  end
@@ -21,35 +21,35 @@ module Basic101
21
21
  context 'when unquoted' do
22
22
  let(:line) {%Q'abc,123'}
23
23
  specify do
24
- input_reader.read_string.should eq 'abc'
24
+ expect(input_reader.read_string).to eq 'abc'
25
25
  end
26
26
  end
27
27
 
28
28
  context 'with comma' do
29
29
  let(:line) {%Q'"abc,def",123'}
30
30
  specify do
31
- input_reader.read_string.should eq 'abc,def'
31
+ expect(input_reader.read_string).to eq 'abc,def'
32
32
  end
33
33
  end
34
34
 
35
35
  context 'with quote' do
36
36
  let(:line) {%Q'"abc""def",123'}
37
37
  specify do
38
- input_reader.read_string.should eq 'abc"def'
38
+ expect(input_reader.read_string).to eq 'abc"def'
39
39
  end
40
40
  end
41
41
 
42
42
  context 'when blank' do
43
43
  let(:line) {",abc"}
44
44
  specify do
45
- input_reader.read_string.should eq ''
45
+ expect(input_reader.read_string).to eq ''
46
46
  end
47
47
  end
48
48
 
49
49
  context 'when end of line' do
50
50
  let(:line) {""}
51
51
  specify do
52
- input_reader.read_string.should eq ''
52
+ expect(input_reader.read_string).to eq ''
53
53
  end
54
54
  end
55
55
 
@@ -70,42 +70,42 @@ module Basic101
70
70
  context 'when integer' do
71
71
  let(:line) {"123,abc"}
72
72
  specify do
73
- input_reader.read_numeric.should eq 123
73
+ expect(input_reader.read_numeric).to eq 123
74
74
  end
75
75
  end
76
76
 
77
77
  context 'when positive integer' do
78
78
  let(:line) {"+123,abc"}
79
79
  specify do
80
- input_reader.read_numeric.should eq 123
80
+ expect(input_reader.read_numeric).to eq 123
81
81
  end
82
82
  end
83
83
 
84
84
  context 'when negative integer' do
85
85
  let(:line) {"-123,abc"}
86
86
  specify do
87
- input_reader.read_numeric.should eq -123
87
+ expect(input_reader.read_numeric).to eq -123
88
88
  end
89
89
  end
90
90
 
91
91
  context 'when float' do
92
92
  let(:line) {"1.2,abc"}
93
93
  specify do
94
- input_reader.read_numeric.should be_within(0.000001).of(1.2)
94
+ expect(input_reader.read_numeric).to be_within(0.000001).of(1.2)
95
95
  end
96
96
  end
97
97
 
98
98
  context 'when positive float' do
99
99
  let(:line) {"+1.2,abc"}
100
100
  specify do
101
- input_reader.read_numeric.should be_within(0.000001).of(1.2)
101
+ expect(input_reader.read_numeric).to be_within(0.000001).of(1.2)
102
102
  end
103
103
  end
104
104
 
105
105
  context 'when negative float' do
106
106
  let(:line) {"-1.2,abc"}
107
107
  specify do
108
- input_reader.read_numeric.should be_within(0.000001).of(-1.2)
108
+ expect(input_reader.read_numeric).to be_within(0.000001).of(-1.2)
109
109
  end
110
110
  end
111
111
 
@@ -9,7 +9,7 @@ module Basic101
9
9
  let(:file) {StringIO.new(input_string)}
10
10
  let(:output) {double Output, :isatty => output_isatty}
11
11
  subject(:input) {described_class.new(output, file)}
12
- before(:each) {file.stub(:isatty => input_isatty)}
12
+ before(:each) {allow(file).to receive(:isatty).and_return(input_isatty)}
13
13
 
14
14
  describe 'transcript' do
15
15
 
@@ -61,7 +61,7 @@ module Basic101
61
61
  let(:input_isatty) {false}
62
62
  let(:output_isatty) {false}
63
63
  specify do
64
- output.should receive(:echo).with(input_string)
64
+ expect(output).to receive(:echo).with(input_string)
65
65
  input.read_line
66
66
  end
67
67
  end
@@ -70,7 +70,7 @@ module Basic101
70
70
  let(:input_isatty) {false}
71
71
  let(:output_isatty) {true}
72
72
  specify do
73
- output.should receive(:echo).with(input_string)
73
+ expect(output).to receive(:echo).with(input_string)
74
74
  input.read_line
75
75
  end
76
76
  end
@@ -79,7 +79,7 @@ module Basic101
79
79
  let(:input_isatty) {true}
80
80
  let(:output_isatty) {false}
81
81
  specify do
82
- output.should receive(:echo).with(input_string)
82
+ expect(output).to receive(:echo).with(input_string)
83
83
  input.read_line
84
84
  end
85
85
  end
@@ -88,7 +88,7 @@ module Basic101
88
88
  let(:input_isatty) {true}
89
89
  let(:output_isatty) {true}
90
90
  specify do
91
- output.should_not receive(:print)
91
+ expect(output).to_not receive(:print)
92
92
  input.read_line
93
93
  end
94
94
  end
@@ -134,16 +134,16 @@ module Basic101
134
134
 
135
135
  describe '#isatty' do
136
136
 
137
- before(:each) {file.stub(:isatty => file_isatty)}
137
+ before(:each) {allow(file).to receive(:isatty).and_return(file_isatty)}
138
138
 
139
139
  context 'when file is tty' do
140
140
  let(:file_isatty) {true}
141
- its(:isatty) {should be_true}
141
+ its(:isatty) {should be_truthy}
142
142
  end
143
143
 
144
144
  context 'when file is tty' do
145
145
  let(:file_isatty) {false}
146
- its(:isatty) {should be_false}
146
+ its(:isatty) {should be_falsey}
147
147
  end
148
148
 
149
149
  end
@@ -2,11 +2,12 @@
2
2
  require 'simplecov'
3
3
  SimpleCov.command_name 'RSpec'
4
4
 
5
+ require 'rspec/its'
6
+
5
7
  require_relative '../../lib/basic101'
6
8
 
7
9
  # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
8
10
  RSpec.configure do |config|
9
- config.treat_symbols_as_metadata_keys_with_true_values = true
10
11
  end
11
12
 
12
13
  glob = File.expand_path('support/**/*.rb', __dir__)