keisan 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2d556d5ef3e67015596fee5856e2fe0b27295b227f7d4edf8cb41c037aed98b
4
- data.tar.gz: c8c20ac6ba6a9ad27654931238a2dbafcbbbc509b58fd2a74161b7a38b3edaab
3
+ metadata.gz: 25f0cd7f7a5bd124a62c244a270bb4db0632fc0ce295d7f55fa25409eae66473
4
+ data.tar.gz: 5cdeae27276969608966b56891abe91fe8b2bddaef9f7ef3fdeb6a3fe6696176
5
5
  SHA512:
6
- metadata.gz: 9ccc5172adc0b5ebafabe3cd5846fb455ada6e1351c94deab4da5bfd38617c0e0692258e9384d760d25b88a899b46de1899b1688850bfac8ddcdd432091ddf50
7
- data.tar.gz: cb2ca195319a744f3ee9b56ef7df14d8dfcf36dbcafcbe1e675a858f232457d39cb3fe96d7f056a26746630d4a7f1c47a8fe6fc75a880683cd2120428a448ff6
6
+ metadata.gz: 32d761e97663ad54bc37d2e3894875068daa8567ae521dd877879a94f66417c752cc338eba7f1a06bbe23f2a1455fce7751690323fcf4948f243d8254c69f1b4
7
+ data.tar.gz: 6c62bfc43752fe4918022e0217227c4a31d1fae6225bf70d65bc61afb025dbef5af74597055b1216a4ef9d261252e2f2d9ac26467319e33c4c842a2764711053
data/.travis.yml CHANGED
@@ -1,7 +1,9 @@
1
1
  sudo: false
2
2
  language: ruby
3
+ before_install:
4
+ - gem install bundler
3
5
  rvm:
4
- - 2.3.6
5
- - 2.4.3
6
- - 2.5.0
7
- before_install: gem install bundler -v 1.16.1
6
+ - 2.4.9
7
+ - 2.5.7
8
+ - 2.6.5
9
+ - 2.7.0
data/README.md CHANGED
@@ -340,7 +340,7 @@ calculator.evaluate("[2, 3, 7, 11].has_element(11)")
340
340
 
341
341
  ##### Bitwise operations
342
342
 
343
- The basic bitwise operations, NOT `~`, OR `|`, XOR `^`, and AND `&` are also available for use
343
+ The basic bitwise operations, NOT `~`, OR `|`, XOR `^`, AND `&`, and left/right bitwise shifts (`<<` and `>>`) are also available for use
344
344
 
345
345
  ```ruby
346
346
  calculator = Keisan::Calculator.new
@@ -485,6 +485,7 @@ calculator.evaluate("puts x**2") # prints "25\n" to STDOUT
485
485
 
486
486
  #### Bitwise operators
487
487
  - `&`, `|`, `^`: bitwise **and**, **or**, **xor** operators
488
+ - `<<`, `>>` bitwise shift operators
488
489
  - `~`: unary bitwise not
489
490
 
490
491
  #### Indexing of arrays/hashes
data/keisan.gemspec CHANGED
@@ -21,10 +21,12 @@ Gem::Specification.new do |spec|
21
21
 
22
22
  spec.required_ruby_version = ">= 2.3.0"
23
23
 
24
- spec.add_development_dependency "coveralls"
25
- spec.add_development_dependency "bundler", "~> 1.14"
26
- spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_dependency "cmath", "~> 1.0"
25
+
26
+ spec.add_development_dependency "bundler", "~> 2.0"
27
+ spec.add_development_dependency "rake", "~> 13.0"
27
28
  spec.add_development_dependency "rspec", "~> 3.0"
28
29
  spec.add_development_dependency "pry"
29
30
  spec.add_development_dependency "pry-stack_explorer"
31
+ spec.add_development_dependency "simplecov"
30
32
  end
data/lib/keisan.rb CHANGED
@@ -37,6 +37,8 @@ require "keisan/ast/bitwise_operator"
37
37
  require "keisan/ast/bitwise_and"
38
38
  require "keisan/ast/bitwise_or"
39
39
  require "keisan/ast/bitwise_xor"
40
+ require "keisan/ast/bitwise_left_shift"
41
+ require "keisan/ast/bitwise_right_shift"
40
42
  require "keisan/ast/logical_operator"
41
43
  require "keisan/ast/logical_and"
42
44
  require "keisan/ast/logical_or"
@@ -78,10 +80,12 @@ require "keisan/tokens/assignment"
78
80
  require "keisan/tokens/arithmetic_operator"
79
81
  require "keisan/tokens/logical_operator"
80
82
  require "keisan/tokens/bitwise_operator"
83
+ require "keisan/tokens/bitwise_shift"
81
84
  require "keisan/tokens/word"
82
85
  require "keisan/tokens/line_separator"
83
86
  require "keisan/tokens/unknown"
84
87
 
88
+ require "keisan/string_and_group_parser"
85
89
  require "keisan/tokenizer"
86
90
 
87
91
  require "keisan/parsing/component"
@@ -128,6 +132,8 @@ require "keisan/parsing/bitwise_or"
128
132
  require "keisan/parsing/bitwise_xor"
129
133
  require "keisan/parsing/bitwise_not"
130
134
  require "keisan/parsing/bitwise_not_not"
135
+ require "keisan/parsing/bitwise_left_shift"
136
+ require "keisan/parsing/bitwise_right_shift"
131
137
  require "keisan/parsing/logical_operator"
132
138
  require "keisan/parsing/logical_less_than"
133
139
  require "keisan/parsing/logical_greater_than"
@@ -0,0 +1,17 @@
1
+ module Keisan
2
+ module AST
3
+ class BitwiseLeftShift < BitwiseOperator
4
+ def self.symbol
5
+ :<<
6
+ end
7
+
8
+ def blank_value
9
+ 0
10
+ end
11
+
12
+ def evaluate(context = nil)
13
+ children[1..-1].inject(children.first.evaluate(context)) {|total, child| total << child.evaluate(context)}
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module Keisan
2
+ module AST
3
+ class BitwiseRightShift < BitwiseOperator
4
+ def self.symbol
5
+ :>>
6
+ end
7
+
8
+ def blank_value
9
+ 0
10
+ end
11
+
12
+ def evaluate(context = nil)
13
+ children[1..-1].inject(children.first.evaluate(context)) {|total, child| total >> child.evaluate(context)}
14
+ end
15
+ end
16
+ end
17
+ end
@@ -45,10 +45,18 @@ module Keisan
45
45
  raise Exceptions::NonDifferentiableError.new
46
46
  end
47
47
 
48
+ def differentiated(variable, context = nil)
49
+ deep_dup.differentiate(variable, context)
50
+ end
51
+
48
52
  def replace(variable, replacement)
49
53
  self
50
54
  end
51
55
 
56
+ def replaced(variable, replacement)
57
+ deep_dup.replace(variable, replacement)
58
+ end
59
+
52
60
  def coerce(other)
53
61
  [other.to_node, self]
54
62
  end
@@ -132,6 +140,14 @@ module Keisan
132
140
  BitwiseOr.new([self, other.to_node])
133
141
  end
134
142
 
143
+ def <<(other)
144
+ BitwiseLeftShift.new([self, other.to_node])
145
+ end
146
+
147
+ def >>(other)
148
+ BitwiseRightShift.new([self, other.to_node])
149
+ end
150
+
135
151
  def >(other)
136
152
  LogicalGreaterThan.new([self, other.to_node])
137
153
  end
@@ -111,6 +111,26 @@ module Keisan
111
111
  end
112
112
  end
113
113
 
114
+ def <<(other)
115
+ other = other.to_node
116
+ case other
117
+ when Number
118
+ Number.new(value << other.value)
119
+ else
120
+ super
121
+ end
122
+ end
123
+
124
+ def >>(other)
125
+ other = other.to_node
126
+ case other
127
+ when Number
128
+ Number.new(value >> other.value)
129
+ else
130
+ super
131
+ end
132
+ end
133
+
114
134
  def >(other)
115
135
  other = other.to_node
116
136
  case other
@@ -13,6 +13,8 @@ module Keisan
13
13
  "%": [2, 85, :left], # Modulo
14
14
  "+": [2, 80, :left], # Plus
15
15
  # "-": [2, 80, :left], # Minus
16
+ "<<": [2, 75, :left], # Bitwise left shift
17
+ ">>": [2, 75, :left], # Bitwise right shift
16
18
  "&": [2, 70, :left], # Bitwise and
17
19
  "^": [2, 65, :left], # Bitwise xor
18
20
  "|": [2, 65, :left], # Bitwise or
@@ -19,7 +19,7 @@ module Keisan
19
19
  @children = [child.simplify(context)]
20
20
  case child
21
21
  when Number
22
- Number.new(Rational(1,child.value(context))).simplify(context)
22
+ Number.new(child.value**-1)
23
23
  else
24
24
  (child ** -1).simplify(context)
25
25
  end
@@ -13,7 +13,13 @@ module Keisan
13
13
 
14
14
  def value(context = nil)
15
15
  context ||= Context.new
16
- variable_node_from_context(context).value(context)
16
+ node = variable_node_from_context(context)
17
+ case node
18
+ when Variable
19
+ node
20
+ else
21
+ node.value(context)
22
+ end
17
23
  end
18
24
 
19
25
  def unbound_variables(context = nil)
@@ -78,9 +84,7 @@ module Keisan
78
84
 
79
85
  def variable_node_from_context(context)
80
86
  variable = context.variable(name)
81
- if variable.is_a?(Cell)
82
- variable = variable.node
83
- end
87
+ variable = variable.node if variable.is_a?(Cell)
84
88
  variable
85
89
  end
86
90
  end
@@ -4,7 +4,9 @@ module Keisan
4
4
  module Functions
5
5
  class CMathFunction < MathFunction
6
6
  def initialize(name, proc_function = nil)
7
- super(name, proc_function || Proc.new {|arg| CMath.send(name, arg)})
7
+ super(name, proc_function || Proc.new {|arg|
8
+ CMath.send(name, arg)
9
+ })
8
10
  end
9
11
  end
10
12
  end
@@ -5,7 +5,11 @@ module Keisan
5
5
 
6
6
  def initialize(name, arguments, expression, transient_definitions)
7
7
  super(name, arguments.count)
8
- @expression = expression.deep_dup
8
+ if expression.is_a?(::String)
9
+ @expression = AST::parse(expression)
10
+ else
11
+ @expression = expression.deep_dup
12
+ end
9
13
  @arguments = arguments
10
14
  @transient_definitions = transient_definitions
11
15
  end
@@ -70,17 +74,20 @@ module Keisan
70
74
 
71
75
  local = local_context_for(context)
72
76
 
73
- # expression.differentiate(variable, context)
74
-
75
- argument_values = ast_function.children.map {|child| child.evaluate(local)}
77
+ argument_values = ast_function.children.map {|child| child.evaluated(local)}
76
78
 
77
79
  argument_derivatives = ast_function.children.map do |child|
78
- child.differentiate(variable, context)
80
+ child.differentiated(variable, context)
79
81
  end
80
82
 
83
+ partial_derivatives = calculate_partial_derivatives(context)
84
+
81
85
  AST::Plus.new(
82
86
  argument_derivatives.map.with_index {|argument_derivative, i|
83
- partial_derivative = partial_derivatives[i].replace(argument_variables[i], argument_values[i])
87
+ partial_derivative = partial_derivatives[i]
88
+ argument_variables.each.with_index {|argument_variable, j|
89
+ partial_derivative = partial_derivative.replaced(argument_variable, argument_values[j])
90
+ }
84
91
  AST::Times.new([argument_derivative, partial_derivative])
85
92
  }
86
93
  )
@@ -92,9 +99,9 @@ module Keisan
92
99
  @argument_variables ||= arguments.map {|argument| AST::Variable.new(argument)}
93
100
  end
94
101
 
95
- def partial_derivatives
96
- @partial_derivatives ||= argument_variables.map.with_index do |variable, i|
97
- partial_derivative = expression.differentiate(variable)
102
+ def calculate_partial_derivatives(context)
103
+ argument_variables.map.with_index do |variable, i|
104
+ partial_derivative = expression.differentiated(variable, context)
98
105
  end
99
106
  end
100
107
 
@@ -28,7 +28,7 @@ module Keisan
28
28
 
29
29
  ast_function.instance_variable_set(
30
30
  :@children,
31
- ast_function.children.map {|child| child.evaluate(context).to_node}
31
+ ast_function.children.map {|child| child.simplify(context).to_node}
32
32
  )
33
33
 
34
34
  if ast_function.children.all? {|child| child.well_defined?(context)}
@@ -44,7 +44,7 @@ module Keisan
44
44
 
45
45
  ast_function.instance_variable_set(
46
46
  :@children,
47
- ast_function.children.map {|child| child.evaluate(context)}
47
+ ast_function.children.map {|child| child.simplify(context)}
48
48
  )
49
49
 
50
50
  if ast_function.children.all? {|child| child.is_a?(AST::ConstantLiteral)}
@@ -10,19 +10,19 @@ module Keisan
10
10
  evaluate(ast_function, context).value(context)
11
11
  end
12
12
 
13
- def evaluate(ast_function, context = nil)
13
+ def simplify(ast_function, context = nil)
14
14
  context ||= Context.new
15
15
  expression, variable, replacement = expression_variable_replacement(ast_function)
16
16
 
17
- expression = expression.evaluate(context)
18
- replacement = replacement.evaluate(context)
17
+ expression = expression.simplify(context)
18
+ replacement = replacement.simplify(context)
19
19
 
20
- expression.replace(variable, replacement).evaluate(context)
20
+ expression.replace(variable, replacement).simplify(context)
21
21
  end
22
22
 
23
- def simplify(ast_function, context = nil)
23
+ def evaluate(ast_function, context = nil)
24
24
  context ||= Context.new
25
- evaluate(ast_function, context).simplify(context)
25
+ simplify(ast_function, context).evaluate(context)
26
26
  end
27
27
 
28
28
  private
data/lib/keisan/parser.rb CHANGED
@@ -241,6 +241,8 @@ module Keisan
241
241
  :"&" => Parsing::BitwiseAnd,
242
242
  :"|" => Parsing::BitwiseOr,
243
243
  :"^" => Parsing::BitwiseXor,
244
+ :<< => Parsing::BitwiseLeftShift,
245
+ :>> => Parsing::BitwiseRightShift,
244
246
  :"==" => Parsing::LogicalEqual,
245
247
  :"!=" => Parsing::LogicalNotEqual,
246
248
  :"&&" => Parsing::LogicalAnd,
@@ -0,0 +1,9 @@
1
+ module Keisan
2
+ module Parsing
3
+ class BitwiseLeftShift < BitwiseOperator
4
+ def node_class
5
+ AST::BitwiseLeftShift
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Keisan
2
+ module Parsing
3
+ class BitwiseRightShift < BitwiseOperator
4
+ def node_class
5
+ AST::BitwiseRightShift
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,193 @@
1
+ module Keisan
2
+ class StringAndGroupParser
3
+ class Portion
4
+ attr_reader :start_index, :end_index
5
+
6
+ def initialize(start_index)
7
+ @start_index = start_index
8
+ end
9
+ end
10
+
11
+ class StringPortion < Portion
12
+ attr_reader :string
13
+
14
+ def initialize(expression, start_index)
15
+ super(start_index)
16
+
17
+ @string = expression[start_index]
18
+ @end_index = start_index + 1
19
+
20
+ while @end_index < expression.size
21
+ if expression[@end_index] == quote_type
22
+ @string << quote_type
23
+ @end_index += 1
24
+ # Successfully parsed the string
25
+ return
26
+ end
27
+
28
+ n, c = process_next_character(expression, @end_index)
29
+ @string << c
30
+ @end_index += n
31
+ end
32
+
33
+ raise Keisan::Exceptions::TokenizingError.new("Tokenizing error, no closing quote #{quote_type}")
34
+ end
35
+
36
+ def size
37
+ string.size
38
+ end
39
+
40
+ def to_s
41
+ string
42
+ end
43
+
44
+ private
45
+
46
+ # Returns number of processed input characters, and the output character
47
+ def process_next_character(expression, index)
48
+ # escape character
49
+ if expression[index] == "\\"
50
+ return [2, escaped_character(expression[index + 1])]
51
+ else
52
+ return [1, expression[index]]
53
+ end
54
+ end
55
+
56
+ def quote_type
57
+ @string[0]
58
+ end
59
+
60
+ def escaped_character(character)
61
+ case character
62
+ when "\\", '"', "'"
63
+ character
64
+ when "a"
65
+ "\a"
66
+ when "b"
67
+ "\b"
68
+ when "r"
69
+ "\r"
70
+ when "n"
71
+ "\n"
72
+ when "s"
73
+ "\s"
74
+ when "t"
75
+ "\t"
76
+ else
77
+ raise Keisan::Exceptions::TokenizingError.new("Tokenizing error, unknown escape character: \"\\#{character}\"")
78
+ end
79
+ end
80
+ end
81
+
82
+ class GroupPortion < Portion
83
+ attr_reader :opening_brace, :closing_brace ,:portions, :size
84
+
85
+ OPENING_TO_CLOSING_BRACE = {
86
+ "(" => ")",
87
+ "{" => "}",
88
+ "[" => "]",
89
+ }
90
+
91
+ def initialize(expression, start_index)
92
+ super(start_index)
93
+
94
+ case expression[start_index]
95
+ when OPEN_GROUP_REGEX
96
+ @opening_brace = expression[start_index]
97
+ else
98
+ raise Keisan::Exceptions::TokenizingError.new("Internal error, GroupPortion did not start with brace")
99
+ end
100
+
101
+ @closing_brace = OPENING_TO_CLOSING_BRACE[opening_brace]
102
+
103
+ parser = StringAndGroupParser.new(expression, start_index: start_index + 1, ending_character: closing_brace)
104
+ @portions = parser.portions
105
+ @size = parser.size + 2
106
+
107
+ if start_index + size > expression.size || expression[start_index + size - 1] != closing_brace
108
+ raise Keisan::Exceptions::TokenizingError.new("Tokenizing error, group with opening brace #{opening_brace} did not have closing brace")
109
+ end
110
+ end
111
+
112
+ def to_s
113
+ opening_brace + portions.map(&:to_s).join + closing_brace
114
+ end
115
+ end
116
+
117
+ class OtherPortion < Portion
118
+ attr_reader :string
119
+
120
+ def initialize(expression, start_index)
121
+ super(start_index)
122
+
123
+ case expression[start_index]
124
+ when STRING_CHARACTER_REGEX, OPEN_GROUP_REGEX, CLOSED_GROUP_REGEX
125
+ raise Keisan::Exceptions::TokenizingError.new("Internal error, OtherPortion should not have string/braces at start")
126
+ else
127
+ index = start_index + 1
128
+ end
129
+
130
+ while index < expression.size
131
+ case expression[index]
132
+ when STRING_CHARACTER_REGEX, OPEN_GROUP_REGEX, CLOSED_GROUP_REGEX
133
+ break
134
+ else
135
+ index += 1
136
+ end
137
+ end
138
+
139
+ @end_index = index
140
+ @string = expression[start_index...end_index]
141
+ end
142
+
143
+ def size
144
+ string.size
145
+ end
146
+
147
+ def to_s
148
+ string
149
+ end
150
+ end
151
+
152
+ # An ordered array of "portions", which
153
+ attr_reader :portions, :size
154
+
155
+ STRING_CHARACTER_REGEX = /["']/
156
+ OPEN_GROUP_REGEX = /[\(\{\[]/
157
+ CLOSED_GROUP_REGEX = /[\)\}\]]/
158
+
159
+ # Ending character is used as a second ending condition besides expression size
160
+ def initialize(expression, start_index: 0, ending_character: nil)
161
+ index = start_index
162
+ @portions = []
163
+
164
+ while index < expression.size && (ending_character.nil? || expression[index] != ending_character)
165
+ case expression[index]
166
+ when STRING_CHARACTER_REGEX
167
+ portion = StringPortion.new(expression, index)
168
+ index = portion.end_index
169
+ @portions << portion
170
+
171
+ when OPEN_GROUP_REGEX
172
+ portion = GroupPortion.new(expression, index)
173
+ index += portion.size
174
+ @portions << portion
175
+
176
+ when CLOSED_GROUP_REGEX
177
+ raise Keisan::Exceptions::TokenizingError.new("Tokenizing error, unexpected closing brace #{expression[start_index]}")
178
+
179
+ else
180
+ portion = OtherPortion.new(expression, index)
181
+ index += portion.size
182
+ @portions << portion
183
+ end
184
+ end
185
+
186
+ @size = index - start_index
187
+ end
188
+
189
+ def to_s
190
+ portions.map(&:to_s).join
191
+ end
192
+ end
193
+ end
@@ -1,13 +1,12 @@
1
1
  module Keisan
2
2
  class Tokenizer
3
3
  TOKEN_CLASSES = [
4
- Tokens::Group,
5
- Tokens::String,
6
4
  Tokens::Null,
7
5
  Tokens::Boolean,
8
6
  Tokens::Word,
9
7
  Tokens::Number,
10
8
  Tokens::Assignment,
9
+ Tokens::BitwiseShift,
11
10
  Tokens::LogicalOperator,
12
11
  Tokens::ArithmeticOperator,
13
12
  Tokens::BitwiseOperator,
@@ -26,8 +25,22 @@ module Keisan
26
25
 
27
26
  def initialize(expression)
28
27
  @expression = self.class.normalize_expression(expression)
29
- @scan = @expression.scan(TOKEN_REGEX)
30
- @tokens = tokenize!
28
+
29
+ portions = StringAndGroupParser.new(@expression).portions
30
+
31
+ @tokens = portions.inject([]) do |tokens, portion|
32
+ case portion
33
+ when StringAndGroupParser::StringPortion
34
+ tokens << Tokens::String.new(portion.to_s)
35
+ when StringAndGroupParser::GroupPortion
36
+ tokens << Tokens::Group.new(portion.to_s)
37
+ when StringAndGroupParser::OtherPortion
38
+ scan = portion.to_s.scan(TOKEN_REGEX)
39
+ tokens += tokenize!(scan)
40
+ end
41
+
42
+ tokens
43
+ end
31
44
  end
32
45
 
33
46
  def self.normalize_expression(expression)
@@ -45,8 +58,8 @@ module Keisan
45
58
  expression.gsub(/#[^;]*/, "")
46
59
  end
47
60
 
48
- def tokenize!
49
- @scan.map do |scan_result|
61
+ def tokenize!(scan)
62
+ scan.map do |scan_result|
50
63
  i = scan_result.find_index {|token| !token.nil?}
51
64
  token_string = scan_result[i]
52
65
  token = TOKEN_CLASSES[i].new(token_string)
@@ -13,7 +13,9 @@ module Keisan
13
13
  \% |
14
14
  \& |
15
15
  \| |
16
- \^
16
+ \^ |
17
+ \<\< |
18
+ \>\>
17
19
  )?
18
20
  \=
19
21
  (?!\=) # negative lookahead to prevent matching ==
@@ -0,0 +1,23 @@
1
+ module Keisan
2
+ module Tokens
3
+ class BitwiseShift < Operator
4
+ LEFT_SHIFT = /(?:<<)/
5
+ RIGHT_SHIFT = /(?:>>)/
6
+
7
+ REGEX = /(#{LEFT_SHIFT}|#{RIGHT_SHIFT})/
8
+
9
+ def self.regex
10
+ REGEX
11
+ end
12
+
13
+ def operator_type
14
+ case string
15
+ when LEFT_SHIFT
16
+ :<<
17
+ when RIGHT_SHIFT
18
+ :>>
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,19 +1,13 @@
1
1
  module Keisan
2
2
  module Tokens
3
3
  class Group < Token
4
- REGEX = /(\((?:[^\[\]\(\)\{\}]*+\g<1>*+)*+\)|\[(?:[^\[\]\(\)\{\}]*+\g<1>*+)*+\]|\{(?:[^\[\]\(\)\{\}]*+\g<1>*+)*+\})/
5
-
6
4
  attr_reader :sub_tokens
7
5
 
8
6
  def initialize(string)
9
- super
7
+ @string = string
10
8
  @sub_tokens = Tokenizer.new(string[1...-1]).tokens
11
9
  end
12
10
 
13
- def self.regex
14
- REGEX
15
- end
16
-
17
11
  # Either :round, :square
18
12
  def group_type
19
13
  case string[0]
@@ -1,10 +1,8 @@
1
1
  module Keisan
2
2
  module Tokens
3
3
  class String < Token
4
- REGEX = /(\"[^\"]*\"|\'[^\']*\')/
5
-
6
- def self.regex
7
- REGEX
4
+ def initialize(string)
5
+ @string = string
8
6
  end
9
7
 
10
8
  def value
@@ -1,3 +1,3 @@
1
1
  module Keisan
2
- VERSION = "0.8.0"
2
+ VERSION = "0.8.1"
3
3
  end
metadata CHANGED
@@ -1,57 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: keisan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Locke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-23 00:00:00.000000000 Z
11
+ date: 2020-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: coveralls
14
+ name: cmath
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
19
+ version: '1.0'
20
+ type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '0'
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.14'
33
+ version: '2.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.14'
40
+ version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '10.0'
47
+ version: '13.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '10.0'
54
+ version: '13.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  description: A library for parsing equations into an abstract syntax tree for evaluation
98
112
  email:
99
113
  - project.eutopia@gmail.com
@@ -117,8 +131,10 @@ files:
117
131
  - lib/keisan/ast/arithmetic_operator.rb
118
132
  - lib/keisan/ast/assignment.rb
119
133
  - lib/keisan/ast/bitwise_and.rb
134
+ - lib/keisan/ast/bitwise_left_shift.rb
120
135
  - lib/keisan/ast/bitwise_operator.rb
121
136
  - lib/keisan/ast/bitwise_or.rb
137
+ - lib/keisan/ast/bitwise_right_shift.rb
122
138
  - lib/keisan/ast/bitwise_xor.rb
123
139
  - lib/keisan/ast/block.rb
124
140
  - lib/keisan/ast/boolean.rb
@@ -219,10 +235,12 @@ files:
219
235
  - lib/keisan/parsing/arithmetic_operator.rb
220
236
  - lib/keisan/parsing/assignment.rb
221
237
  - lib/keisan/parsing/bitwise_and.rb
238
+ - lib/keisan/parsing/bitwise_left_shift.rb
222
239
  - lib/keisan/parsing/bitwise_not.rb
223
240
  - lib/keisan/parsing/bitwise_not_not.rb
224
241
  - lib/keisan/parsing/bitwise_operator.rb
225
242
  - lib/keisan/parsing/bitwise_or.rb
243
+ - lib/keisan/parsing/bitwise_right_shift.rb
226
244
  - lib/keisan/parsing/bitwise_xor.rb
227
245
  - lib/keisan/parsing/boolean.rb
228
246
  - lib/keisan/parsing/component.rb
@@ -266,11 +284,13 @@ files:
266
284
  - lib/keisan/parsing/unary_plus.rb
267
285
  - lib/keisan/parsing/variable.rb
268
286
  - lib/keisan/repl.rb
287
+ - lib/keisan/string_and_group_parser.rb
269
288
  - lib/keisan/token.rb
270
289
  - lib/keisan/tokenizer.rb
271
290
  - lib/keisan/tokens/arithmetic_operator.rb
272
291
  - lib/keisan/tokens/assignment.rb
273
292
  - lib/keisan/tokens/bitwise_operator.rb
293
+ - lib/keisan/tokens/bitwise_shift.rb
274
294
  - lib/keisan/tokens/boolean.rb
275
295
  - lib/keisan/tokens/colon.rb
276
296
  - lib/keisan/tokens/comma.rb
@@ -308,8 +328,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
308
328
  - !ruby/object:Gem::Version
309
329
  version: '0'
310
330
  requirements: []
311
- rubyforge_project:
312
- rubygems_version: 2.7.7
331
+ rubygems_version: 3.0.3
313
332
  signing_key:
314
333
  specification_version: 4
315
334
  summary: An equation parser and evaluator