basic101 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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__)
|