electr 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/CHANGELOG.md +17 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +196 -0
  9. data/Rakefile +7 -0
  10. data/bin/electr +27 -0
  11. data/electr.gemspec +25 -0
  12. data/lib/electr.rb +20 -0
  13. data/lib/electr/ast.rb +9 -0
  14. data/lib/electr/ast/ast.rb +62 -0
  15. data/lib/electr/ast/constant_ast.rb +14 -0
  16. data/lib/electr/ast/func_args_ast.rb +11 -0
  17. data/lib/electr/ast/func_ast.rb +12 -0
  18. data/lib/electr/ast/func_name_ast.rb +14 -0
  19. data/lib/electr/ast/numeric_ast.rb +13 -0
  20. data/lib/electr/ast/operator_ast.rb +13 -0
  21. data/lib/electr/ast/root_ast.rb +11 -0
  22. data/lib/electr/ast/value_ast.rb +12 -0
  23. data/lib/electr/compiler.rb +24 -0
  24. data/lib/electr/evaluator.rb +64 -0
  25. data/lib/electr/exceptions.rb +6 -0
  26. data/lib/electr/option.rb +70 -0
  27. data/lib/electr/parser.rb +5 -0
  28. data/lib/electr/parser/lexer.rb +50 -0
  29. data/lib/electr/parser/lexical_unit.rb +67 -0
  30. data/lib/electr/parser/rules/base_rule.rb +60 -0
  31. data/lib/electr/parser/rules/expression_rule.rb +79 -0
  32. data/lib/electr/parser/rules/root_rule.rb +21 -0
  33. data/lib/electr/parser/sya.rb +105 -0
  34. data/lib/electr/parser/syntaxer.rb +21 -0
  35. data/lib/electr/parser/tokenizer.rb +79 -0
  36. data/lib/electr/repl.rb +56 -0
  37. data/lib/electr/rules.rb +3 -0
  38. data/lib/electr/version.rb +3 -0
  39. data/spec/compiler_spec.rb +42 -0
  40. data/spec/electr_spec.rb +7 -0
  41. data/spec/evaluator_spec.rb +47 -0
  42. data/spec/lexer_spec.rb +29 -0
  43. data/spec/spec_helper.rb +8 -0
  44. data/spec/sya_spec.rb +153 -0
  45. data/spec/tokenizer_spec.rb +102 -0
  46. metadata +138 -0
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ include Electr
4
+
5
+ describe Lexer do
6
+ before { @lexer = Lexer.new }
7
+
8
+ TOKENS = [
9
+ [ :numeric, "123" ],
10
+ [ :numeric, "0.6" ],
11
+ [ :operator, "+" ],
12
+ [ :constant, "pi" ],
13
+ [ :value, "11K" ],
14
+ [ :value, "11kΩ" ],
15
+ [ :name, "foobar" ],
16
+ [ :fname, "sqrt" ],
17
+ [ :open_parenthesis, "(" ],
18
+ [ :closed_parenthesis, ")" ],
19
+ ]
20
+
21
+ it "lexify" do
22
+ TOKENS.each do |token|
23
+ lexeme = @lexer.lexify(token.last)
24
+ expect(lexeme.type).to eq token.first
25
+ expect(lexeme.value).to eq token.last
26
+ end
27
+ end
28
+
29
+ end
@@ -0,0 +1,8 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'electr'
3
+
4
+ RSpec.configure do |config|
5
+ if config.files_to_run.one?
6
+ config.default_formatter = 'documentation'
7
+ end
8
+ end
@@ -0,0 +1,153 @@
1
+ require 'spec_helper'
2
+
3
+ include Electr
4
+
5
+ describe Sya do
6
+
7
+ specify '2 + 3' do
8
+ a = LexicalUnit.numeric('2')
9
+ b = LexicalUnit.operator('+')
10
+ c = LexicalUnit.numeric('3')
11
+ sya = Sya.new([a, b, c])
12
+
13
+ expect(sya.run).to eq [b, a, c]
14
+ end
15
+
16
+ specify '2 3 + 4' do
17
+ a = LexicalUnit.numeric('2')
18
+ b = LexicalUnit.numeric('3')
19
+ c = LexicalUnit.operator('+')
20
+ d = LexicalUnit.numeric('4')
21
+ added = LexicalUnit.operator('*')
22
+ sya = Sya.new([a, b, c, d])
23
+
24
+ # + * 2 3 4
25
+ expect(sya.run).to eq [c, added, a, b, d]
26
+ end
27
+
28
+ specify '2 + 3 4' do
29
+ a = LexicalUnit.numeric('2')
30
+ b = LexicalUnit.operator('+')
31
+ c = LexicalUnit.numeric('3')
32
+ d = LexicalUnit.numeric('4')
33
+ added = LexicalUnit.operator('*')
34
+ sya = Sya.new([a, b, c, d])
35
+
36
+ # + 2 * 3 4
37
+ expect(sya.run).to eq [b, a, added, c, d]
38
+ end
39
+
40
+ specify '2 pi' do
41
+ a = LexicalUnit.numeric('2')
42
+ b = LexicalUnit.constant('pi')
43
+ added = LexicalUnit.operator('*')
44
+ sya = Sya.new([a, b])
45
+
46
+ # * 2 pi
47
+ expect(sya.run).to eq [added, a, b]
48
+ end
49
+
50
+ specify '2 11K' do
51
+ a = LexicalUnit.numeric('2')
52
+ b = LexicalUnit.constant('11K')
53
+ added = LexicalUnit.operator('*')
54
+ sya = Sya.new([a, b])
55
+
56
+ # * 2 11K
57
+ expect(sya.run).to eq [added, a, b]
58
+ end
59
+
60
+ specify 'sqrt(49) + 1' do
61
+ a = LexicalUnit.fname('sqrt')
62
+ b = LexicalUnit.open_parenthesis
63
+ c = LexicalUnit.numeric('49')
64
+ d = LexicalUnit.closed_parenthesis
65
+ e = LexicalUnit.operator('+')
66
+ f = LexicalUnit.numeric('1')
67
+ sya = Sya.new([a, b, c, d, e, f])
68
+
69
+ # + sqrt 49 1
70
+ expect(sya.run).to eq [e, a, c, f]
71
+ end
72
+
73
+ specify '1 + sqrt(7)' do
74
+ a = LexicalUnit.numeric('1')
75
+ b = LexicalUnit.operator('+')
76
+ c = LexicalUnit.fname('sqrt')
77
+ d = LexicalUnit.open_parenthesis
78
+ e = LexicalUnit.numeric('7')
79
+ f = LexicalUnit.closed_parenthesis
80
+ sya = Sya.new([a, b, c, d, e, f])
81
+
82
+ # + 1 sqrt 7
83
+ expect(sya.run).to eq [b, a, c, e]
84
+ end
85
+
86
+ specify '3 / 2 + 1' do
87
+ a = LexicalUnit.numeric('3')
88
+ b = LexicalUnit.operator('/')
89
+ c = LexicalUnit.numeric('2')
90
+ d = LexicalUnit.operator('+')
91
+ e = LexicalUnit.numeric('1')
92
+ sya = Sya.new([a, b, c, d, e])
93
+
94
+ # + / 3 2 1
95
+ expect(sya.run).to eq [d, b, a, c, e]
96
+ end
97
+
98
+ specify '2 - 3 + 5' do
99
+ a = LexicalUnit.numeric('2')
100
+ b = LexicalUnit.operator('-')
101
+ c = LexicalUnit.numeric('3')
102
+ d = LexicalUnit.operator('+')
103
+ e = LexicalUnit.numeric('5')
104
+ sya = Sya.new([a, b, c, d, e])
105
+
106
+ # + - 2 3 5
107
+ expect(sya.run).to eq [d, b, a, c, e]
108
+ end
109
+
110
+ specify '1 - 1 + 4 - 1 - 1' do
111
+ a = LexicalUnit.numeric('1')
112
+ b = LexicalUnit.operator('-')
113
+ c = LexicalUnit.numeric('1')
114
+ d = LexicalUnit.operator('+')
115
+ e = LexicalUnit.numeric('4')
116
+ f = LexicalUnit.operator('-')
117
+ g = LexicalUnit.numeric('1')
118
+ h = LexicalUnit.operator('-')
119
+ i = LexicalUnit.numeric('1')
120
+ sya = Sya.new([a, b, c, d, e, f, g, h, i])
121
+
122
+ # - - + - 1 1 4 1 1
123
+ expect(sya.run).to eq [b, b, d, b, a, c, e, g, i]
124
+ end
125
+
126
+ specify '3 / (2 + 1)' do
127
+ a = LexicalUnit.numeric('3')
128
+ b = LexicalUnit.operator('/')
129
+ c = LexicalUnit.open_parenthesis
130
+ d = LexicalUnit.numeric('2')
131
+ e = LexicalUnit.operator('+')
132
+ f = LexicalUnit.numeric('1')
133
+ g = LexicalUnit.closed_parenthesis
134
+ sya = Sya.new([a, b, c, d, e, f, g])
135
+
136
+ # / 3 + 2 1
137
+ expect(sya.run).to eq [b, a, e, d, f]
138
+ end
139
+
140
+ specify 'sqrt(40 + 9)' do
141
+ a = LexicalUnit.fname('sqrt')
142
+ b = LexicalUnit.open_parenthesis
143
+ c = LexicalUnit.numeric('40')
144
+ d = LexicalUnit.operator('+')
145
+ e = LexicalUnit.numeric('9')
146
+ f = LexicalUnit.closed_parenthesis
147
+ sya = Sya.new([a, b, c, d, e, f])
148
+
149
+ # sqrt + 40 9
150
+ expect(sya.run).to eq [a, d, c, e]
151
+ end
152
+
153
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ include Electr
4
+
5
+ describe Tokenizer do
6
+
7
+ describe "#has_more_token?" do
8
+ it "returns true when a token is available" do
9
+ tkr = Tokenizer.new("2 3")
10
+ expect(tkr.has_more_token?).to eq true
11
+ tkr.next_token
12
+ expect(tkr.has_more_token?).to eq true
13
+ end
14
+
15
+ it "returns false when no more tokens are available" do
16
+ tkr = Tokenizer.new("0")
17
+ tkr.next_token
18
+ expect(tkr.has_more_token?).to eq false
19
+ end
20
+ end
21
+
22
+ specify "21 300" do
23
+ tkr = Tokenizer.new("21 300")
24
+ expect(tkr.next_token).to eq "21"
25
+ expect(tkr.next_token).to eq "300"
26
+ end
27
+
28
+ specify "2 0.6" do
29
+ tkr = Tokenizer.new("2 0.6")
30
+ expect(tkr.next_token).to eq "2"
31
+ expect(tkr.next_token).to eq "0.6"
32
+ end
33
+
34
+ specify "2 0.6 3" do
35
+ tkr = Tokenizer.new("2 0.6 3")
36
+ expect(tkr.next_token).to eq "2"
37
+ expect(tkr.next_token).to eq "0.6"
38
+ expect(tkr.next_token).to eq "3"
39
+ end
40
+
41
+ specify "2 + 3" do
42
+ tkr = Tokenizer.new("2 + 3")
43
+ expect(tkr.next_token).to eq "2"
44
+ expect(tkr.next_token).to eq "+"
45
+ expect(tkr.next_token).to eq "3"
46
+ end
47
+
48
+ specify "2 pi" do
49
+ tkr = Tokenizer.new("2 pi")
50
+ expect(tkr.next_token).to eq "2"
51
+ expect(tkr.next_token).to eq "pi"
52
+ end
53
+
54
+ specify "11K 22k 33kΩ" do
55
+ tkr = Tokenizer.new("11K 22k 33kΩ")
56
+ expect(tkr.next_token).to eq "11K"
57
+ expect(tkr.next_token).to eq "22k"
58
+ expect(tkr.next_token).to eq "33kΩ"
59
+ end
60
+
61
+ specify "100R 200Ω" do
62
+ tkr = Tokenizer.new("100R 200Ω")
63
+ expect(tkr.next_token).to eq "100R"
64
+ expect(tkr.next_token).to eq "200Ω"
65
+ end
66
+
67
+ specify "10uF 100u 470μF 1000μ 10pF 100p" do
68
+ tkr = Tokenizer.new("10uF 100u 470μF 1000μ 10pF 100p")
69
+ expect(tkr.next_token).to eq "10uF"
70
+ expect(tkr.next_token).to eq "100u"
71
+ expect(tkr.next_token).to eq "470μF"
72
+ expect(tkr.next_token).to eq "1000μ"
73
+ expect(tkr.next_token).to eq "10pF"
74
+ expect(tkr.next_token).to eq "100p"
75
+ end
76
+
77
+ specify "sqrt(11k 22k)" do
78
+ tkr = Tokenizer.new("sqrt(11k 22k)")
79
+ expect(tkr.next_token).to eq "sqrt"
80
+ expect(tkr.next_token).to eq "("
81
+ expect(tkr.next_token).to eq "11k"
82
+ expect(tkr.next_token).to eq "22k"
83
+ expect(tkr.next_token).to eq ")"
84
+ end
85
+
86
+ specify "1 / (2 pi 0.5uF sqrt(11K 22K))" do
87
+ tkr = Tokenizer.new("1 / (2 pi 0.5uF sqrt(11K 22K))")
88
+ expect(tkr.next_token).to eq "1"
89
+ expect(tkr.next_token).to eq "/"
90
+ expect(tkr.next_token).to eq "("
91
+ expect(tkr.next_token).to eq "2"
92
+ expect(tkr.next_token).to eq "pi"
93
+ expect(tkr.next_token).to eq "0.5uF"
94
+ expect(tkr.next_token).to eq "sqrt"
95
+ expect(tkr.next_token).to eq "("
96
+ expect(tkr.next_token).to eq "11K"
97
+ expect(tkr.next_token).to eq "22K"
98
+ expect(tkr.next_token).to eq ")"
99
+ expect(tkr.next_token).to eq ")"
100
+ end
101
+
102
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: electr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - lkdjiin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email:
57
+ - xavier.nayrac@gmail.com
58
+ executables:
59
+ - electr
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - ".rspec"
65
+ - ".travis.yml"
66
+ - CHANGELOG.md
67
+ - Gemfile
68
+ - LICENSE.txt
69
+ - README.md
70
+ - Rakefile
71
+ - bin/electr
72
+ - electr.gemspec
73
+ - lib/electr.rb
74
+ - lib/electr/ast.rb
75
+ - lib/electr/ast/ast.rb
76
+ - lib/electr/ast/constant_ast.rb
77
+ - lib/electr/ast/func_args_ast.rb
78
+ - lib/electr/ast/func_ast.rb
79
+ - lib/electr/ast/func_name_ast.rb
80
+ - lib/electr/ast/numeric_ast.rb
81
+ - lib/electr/ast/operator_ast.rb
82
+ - lib/electr/ast/root_ast.rb
83
+ - lib/electr/ast/value_ast.rb
84
+ - lib/electr/compiler.rb
85
+ - lib/electr/evaluator.rb
86
+ - lib/electr/exceptions.rb
87
+ - lib/electr/option.rb
88
+ - lib/electr/parser.rb
89
+ - lib/electr/parser/lexer.rb
90
+ - lib/electr/parser/lexical_unit.rb
91
+ - lib/electr/parser/rules/base_rule.rb
92
+ - lib/electr/parser/rules/expression_rule.rb
93
+ - lib/electr/parser/rules/root_rule.rb
94
+ - lib/electr/parser/sya.rb
95
+ - lib/electr/parser/syntaxer.rb
96
+ - lib/electr/parser/tokenizer.rb
97
+ - lib/electr/repl.rb
98
+ - lib/electr/rules.rb
99
+ - lib/electr/version.rb
100
+ - spec/compiler_spec.rb
101
+ - spec/electr_spec.rb
102
+ - spec/evaluator_spec.rb
103
+ - spec/lexer_spec.rb
104
+ - spec/spec_helper.rb
105
+ - spec/sya_spec.rb
106
+ - spec/tokenizer_spec.rb
107
+ homepage: https://github.com/lkdjiin/electr
108
+ licenses:
109
+ - MIT
110
+ metadata: {}
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '2.2'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubyforge_project:
127
+ rubygems_version: 2.4.5
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: Interactive language for electronic formulas
131
+ test_files:
132
+ - spec/compiler_spec.rb
133
+ - spec/electr_spec.rb
134
+ - spec/evaluator_spec.rb
135
+ - spec/lexer_spec.rb
136
+ - spec/spec_helper.rb
137
+ - spec/sya_spec.rb
138
+ - spec/tokenizer_spec.rb