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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -0
- data/Changelog.md +9 -1
- data/Gemfile +9 -8
- data/Gemfile.lock +66 -53
- data/README.md +8 -6
- data/VERSION +1 -1
- data/basic101.gemspec +688 -0
- data/lib/basic101/parser.rb +28 -457
- data/lib/basic101/parser/data_statement.rb +20 -0
- data/lib/basic101/parser/define_function_statement.rb +18 -0
- data/lib/basic101/parser/dim_statement.rb +16 -0
- data/lib/basic101/parser/end_statement.rb +11 -0
- data/lib/basic101/parser/expression.rb +100 -0
- data/lib/basic101/parser/for_statement.rb +17 -0
- data/lib/basic101/parser/function_call.rb +13 -0
- data/lib/basic101/parser/gosub_statement.rb +12 -0
- data/lib/basic101/parser/goto_statement.rb +11 -0
- data/lib/basic101/parser/identifier.rb +87 -0
- data/lib/basic101/parser/if_statement.rb +20 -0
- data/lib/basic101/parser/input_statement.rb +19 -0
- data/lib/basic101/parser/let_statement.rb +13 -0
- data/lib/basic101/parser/next_statement.rb +16 -0
- data/lib/basic101/parser/numeric.rb +34 -0
- data/lib/basic101/parser/on_goto_statement.rb +20 -0
- data/lib/basic101/parser/print_statement.rb +19 -0
- data/lib/basic101/parser/program.rb +17 -0
- data/lib/basic101/parser/randomize_statement.rb +11 -0
- data/lib/basic101/parser/read_statement.rb +12 -0
- data/lib/basic101/parser/reference.rb +36 -0
- data/lib/basic101/parser/remark_statement.rb +11 -0
- data/lib/basic101/parser/restore_statement.rb +12 -0
- data/lib/basic101/parser/return_statement.rb +11 -0
- data/lib/basic101/parser/space.rb +23 -0
- data/lib/basic101/parser/statements.rb +36 -0
- data/lib/basic101/parser/stop_statement.rb +11 -0
- data/lib/basic101/parser/string.rb +17 -0
- data/test/spec/basic_float_spec.rb +2 -2
- data/test/spec/basic_object_spec.rb +1 -1
- data/test/spec/basic_string_spec.rb +2 -2
- data/test/spec/input_reader_spec.rb +11 -11
- data/test/spec/input_spec.rb +5 -5
- data/test/spec/output_spec.rb +3 -3
- data/test/spec/spec_helper.rb +2 -1
- data/test/spec/support/basic_numeric_helpers.rb +3 -3
- 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,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,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,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.
|
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.
|
23
|
+
expect(b).to eq a
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -240,14 +240,14 @@ module Basic101
|
|
240
240
|
|
241
241
|
describe '#print_string' do
|
242
242
|
specify do
|
243
|
-
output.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
108
|
+
expect(input_reader.read_numeric).to be_within(0.000001).of(-1.2)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
data/test/spec/input_spec.rb
CHANGED
@@ -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.
|
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.
|
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.
|
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.
|
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.
|
91
|
+
expect(output).to_not receive(:print)
|
92
92
|
input.read_line
|
93
93
|
end
|
94
94
|
end
|
data/test/spec/output_spec.rb
CHANGED
@@ -134,16 +134,16 @@ module Basic101
|
|
134
134
|
|
135
135
|
describe '#isatty' do
|
136
136
|
|
137
|
-
before(:each) {file.
|
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
|
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
|
146
|
+
its(:isatty) {should be_falsey}
|
147
147
|
end
|
148
148
|
|
149
149
|
end
|
data/test/spec/spec_helper.rb
CHANGED
@@ -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__)
|