Class: Mxrb::Runtime::Native::Expression
- Inherits:
-
Object
- Object
- Mxrb::Runtime::Native::Expression
- Defined in:
- lib/mxrb/runtime/native.rb
Overview
Deliberately small Mendix-expression evaluator. Unsupported syntax is rejected rather than guessed, preserving deterministic test semantics.
Defined Under Namespace
Instance Method Summary collapse
- #evaluate(source, variables, node: nil) ⇒ Object
-
#initialize ⇒ Expression
constructor
A new instance of Expression.
- #invoke(name, arguments) ⇒ Object
- #resolve_identifier(text, node) ⇒ Object
- #resolve_variable(text, variables) ⇒ Object
Constructor Details
#initialize ⇒ Expression
Returns a new instance of Expression.
168 169 170 |
# File 'lib/mxrb/runtime/native.rb', line 168 def initialize @token_cache = {} end |
Instance Method Details
#evaluate(source, variables, node: nil) ⇒ Object
172 173 174 175 176 177 178 179 180 |
# File 'lib/mxrb/runtime/native.rb', line 172 def evaluate(source, variables, node: nil) text = unwrap(source).strip return nil if text.empty? tokens = (@token_cache[text] ||= Lexer.new(text).tokens.freeze) Parser.new(tokens, self, variables, node).parse rescue ArgumentError, TypeError, KeyError raise NativeRuntimeError, "unsupported Mendix expression: #{source.inspect}" end |
#invoke(name, arguments) ⇒ Object
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/mxrb/runtime/native.rb', line 209 def invoke(name, arguments) case name.downcase when 'tostring' then mendix_string(arguments.fetch(0)) when 'parseinteger' then Integer(arguments.fetch(0)) when 'parsedecimal' then Float(arguments.fetch(0)) when 'round' then arguments.fetch(0).round when 'random' then Random.rand when 'substring' then substring(*arguments) when 'find' then arguments.fetch(0).to_s.index(arguments.fetch(1).to_s) || -1 when 'formatdatetime' then format_datetime(*arguments) when 'contains' then arguments.fetch(0).to_s.include?(arguments.fetch(1).to_s) when 'startswith' then arguments.fetch(0).to_s.start_with?(arguments.fetch(1).to_s) when 'endswith' then arguments.fetch(0).to_s.end_with?(arguments.fetch(1).to_s) else raise ArgumentError, name end end |
#resolve_identifier(text, node) ⇒ Object
194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/mxrb/runtime/native.rb', line 194 def resolve_identifier(text, node) return true if text.casecmp?('true') return false if text.casecmp?('false') return nil if text.casecmp?('empty') if node && (text) member = text.split('/').last.split('.').last return node.members[member] if node.members.key?(member) end return text if text.match?(/\A[A-Za-z_]\w*\.[A-Za-z_]\w*\.[A-Za-z_]\w*\z/) return node_member(text, node) if node && (text) raise ArgumentError, text end |
#resolve_variable(text, variables) ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 |
# File 'lib/mxrb/runtime/native.rb', line 182 def resolve_variable(text, variables) name, member = text.delete_prefix('$').split('/', 2) value = variables.fetch(name) do raise NativeRuntimeError, "unknown variable $#{name}" end return value unless member raise NativeRuntimeError, "$#{name} is not an object" unless value.is_a?(ObjectValue) value.members[member.split('.').last] end |