keisan 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +4 -0
  6. data/MIT-LICENSE +19 -0
  7. data/README.md +188 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +10 -0
  10. data/bin/setup +8 -0
  11. data/keisan.gemspec +31 -0
  12. data/lib/keisan.rb +118 -0
  13. data/lib/keisan/ast/arithmetic_operator.rb +9 -0
  14. data/lib/keisan/ast/bitwise_and.rb +21 -0
  15. data/lib/keisan/ast/bitwise_operator.rb +9 -0
  16. data/lib/keisan/ast/bitwise_or.rb +21 -0
  17. data/lib/keisan/ast/bitwise_xor.rb +21 -0
  18. data/lib/keisan/ast/boolean.rb +15 -0
  19. data/lib/keisan/ast/builder.rb +141 -0
  20. data/lib/keisan/ast/exponent.rb +25 -0
  21. data/lib/keisan/ast/function.rb +19 -0
  22. data/lib/keisan/ast/indexing.rb +16 -0
  23. data/lib/keisan/ast/list.rb +10 -0
  24. data/lib/keisan/ast/literal.rb +6 -0
  25. data/lib/keisan/ast/logical_and.rb +21 -0
  26. data/lib/keisan/ast/logical_greater_than.rb +17 -0
  27. data/lib/keisan/ast/logical_greater_than_or_equal_to.rb +17 -0
  28. data/lib/keisan/ast/logical_less_than.rb +17 -0
  29. data/lib/keisan/ast/logical_less_than_or_equal_to.rb +17 -0
  30. data/lib/keisan/ast/logical_operator.rb +9 -0
  31. data/lib/keisan/ast/logical_or.rb +21 -0
  32. data/lib/keisan/ast/node.rb +9 -0
  33. data/lib/keisan/ast/null.rb +12 -0
  34. data/lib/keisan/ast/number.rb +15 -0
  35. data/lib/keisan/ast/operator.rb +50 -0
  36. data/lib/keisan/ast/parent.rb +15 -0
  37. data/lib/keisan/ast/plus.rb +49 -0
  38. data/lib/keisan/ast/string.rb +15 -0
  39. data/lib/keisan/ast/times.rb +36 -0
  40. data/lib/keisan/ast/unary_bitwise_not.rb +9 -0
  41. data/lib/keisan/ast/unary_identity.rb +9 -0
  42. data/lib/keisan/ast/unary_inverse.rb +9 -0
  43. data/lib/keisan/ast/unary_logical_not.rb +9 -0
  44. data/lib/keisan/ast/unary_minus.rb +9 -0
  45. data/lib/keisan/ast/unary_operator.rb +13 -0
  46. data/lib/keisan/ast/unary_plus.rb +9 -0
  47. data/lib/keisan/ast/variable.rb +16 -0
  48. data/lib/keisan/calculator.rb +30 -0
  49. data/lib/keisan/context.rb +36 -0
  50. data/lib/keisan/exceptions.rb +19 -0
  51. data/lib/keisan/function.rb +15 -0
  52. data/lib/keisan/functions/default_registry.rb +58 -0
  53. data/lib/keisan/functions/rand.rb +22 -0
  54. data/lib/keisan/functions/registry.rb +50 -0
  55. data/lib/keisan/functions/sample.rb +20 -0
  56. data/lib/keisan/parser.rb +211 -0
  57. data/lib/keisan/parsing/argument.rb +6 -0
  58. data/lib/keisan/parsing/arithmetic_operator.rb +6 -0
  59. data/lib/keisan/parsing/bitwise_and.rb +9 -0
  60. data/lib/keisan/parsing/bitwise_not.rb +9 -0
  61. data/lib/keisan/parsing/bitwise_not_not.rb +9 -0
  62. data/lib/keisan/parsing/bitwise_operator.rb +6 -0
  63. data/lib/keisan/parsing/bitwise_or.rb +9 -0
  64. data/lib/keisan/parsing/bitwise_xor.rb +9 -0
  65. data/lib/keisan/parsing/boolean.rb +11 -0
  66. data/lib/keisan/parsing/component.rb +6 -0
  67. data/lib/keisan/parsing/divide.rb +9 -0
  68. data/lib/keisan/parsing/element.rb +6 -0
  69. data/lib/keisan/parsing/exponent.rb +9 -0
  70. data/lib/keisan/parsing/function.rb +12 -0
  71. data/lib/keisan/parsing/group.rb +11 -0
  72. data/lib/keisan/parsing/indexing.rb +14 -0
  73. data/lib/keisan/parsing/list.rb +10 -0
  74. data/lib/keisan/parsing/logical_and.rb +9 -0
  75. data/lib/keisan/parsing/logical_greater_than.rb +9 -0
  76. data/lib/keisan/parsing/logical_greater_than_or_equal_to.rb +9 -0
  77. data/lib/keisan/parsing/logical_less_than.rb +9 -0
  78. data/lib/keisan/parsing/logical_less_than_or_equal_to.rb +9 -0
  79. data/lib/keisan/parsing/logical_not.rb +9 -0
  80. data/lib/keisan/parsing/logical_not_not.rb +9 -0
  81. data/lib/keisan/parsing/logical_operator.rb +6 -0
  82. data/lib/keisan/parsing/logical_or.rb +9 -0
  83. data/lib/keisan/parsing/minus.rb +9 -0
  84. data/lib/keisan/parsing/null.rb +6 -0
  85. data/lib/keisan/parsing/number.rb +10 -0
  86. data/lib/keisan/parsing/operator.rb +13 -0
  87. data/lib/keisan/parsing/plus.rb +9 -0
  88. data/lib/keisan/parsing/round_group.rb +6 -0
  89. data/lib/keisan/parsing/square_group.rb +6 -0
  90. data/lib/keisan/parsing/string.rb +10 -0
  91. data/lib/keisan/parsing/times.rb +9 -0
  92. data/lib/keisan/parsing/unary_minus.rb +9 -0
  93. data/lib/keisan/parsing/unary_operator.rb +9 -0
  94. data/lib/keisan/parsing/unary_plus.rb +9 -0
  95. data/lib/keisan/parsing/variable.rb +11 -0
  96. data/lib/keisan/token.rb +25 -0
  97. data/lib/keisan/tokenizer.rb +41 -0
  98. data/lib/keisan/tokens/arithmetic_operator.rb +29 -0
  99. data/lib/keisan/tokens/bitwise_operator.rb +29 -0
  100. data/lib/keisan/tokens/boolean.rb +20 -0
  101. data/lib/keisan/tokens/comma.rb +11 -0
  102. data/lib/keisan/tokens/group.rb +28 -0
  103. data/lib/keisan/tokens/logical_operator.rb +38 -0
  104. data/lib/keisan/tokens/null.rb +15 -0
  105. data/lib/keisan/tokens/number.rb +24 -0
  106. data/lib/keisan/tokens/operator.rb +9 -0
  107. data/lib/keisan/tokens/string.rb +15 -0
  108. data/lib/keisan/tokens/word.rb +11 -0
  109. data/lib/keisan/variables/default_registry.rb +20 -0
  110. data/lib/keisan/variables/registry.rb +41 -0
  111. data/lib/keisan/version.rb +3 -0
  112. metadata +238 -0
@@ -0,0 +1,38 @@
1
+ module Keisan
2
+ module Tokens
3
+ class LogicalOperator < Operator
4
+ LESS_THAN_OR_EQUAL_TO = /(?:\<\=)/
5
+ GREATER_THAN_OR_EQUAL_TO = /(?:\>\=)/
6
+ LESS_THAN = /(?:\<)/
7
+ GREATER_THAN = /(?:\>)/
8
+ AND = /(?:\&\&)/
9
+ OR = /(?:\|\|)/
10
+ NOT = /(?:\!+)/
11
+
12
+ REGEX = /(#{LESS_THAN_OR_EQUAL_TO}|#{GREATER_THAN_OR_EQUAL_TO}|#{LESS_THAN}|#{GREATER_THAN}|#{AND}|#{OR}|#{NOT})/
13
+
14
+ def self.regex
15
+ REGEX
16
+ end
17
+
18
+ def operator_type
19
+ case string
20
+ when LESS_THAN_OR_EQUAL_TO
21
+ :<=
22
+ when GREATER_THAN_OR_EQUAL_TO
23
+ :>=
24
+ when LESS_THAN
25
+ :<
26
+ when GREATER_THAN
27
+ :>
28
+ when AND
29
+ :"&&"
30
+ when OR
31
+ :"||"
32
+ when NOT
33
+ string.count("!").even? ? :"!!" : :"!"
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ module Keisan
2
+ module Tokens
3
+ class Null < Token
4
+ REGEX = /(\bnil\b)/
5
+
6
+ def self.regex
7
+ REGEX
8
+ end
9
+
10
+ def value
11
+ nil
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ module Keisan
2
+ module Tokens
3
+ class Number < Token
4
+ INTEGER_REGEX = /\d+/
5
+ FLOATING_POINT_REGEX = /\d+\.\d+/
6
+ SCIENTIFC_NOTATION_REGEX = /\d+(?:\.\d+)e(?:\+|\-)?\d+/
7
+
8
+ REGEX = /(\d+(?:\.\d+)?(?:e(?:\+|\-)?\d+)?)/
9
+
10
+ def self.regex
11
+ REGEX
12
+ end
13
+
14
+ def value
15
+ case string
16
+ when SCIENTIFC_NOTATION_REGEX, FLOATING_POINT_REGEX
17
+ Float(string)
18
+ when INTEGER_REGEX
19
+ Integer(string)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ module Keisan
2
+ module Tokens
3
+ class Operator < Token
4
+ def type
5
+ :operator
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,15 @@
1
+ module Keisan
2
+ module Tokens
3
+ class String < Token
4
+ REGEX = /(\"[^\"\']*\"|\'[^\"\']*\')/
5
+
6
+ def self.regex
7
+ REGEX
8
+ end
9
+
10
+ def value
11
+ string[1...-1]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ module Keisan
2
+ module Tokens
3
+ class Word < Token
4
+ REGEX = /([a-zA-Z0-9_]*[a-zA-Z][a-zA-Z0-9_]*)/
5
+
6
+ def self.regex
7
+ REGEX
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ module Keisan
2
+ module Variables
3
+ class DefaultRegistry < Registry
4
+ def initialize
5
+ @hash = {}
6
+ @parent = self.class.registry
7
+ end
8
+
9
+ VARIABLES = {
10
+ "pi" => Math::PI,
11
+ "e" => Math::E,
12
+ "i" => Complex(0,1)
13
+ }
14
+
15
+ def self.registry
16
+ @registry ||= Registry.new(variables: VARIABLES, parent: nil).freeze
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,41 @@
1
+ module Keisan
2
+ module Variables
3
+ class Registry
4
+ def initialize(variables: {}, parent: nil, use_defaults: true)
5
+ @hash = {}
6
+ @parent = parent
7
+ @use_defaults = use_defaults
8
+
9
+ variables.each do |name, value|
10
+ register!(name, value)
11
+ end
12
+ end
13
+
14
+ def [](name)
15
+ return @hash[name] if @hash.has_key?(name)
16
+ return @parent[name] if @parent.present? && @parent.has_name?(name)
17
+ return default_registry[name] if @use_defaults && default_registry.has_name?(name)
18
+ raise Keisan::Exceptions::UndefinedVariableError.new name
19
+ end
20
+
21
+ def has_name?(name)
22
+ @hash.has_key?(name)
23
+ end
24
+
25
+ def register!(name, value)
26
+ raise Keisan::Exceptions::UnmodifiableError.new("Cannot modify frozen variables registry") if frozen?
27
+ self[name.to_s] = value
28
+ end
29
+
30
+ private
31
+
32
+ def []=(name, value)
33
+ @hash[name] = value
34
+ end
35
+
36
+ def default_registry
37
+ DefaultRegistry.registry
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,3 @@
1
+ module Keisan
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,238 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: keisan
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Christopher Locke
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.2.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 4.2.2
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.14'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.14'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry-stack_explorer
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description: A library for parsing equations into an abstract syntax tree for evaluation
98
+ email:
99
+ - project.eutopia@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".travis.yml"
107
+ - Gemfile
108
+ - MIT-LICENSE
109
+ - README.md
110
+ - Rakefile
111
+ - bin/console
112
+ - bin/setup
113
+ - keisan.gemspec
114
+ - lib/keisan.rb
115
+ - lib/keisan/ast/arithmetic_operator.rb
116
+ - lib/keisan/ast/bitwise_and.rb
117
+ - lib/keisan/ast/bitwise_operator.rb
118
+ - lib/keisan/ast/bitwise_or.rb
119
+ - lib/keisan/ast/bitwise_xor.rb
120
+ - lib/keisan/ast/boolean.rb
121
+ - lib/keisan/ast/builder.rb
122
+ - lib/keisan/ast/exponent.rb
123
+ - lib/keisan/ast/function.rb
124
+ - lib/keisan/ast/indexing.rb
125
+ - lib/keisan/ast/list.rb
126
+ - lib/keisan/ast/literal.rb
127
+ - lib/keisan/ast/logical_and.rb
128
+ - lib/keisan/ast/logical_greater_than.rb
129
+ - lib/keisan/ast/logical_greater_than_or_equal_to.rb
130
+ - lib/keisan/ast/logical_less_than.rb
131
+ - lib/keisan/ast/logical_less_than_or_equal_to.rb
132
+ - lib/keisan/ast/logical_operator.rb
133
+ - lib/keisan/ast/logical_or.rb
134
+ - lib/keisan/ast/node.rb
135
+ - lib/keisan/ast/null.rb
136
+ - lib/keisan/ast/number.rb
137
+ - lib/keisan/ast/operator.rb
138
+ - lib/keisan/ast/parent.rb
139
+ - lib/keisan/ast/plus.rb
140
+ - lib/keisan/ast/string.rb
141
+ - lib/keisan/ast/times.rb
142
+ - lib/keisan/ast/unary_bitwise_not.rb
143
+ - lib/keisan/ast/unary_identity.rb
144
+ - lib/keisan/ast/unary_inverse.rb
145
+ - lib/keisan/ast/unary_logical_not.rb
146
+ - lib/keisan/ast/unary_minus.rb
147
+ - lib/keisan/ast/unary_operator.rb
148
+ - lib/keisan/ast/unary_plus.rb
149
+ - lib/keisan/ast/variable.rb
150
+ - lib/keisan/calculator.rb
151
+ - lib/keisan/context.rb
152
+ - lib/keisan/exceptions.rb
153
+ - lib/keisan/function.rb
154
+ - lib/keisan/functions/default_registry.rb
155
+ - lib/keisan/functions/rand.rb
156
+ - lib/keisan/functions/registry.rb
157
+ - lib/keisan/functions/sample.rb
158
+ - lib/keisan/parser.rb
159
+ - lib/keisan/parsing/argument.rb
160
+ - lib/keisan/parsing/arithmetic_operator.rb
161
+ - lib/keisan/parsing/bitwise_and.rb
162
+ - lib/keisan/parsing/bitwise_not.rb
163
+ - lib/keisan/parsing/bitwise_not_not.rb
164
+ - lib/keisan/parsing/bitwise_operator.rb
165
+ - lib/keisan/parsing/bitwise_or.rb
166
+ - lib/keisan/parsing/bitwise_xor.rb
167
+ - lib/keisan/parsing/boolean.rb
168
+ - lib/keisan/parsing/component.rb
169
+ - lib/keisan/parsing/divide.rb
170
+ - lib/keisan/parsing/element.rb
171
+ - lib/keisan/parsing/exponent.rb
172
+ - lib/keisan/parsing/function.rb
173
+ - lib/keisan/parsing/group.rb
174
+ - lib/keisan/parsing/indexing.rb
175
+ - lib/keisan/parsing/list.rb
176
+ - lib/keisan/parsing/logical_and.rb
177
+ - lib/keisan/parsing/logical_greater_than.rb
178
+ - lib/keisan/parsing/logical_greater_than_or_equal_to.rb
179
+ - lib/keisan/parsing/logical_less_than.rb
180
+ - lib/keisan/parsing/logical_less_than_or_equal_to.rb
181
+ - lib/keisan/parsing/logical_not.rb
182
+ - lib/keisan/parsing/logical_not_not.rb
183
+ - lib/keisan/parsing/logical_operator.rb
184
+ - lib/keisan/parsing/logical_or.rb
185
+ - lib/keisan/parsing/minus.rb
186
+ - lib/keisan/parsing/null.rb
187
+ - lib/keisan/parsing/number.rb
188
+ - lib/keisan/parsing/operator.rb
189
+ - lib/keisan/parsing/plus.rb
190
+ - lib/keisan/parsing/round_group.rb
191
+ - lib/keisan/parsing/square_group.rb
192
+ - lib/keisan/parsing/string.rb
193
+ - lib/keisan/parsing/times.rb
194
+ - lib/keisan/parsing/unary_minus.rb
195
+ - lib/keisan/parsing/unary_operator.rb
196
+ - lib/keisan/parsing/unary_plus.rb
197
+ - lib/keisan/parsing/variable.rb
198
+ - lib/keisan/token.rb
199
+ - lib/keisan/tokenizer.rb
200
+ - lib/keisan/tokens/arithmetic_operator.rb
201
+ - lib/keisan/tokens/bitwise_operator.rb
202
+ - lib/keisan/tokens/boolean.rb
203
+ - lib/keisan/tokens/comma.rb
204
+ - lib/keisan/tokens/group.rb
205
+ - lib/keisan/tokens/logical_operator.rb
206
+ - lib/keisan/tokens/null.rb
207
+ - lib/keisan/tokens/number.rb
208
+ - lib/keisan/tokens/operator.rb
209
+ - lib/keisan/tokens/string.rb
210
+ - lib/keisan/tokens/word.rb
211
+ - lib/keisan/variables/default_registry.rb
212
+ - lib/keisan/variables/registry.rb
213
+ - lib/keisan/version.rb
214
+ homepage: https://github.com/project-eutopia/keisan
215
+ licenses:
216
+ - MIT
217
+ metadata: {}
218
+ post_install_message:
219
+ rdoc_options: []
220
+ require_paths:
221
+ - lib
222
+ required_ruby_version: !ruby/object:Gem::Requirement
223
+ requirements:
224
+ - - ">="
225
+ - !ruby/object:Gem::Version
226
+ version: 2.4.0
227
+ required_rubygems_version: !ruby/object:Gem::Requirement
228
+ requirements:
229
+ - - ">="
230
+ - !ruby/object:Gem::Version
231
+ version: '0'
232
+ requirements: []
233
+ rubyforge_project:
234
+ rubygems_version: 2.6.11
235
+ signing_key:
236
+ specification_version: 4
237
+ summary: An equation parser and evaluator
238
+ test_files: []