rox-rollout 4.7.3 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +34 -13
  3. data/.editorconfig +12 -0
  4. data/.github/workflows/ruby.yml +20 -0
  5. data/.rubocop.yml +17 -0
  6. data/Gemfile +2 -2
  7. data/README.md +32 -0
  8. data/Rakefile +12 -9
  9. data/bin/console +3 -4
  10. data/e2e-server/run_server.sh +12 -0
  11. data/e2e-server/server.rb +158 -0
  12. data/e2e/container.rb +11 -14
  13. data/e2e/custom_props.rb +9 -9
  14. data/e2e/rox_e2e_test.rb +17 -19
  15. data/e2e/test_vars.rb +3 -6
  16. data/example/local.rb +40 -0
  17. data/lib/rox/core/analytics.rb +18 -0
  18. data/lib/rox/core/client/buid.rb +8 -8
  19. data/lib/rox/core/client/device_properties.rb +7 -1
  20. data/lib/rox/core/client/dynamic_api.rb +53 -15
  21. data/lib/rox/core/client/internal_flags.rb +14 -2
  22. data/lib/rox/core/client/sdk_settings.rb +1 -1
  23. data/lib/rox/core/configuration/configuration.rb +1 -1
  24. data/lib/rox/core/configuration/configuration_fetched_args.rb +2 -2
  25. data/lib/rox/core/configuration/configuration_fetched_invoker.rb +8 -3
  26. data/lib/rox/core/configuration/configuration_parser.rb +38 -37
  27. data/lib/rox/core/configuration/fetcher_error.rb +1 -1
  28. data/lib/rox/core/configuration/fetcher_status.rb +1 -1
  29. data/lib/rox/core/configuration/models/experiment_model.rb +1 -1
  30. data/lib/rox/core/configuration/models/target_group_model.rb +1 -1
  31. data/lib/rox/core/consts/build.rb +2 -2
  32. data/lib/rox/core/consts/environment.rb +10 -8
  33. data/lib/rox/core/consts/property_type.rb +16 -17
  34. data/lib/rox/core/context/merged_context.rb +2 -1
  35. data/lib/rox/core/core.rb +88 -38
  36. data/lib/rox/core/entities/default_flag_values.rb +10 -0
  37. data/lib/rox/core/entities/flag.rb +22 -7
  38. data/lib/rox/core/entities/flag_setter.rb +6 -6
  39. data/lib/rox/core/entities/rox_double.rb +11 -0
  40. data/lib/rox/core/entities/rox_int.rb +11 -0
  41. data/lib/rox/core/entities/{variant.rb → rox_string.rb} +20 -13
  42. data/lib/rox/core/error_handling/exception_trigger.rb +10 -0
  43. data/lib/rox/core/error_handling/userspace_handler_exception.rb +12 -0
  44. data/lib/rox/core/error_handling/userspace_unhandled_error_invoker.rb +41 -0
  45. data/lib/rox/core/impression/impression_args.rb +2 -2
  46. data/lib/rox/core/impression/impression_invoker.rb +41 -7
  47. data/lib/rox/core/impression/models/experiment.rb +1 -1
  48. data/lib/rox/core/impression/models/reporting_value.rb +10 -2
  49. data/lib/rox/core/logging/logging.rb +3 -3
  50. data/lib/rox/core/logging/no_op_logger.rb +1 -1
  51. data/lib/rox/core/network/configuration_fetcher.rb +2 -2
  52. data/lib/rox/core/network/configuration_fetcher_roxy.rb +2 -2
  53. data/lib/rox/core/network/configuration_fetcher_self_managed.rb +30 -0
  54. data/lib/rox/core/network/configuration_source.rb +1 -1
  55. data/lib/rox/core/network/request.rb +1 -1
  56. data/lib/rox/core/network/request_configuration_builder.rb +5 -5
  57. data/lib/rox/core/network/request_data.rb +1 -1
  58. data/lib/rox/core/network/response.rb +6 -8
  59. data/lib/rox/core/network/state_sender.rb +61 -18
  60. data/lib/rox/core/notifications/notification_listener.rb +4 -4
  61. data/lib/rox/core/properties/custom_property.rb +1 -1
  62. data/lib/rox/core/properties/custom_property_type.rb +1 -1
  63. data/lib/rox/core/properties/device_property.rb +2 -2
  64. data/lib/rox/core/properties/property_factory.rb +132 -0
  65. data/lib/rox/core/register/registerer.rb +13 -12
  66. data/lib/rox/core/reporting/error_reporter.rb +14 -13
  67. data/lib/rox/core/repositories/experiment_repository.rb +2 -4
  68. data/lib/rox/core/repositories/flag_repository.rb +7 -7
  69. data/lib/rox/core/repositories/roxx/experiments_extensions.rb +8 -8
  70. data/lib/rox/core/repositories/roxx/properties_extensions.rb +32 -7
  71. data/lib/rox/core/repositories/target_group_repository.rb +2 -4
  72. data/lib/rox/core/roxx/evaluation_result.rb +2 -0
  73. data/lib/rox/core/roxx/node.rb +1 -1
  74. data/lib/rox/core/roxx/parser.rb +35 -21
  75. data/lib/rox/core/roxx/regular_expression_extensions.rb +6 -3
  76. data/lib/rox/core/roxx/string_tokenizer.rb +3 -1
  77. data/lib/rox/core/roxx/symbols.rb +1 -1
  78. data/lib/rox/core/roxx/token_type.rb +1 -1
  79. data/lib/rox/core/roxx/tokenized_expression.rb +16 -12
  80. data/lib/rox/core/roxx/value_compare_extensions.rb +49 -29
  81. data/lib/rox/core/security/signature_verifier.rb +3 -3
  82. data/lib/rox/core/security/signature_verifier_mock.rb +12 -0
  83. data/lib/rox/core/utils/type_utils.rb +1 -1
  84. data/lib/rox/server/client/server_properties.rb +1 -1
  85. data/lib/rox/server/flags/normalize_flag_type.rb +25 -0
  86. data/lib/rox/server/flags/rox_double.rb +8 -0
  87. data/lib/rox/server/flags/rox_flag.rb +1 -1
  88. data/lib/rox/server/flags/rox_int.rb +8 -0
  89. data/lib/rox/server/flags/rox_string.rb +8 -0
  90. data/lib/rox/server/flags/server_entities_provider.rb +14 -4
  91. data/lib/rox/server/logging/server_logger.rb +2 -2
  92. data/lib/rox/server/rox_options.rb +39 -8
  93. data/lib/rox/server/rox_server.rb +80 -59
  94. data/lib/rox/version.rb +1 -1
  95. data/rox.gemspec +11 -9
  96. metadata +66 -37
  97. data/CODEOWNERS +0 -1
  98. data/README_DEVELOP.md +0 -25
  99. data/_archive/.document +0 -5
  100. data/_archive/.rspec +0 -1
  101. data/_archive/Gemfile +0 -15
  102. data/_archive/README.md +0 -32
  103. data/_archive/README.rdoc +0 -19
  104. data/_archive/Rakefile +0 -50
  105. data/_archive/lib/expr_function_definition.rb +0 -52
  106. data/_archive/lib/function_definition.rb +0 -48
  107. data/_archive/lib/function_token.rb +0 -12
  108. data/_archive/lib/object_extends.rb +0 -12
  109. data/_archive/lib/ruby_interpreter.rb +0 -292
  110. data/_archive/lib/stack.rb +0 -48
  111. data/_archive/lib/string_extends.rb +0 -14
  112. data/_archive/spec/ruby_interpreter_spec.rb +0 -203
  113. data/_archive/spec/spec_helper.rb +0 -30
  114. data/_archive/spec/stack_spec.rb +0 -77
  115. data/lib/rox/server/flags/rox_variant.rb +0 -8
data/CODEOWNERS DELETED
@@ -1 +0,0 @@
1
- * @joshpuetz
data/README_DEVELOP.md DELETED
@@ -1,25 +0,0 @@
1
- # Developer Guide
2
-
3
- Ruby versions supported: 2.3.x, 2.4.x, 2.5.x, 2.6.x
4
-
5
- ## Run tests on current Ruby version
6
-
7
- ```
8
- // Run unit tests (folder 'tests')
9
- rake test
10
-
11
- // Run E2E tests (folder 'e2e')
12
- rake e2e
13
- ```
14
-
15
- ## Publish new version
16
-
17
- ### Steps
18
-
19
- 1. Increment version in ```lib/rox/version.rb```, open a PR and wait for CI to clear
20
- 2. Merge to master, wait for CI to clear
21
- 2. Generate the gem package: ```gem build rox.gemspec```
22
- 3. Install gem locally, and test with a sample project
23
- 4. Upload to RubyGems: ```gem push rox-rollout-VERSION.gem```
24
- 5. Update documentation at https://support.rollout.io/docs/ruby-changelog
25
- 6. Celebrate! 🎉
data/_archive/.document DELETED
@@ -1,5 +0,0 @@
1
- lib/**/*.rb
2
- bin/*
3
- -
4
- features/**/*.feature
5
- LICENSE.txt
data/_archive/.rspec DELETED
@@ -1 +0,0 @@
1
- --color
data/_archive/Gemfile DELETED
@@ -1,15 +0,0 @@
1
- source "https://rubygems.org"
2
- # Add dependencies required to use your gem here.
3
- # Example:
4
- # gem "activesupport", ">= 2.3.5"
5
-
6
- # Add dependencies to develop your gem here.
7
- # Include everything needed to run rake, tests, features, etc.
8
- group :development do
9
- gem 'pry'
10
- gem "rspec", "~> 3.5.0"
11
- gem "rdoc", "~> 3.12"
12
- gem "bundler", "~> 1.0"
13
- gem "jeweler", "~> 2.0.1"
14
- gem "simplecov", ">= 0"
15
- end
data/_archive/README.md DELETED
@@ -1,32 +0,0 @@
1
- ![Rollout](https://1ko9923xosh2dsbjsxpwqp45-wpengine.netdna-ssl.com/wp-content/themes/rollout/images/rollout_white_logo1.png)
2
-
3
- Rollout is a Secure Feature Managment Solution for the Enterprise.
4
-
5
- > Accelerate development and minimize the risk of deploying new code with simple to create feature flags, controlled rollouts, advanced target groups & deployment rules.
6
-
7
- ## Getting Started
8
-
9
- Please see the detailed instructions in our docs how to [add Rollout to your project](https://support.rollout.io/docs/installing-the-sdk).
10
-
11
- ## Documentation
12
-
13
- Getting started guide, use cases, examples and videos can be found in [Rollout support site](https://support.rollout.io)
14
-
15
- # Rollout Ruby SDK
16
-
17
- Rollout Ruby SDK. Define and use simple and advanced feature flags, remote configuration variables, static and computed custom properties in code. Control your application features via Rollout's dashboard.
18
-
19
- ## Installation
20
- ```
21
- gem install rox-rollout
22
- ```
23
-
24
- ## LICENSE
25
-
26
- Rollout is free-to-use, proprietary software. Please see the full license (found in LICENSE in this distribution) for details on its license and the licenses of its dependencies.
27
-
28
- Rollout Ruby SDK is free-to-use, proprietary software. Please see the full license found under the LICENSE file for more details.
29
-
30
- ## Feedback
31
-
32
- Feedback is always welcomed support@rollout.io
data/_archive/README.rdoc DELETED
@@ -1,19 +0,0 @@
1
- = ruby-interpreter
2
-
3
- Description goes here.
4
-
5
- == Contributing to ruby-interpreter
6
-
7
- * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
8
- * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
9
- * Fork the project.
10
- * Start a feature/bugfix branch.
11
- * Commit and push until you are happy with your contribution.
12
- * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
- * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
-
15
- == Copyright
16
-
17
- Copyright (c) 2018 stoarch. See LICENSE.txt for
18
- further details.
19
-
data/_archive/Rakefile DELETED
@@ -1,50 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'rubygems'
4
- require 'bundler'
5
- begin
6
- Bundler.setup(:default, :development)
7
- rescue Bundler::BundlerError => e
8
- $stderr.puts e.message
9
- $stderr.puts "Run `bundle install` to install missing gems"
10
- exit e.status_code
11
- end
12
- require 'rake'
13
-
14
- require 'jeweler'
15
- Jeweler::Tasks.new do |gem|
16
- # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
17
- gem.name = "ruby-interpreter"
18
- gem.homepage = "http://github.com/stoarch/ruby-interpreter"
19
- gem.license = "MIT"
20
- gem.summary = %Q{TODO: one-line summary of your gem}
21
- gem.description = %Q{TODO: longer description of your gem}
22
- gem.email = "stormarchitextor@gmail.com"
23
- gem.authors = ["stoarch"]
24
- # dependencies defined in Gemfile
25
- end
26
- Jeweler::RubygemsDotOrgTasks.new
27
-
28
- require 'rspec/core'
29
- require 'rspec/core/rake_task'
30
- RSpec::Core::RakeTask.new(:spec) do |spec|
31
- spec.pattern = FileList['spec/**/*_spec.rb']
32
- end
33
-
34
- desc "Code coverage detail"
35
- task :simplecov do
36
- ENV['COVERAGE'] = "true"
37
- Rake::Task['spec'].execute
38
- end
39
-
40
- task :default => :spec
41
-
42
- require 'rdoc/task'
43
- Rake::RDocTask.new do |rdoc|
44
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
45
-
46
- rdoc.rdoc_dir = 'rdoc'
47
- rdoc.title = "ruby-interpreter #{version}"
48
- rdoc.rdoc_files.include('README*')
49
- rdoc.rdoc_files.include('lib/**/*.rb')
50
- end
@@ -1,52 +0,0 @@
1
-
2
- module ExprFunctionDefinition
3
- def add_func(name)
4
- @func_list ||= []
5
- @func_list << name unless @func_list.include? name
6
- end
7
-
8
- def unary_bool_func(name, operator)
9
- add_func(name.to_s)
10
-
11
- define_method("evaluate_#{name.to_s}") do
12
-
13
- a = @stack.pop
14
-
15
- res = a.evaluate.to_boolean.send(operator.to_sym)
16
-
17
- @stack.push BooleanValue.new(res, @stack)
18
- end
19
- end
20
-
21
- def bool_func(name, operator)
22
- add_func(name.to_s)
23
-
24
- define_method("evaluate_#{name.to_s}") do
25
-
26
- a = @stack.pop
27
- b = @stack.pop
28
-
29
- res = a.evaluate.send(operator.to_sym, b.evaluate)
30
- @stack.push BooleanValue.new(res, @stack)
31
- end
32
- end
33
-
34
- def comp_func(name, operator)
35
- add_func(name.to_s)
36
-
37
- define_method("evaluate_#{name.to_s}") do
38
- a = @stack.pop
39
- b = @stack.pop
40
-
41
- aval = a.evaluate
42
- bval = b.evaluate
43
-
44
- if( aval.class == bval.class ) #we can compare string with string and numeric with numeric only
45
-
46
- @stack.push BooleanValue.new(aval.send(operator.to_sym, bval), @stack)
47
- else
48
- @stack.push BooleanValue.new(false, @stack)
49
- end
50
- end
51
- end
52
- end
@@ -1,48 +0,0 @@
1
-
2
- module FunctionDefinition
3
- def add_func(name)
4
- @func_list ||= []
5
- @func_list << name unless @func_list.include? name
6
- end
7
-
8
- def unary_bool_func(name, operator)
9
- add_func(name.to_s)
10
-
11
- define_method("evaluate#{name[0].upcase}#{name[1..-1]}") do |stack_index|
12
-
13
- a = @operands_stack.pop
14
-
15
- res = a.to_boolean.send(operator.to_sym).to_s
16
-
17
- @operands_stack.push res
18
- end
19
- end
20
-
21
- def bool_func(name, operator)
22
- add_func(name.to_s)
23
-
24
- define_method("evaluate#{name[0].upcase}#{name[1..-1]}") do |stack_index|
25
-
26
- a = @operands_stack.pop
27
- b = @operands_stack.pop
28
-
29
- res = a.to_boolean.send(operator.to_sym, b.to_boolean).to_s
30
- @operands_stack.push res
31
- end
32
- end
33
-
34
- def comp_func(name, operator)
35
- add_func(name.to_s)
36
-
37
- define_method("evaluate#{name[0].upcase}#{name[1..-1]}") do |stack_index|
38
- a = @operands_stack.pop
39
- b = @operands_stack.pop
40
-
41
- if( a.class == b.class ) #we can compare string with string and numeric with numeric only
42
- @operands_stack.push b.send(operator.to_sym, a).to_s
43
- else
44
- @operands_stack.push 'false'
45
- end
46
- end
47
- end
48
- end
@@ -1,12 +0,0 @@
1
-
2
- class FunctionToken
3
- attr :name
4
- attr :stack_index #to paste value of this function
5
-
6
- def initialize(name, stack_index)
7
- @name = name
8
- @stack_index = stack_index
9
- end
10
-
11
- end
12
-
@@ -1,12 +0,0 @@
1
-
2
- class Object
3
- FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF', 'no', 'NO', 'undefined'].to_set
4
-
5
- def to_boolean
6
- if self.to_s == ''
7
- nil
8
- else
9
- !FALSE_VALUES.include?(self.to_s)
10
- end
11
- end
12
- end
@@ -1,292 +0,0 @@
1
- require 'pry'
2
- require_relative 'object_extends'
3
- require_relative 'string_extends'
4
- require_relative 'function_token'
5
- require_relative 'function_definition'
6
- require_relative 'expr_function_definition'
7
-
8
- class Expression
9
- attr :expr, :stack
10
-
11
- def initialize(expr_val, stack)
12
- @expr = expr_val
13
- @stack = stack
14
- end
15
-
16
- def evaluate
17
- end
18
-
19
- def to_s
20
- @expr
21
- end
22
- end
23
-
24
- class ValueExpression < Expression
25
- def evaluate
26
- @expr
27
- end
28
- end
29
-
30
- class UndefinedValue < ValueExpression
31
- end
32
-
33
- class StringValue < ValueExpression
34
- end
35
-
36
- class BooleanValue < ValueExpression
37
- def evaluate
38
- @expr.to_boolean
39
- end
40
- end
41
-
42
- class FloatValue < ValueExpression
43
- def evaluate
44
- @expr
45
- end
46
- end
47
-
48
- class FunctionExpression < Expression
49
- extend ExprFunctionDefinition
50
-
51
- attr :evaluators
52
-
53
- unary_bool_func :not, '!'
54
-
55
- bool_func :and, '&'
56
- bool_func :or, '|'
57
-
58
- comp_func :eq, '=='
59
- comp_func :ne, '!='
60
- comp_func :lt, '<'
61
- comp_func :lte, '<='
62
- comp_func :gt, '>'
63
- comp_func :gte, '>='
64
-
65
- def initialize(expr_val, stack)
66
- super(expr_val, stack)
67
-
68
- @functions = ['isUndefined', 'now']
69
- @functions << self.class.instance_variable_get('@func_list')
70
- @functions.flatten!
71
-
72
- prepare_evaluators()
73
- end
74
-
75
- def evaluate
76
- ev = @evaluators[@expr]
77
- return ev.call unless ev.nil?
78
-
79
- #todo log invalid function
80
- @stack.push BooleanValue.new(false, @stack) if ev.nil?
81
- end
82
-
83
- private
84
-
85
- def prepare_evaluators()
86
- @evaluators = @functions.map{|f| [f, ->{ self.send("evaluate_#{f}")}]}.to_h
87
- end
88
-
89
- def evaluate_isUndefined
90
- a = @stack.pop
91
- @stack.push BooleanValue.new(a.evaluate == :undefined, @stack)
92
- end
93
-
94
- def evaluate_now
95
- Time.now.to_f.round(3)*1000
96
- end
97
-
98
- end
99
-
100
- ## RubyInterpreter ##
101
- #
102
- # goal: Interpret expression in forward polish notation with some functions
103
- #
104
- class RubyInterpreter
105
- extend FunctionDefinition
106
-
107
- attr_reader :func_stack, :operands_stack
108
- attr_reader :expr_stack
109
-
110
- #operators
111
- unary_bool_func :not, '!'
112
-
113
- bool_func :and, '&'
114
- bool_func :or, '|'
115
-
116
- comp_func :eq, '=='
117
- comp_func :ne, '!='
118
-
119
- comp_func :lt, '<'
120
- comp_func :lte, '<='
121
- comp_func :gt, '>'
122
- comp_func :gte, '>='
123
-
124
- def initialize
125
- @func_stack = Stack.new
126
- @operands_stack = Stack.new
127
- @expr_stack = Stack.new
128
-
129
- @func_list ||= []
130
- @func_list << self.class.instance_variable_get('@func_list')
131
- @func_list << ['isUndefined', 'now']
132
- @func_list.flatten!
133
-
134
- @funcs_re ||= Regexp.new(@func_list.join('|') )
135
- end
136
- #todo make unary/2ry functions by define_method (dry code)
137
-
138
- def prepare_expr_stack(tokens)
139
- is_string_token = false
140
- string_token = ''
141
-
142
- tokens.each do |tkn, i|
143
-
144
- if is_string_token && tkn != '"'
145
- string_token += tkn
146
- next
147
- end
148
-
149
- case tkn
150
- when 'undefined'
151
- @expr_stack.push( UndefinedValue.new(tkn.to_sym, @expr_stack) )
152
- when '"'
153
- if( is_string_token ) #todo check pair "
154
- is_string_token = false
155
- @expr_stack.push StringValue.new(string_token, @expr_stack)
156
- string_token = ''
157
- else
158
- is_string_token = true
159
- end
160
- when ',' , '(', ')', ' '
161
- #do nothing
162
- when @funcs_re
163
- @expr_stack.push( FunctionExpression.new( tkn , @expr_stack) )
164
- when 'true', 'false'
165
- @expr_stack.push BooleanValue.new(tkn, @expr_stack)
166
- else
167
- fval, is_float = tkn.to_float
168
- if(is_float)
169
- @expr_stack.push FloatValue.new(fval, @expr_stack)
170
- else
171
- #todo show error message 'unknown token'
172
- return 'false'
173
- end
174
- end
175
- end
176
- end
177
-
178
- def evaluate_expr_stack()
179
- @func_evaluators = @func_list.map{|f| [f, ->(){ self.send("evaluate_func_#{f}")}]}.to_h
180
-
181
- value = false
182
-
183
- while !@expr_stack.empty? do
184
- expr = @expr_stack.pop
185
- value = expr.evaluate unless expr.nil?
186
-
187
- return false if expr.nil? #todo show error message
188
- end
189
-
190
- value
191
- end
192
-
193
-
194
- def evaluateExpression2(expr)
195
- @expr_stack.clear
196
-
197
- tokens = expr.scan(/\d+\.?\d*|\s+|,|\(|"|\)|\w+|\W+/)
198
-
199
- prepare_expr_stack(tokens)
200
- expr_stack.invert()
201
- evaluate_expr_stack()
202
- end
203
-
204
- # Evaluate expression
205
- #
206
- # info:
207
- # 1. Language is polish forward notation with custom functions
208
- # 2. Function list:
209
- # a. and(a,b)
210
- #
211
- def evaluateExpression(expr)
212
- @func_stack.clear
213
- @operands_stack.clear
214
-
215
-
216
- tokens = expr.scan(/\d+\.?\d*|\s+|,|\(|"|\)|\w+|\W+/)
217
-
218
- is_string_token = false
219
- string_token = ''
220
-
221
- @funcs_re ||= Regexp.new(@func_list.join('|') )
222
-
223
- #prepare stack
224
- tokens.each do |tkn, i|
225
- if is_string_token && tkn != '"'
226
- string_token += tkn
227
- next
228
- end
229
-
230
- case tkn
231
- when 'undefined'
232
- @operands_stack.push( tkn.to_sym )
233
- when '"'
234
- if( is_string_token ) #todo check pair "
235
- is_string_token = false
236
- @operands_stack.push string_token
237
- string_token = ''
238
- else
239
- is_string_token = true
240
- end
241
- when ',' , '(', ')', ' '
242
- #do nothing
243
- when @funcs_re
244
- @func_stack.push( FunctionToken.new( tkn, @operands_stack.size ) )
245
- when 'true', 'false'
246
- @operands_stack.push tkn
247
- else
248
- fval, is_float = tkn.to_float
249
- if(is_float)
250
- @operands_stack.push(fval)
251
- else
252
- #todo show error message 'unknown token'
253
- return 'false'
254
- end
255
- end
256
- end
257
-
258
- #evaluate stack
259
- @func_evals ||= prepare_func_evaluators()
260
-
261
- while !@func_stack.empty? do
262
-
263
- token = @func_stack.pop
264
-
265
- feval = @func_evals[token.name]
266
-
267
- feval.call(token.stack_index) unless feval.nil?
268
- end
269
-
270
- @operands_stack.pop
271
- end
272
-
273
- private
274
-
275
- def prepare_func_evaluators()
276
- # make hash with functors: 'or' => ->(stack_index){ self.send('evaluateOr', stack_index) }
277
- return @func_list.map{|f| [f, ->(stack_index){ self.send("evaluate#{f[0].upcase}#{f[1..-1]}", stack_index) }]}.to_h
278
- end
279
-
280
- #evaluators
281
-
282
- def evaluateIsUndefined(stack_index)
283
- a = @operands_stack.pop
284
- @operands_stack.push (a == :undefined).to_s
285
- end
286
-
287
- def evaluateNow(stack_index)
288
- @operands_stack.insert Time.now().tv_sec.to_f, stack_index
289
- end
290
-
291
-
292
- end