predicator 0.4.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +3 -2
  4. data/HISTORY.md +9 -0
  5. data/README.md +7 -8
  6. data/Rakefile +14 -5
  7. data/lib/predicator.rb +18 -10
  8. data/lib/predicator/ast.rb +138 -0
  9. data/lib/predicator/context.rb +7 -63
  10. data/lib/predicator/evaluator.rb +108 -0
  11. data/lib/predicator/lexer.rex +51 -0
  12. data/lib/predicator/lexer.rex.rb +160 -0
  13. data/lib/predicator/parser.rb +291 -7
  14. data/lib/predicator/parser.y +66 -40
  15. data/lib/predicator/version.rb +1 -1
  16. data/lib/predicator/visitors.rb +5 -0
  17. data/lib/predicator/visitors/dot.rb +100 -0
  18. data/lib/predicator/visitors/each.rb +16 -0
  19. data/lib/predicator/visitors/instructions.rb +117 -0
  20. data/lib/predicator/visitors/string.rb +60 -0
  21. data/lib/predicator/visitors/visitor.rb +48 -0
  22. data/predicator.gemspec +3 -2
  23. metadata +29 -32
  24. data/lib/predicator/errors.rb +0 -5
  25. data/lib/predicator/generated_parser.rb +0 -335
  26. data/lib/predicator/lexer.rb +0 -125
  27. data/lib/predicator/nodes.rb +0 -6
  28. data/lib/predicator/nodes/base_node.rb +0 -53
  29. data/lib/predicator/nodes/date_node.rb +0 -13
  30. data/lib/predicator/nodes/fixnum_node.rb +0 -9
  31. data/lib/predicator/nodes/float_node.rb +0 -9
  32. data/lib/predicator/nodes/nil_class_node.rb +0 -25
  33. data/lib/predicator/nodes/string_node.rb +0 -13
  34. data/lib/predicator/predicates.rb +0 -14
  35. data/lib/predicator/predicates/and.rb +0 -20
  36. data/lib/predicator/predicates/between.rb +0 -31
  37. data/lib/predicator/predicates/equal.rb +0 -9
  38. data/lib/predicator/predicates/false.rb +0 -13
  39. data/lib/predicator/predicates/greater_than.rb +0 -9
  40. data/lib/predicator/predicates/greater_than_or_equal.rb +0 -9
  41. data/lib/predicator/predicates/less_than.rb +0 -9
  42. data/lib/predicator/predicates/less_than_or_equal.rb +0 -9
  43. data/lib/predicator/predicates/method.rb +0 -17
  44. data/lib/predicator/predicates/not.rb +0 -20
  45. data/lib/predicator/predicates/not_equal.rb +0 -9
  46. data/lib/predicator/predicates/or.rb +0 -20
  47. data/lib/predicator/predicates/relation.rb +0 -31
  48. data/lib/predicator/predicates/true.rb +0 -13
  49. data/lib/predicator/variable.rb +0 -26
@@ -1,125 +0,0 @@
1
- require "stringio"
2
- require "strscan"
3
-
4
- module Predicator
5
- class Lexer
6
- SPACE = /[ \t\r\n]/
7
- DOT = /\./
8
- LPAREN = /\(/
9
- RPAREN = /\)/
10
- NEQ = /!=/
11
- GEQ = />=/
12
- LEQ = /<=/
13
- GT = />/
14
- LT = /</
15
- EQ = /=/
16
- BANG = /!/
17
- DATE = /(\d{4})-(\d{2})-(\d{2})/i
18
- FLOAT = /[+-]?(?:[0-9_]+\.[0-9_]*|\.[0-9_]+|\d+(?=[eE]))(?:[eE][+-]?[0-9_]+)?\b/
19
- INTEGER = /[+-]?\d(_?\d)*\b/
20
- TRUE = /true\b/
21
- FALSE = /false\b/
22
- AND = /and/i
23
- OR = /or/i
24
- BETWEEN = /between/i
25
- BLANK = /blank\?/i
26
- PRESENT = /present\?/i
27
- STRING = /(["])(?:\\?.)*?\1/
28
- IDENTIFIER = /[a-z][A-Za-z0-9_]*/
29
-
30
- def initialize string_or_io
31
- io = string_or_io.is_a?(String) ?
32
- StringIO.new(string_or_io) :
33
- string_or_io
34
-
35
- @ss = StringScanner.new io.read
36
- @tokens = []
37
- tokenize
38
- end
39
-
40
- def next_token
41
- @tokens.shift
42
- end
43
-
44
- def tokenize
45
- until @ss.eos?
46
- case
47
- when @ss.scan(SPACE)
48
- # ignore space
49
-
50
- when text = @ss.scan(DOT)
51
- @tokens.push [:tDOT, text]
52
-
53
- when text = @ss.scan(LPAREN)
54
- @tokens.push [:tLPAREN, text]
55
-
56
- when text = @ss.scan(RPAREN)
57
- @tokens.push [:tRPAREN, text]
58
-
59
- when text = @ss.scan(NEQ)
60
- @tokens.push [:tNEQ, text]
61
-
62
- when text = @ss.scan(GEQ)
63
- @tokens.push [:tGEQ, text]
64
-
65
- when text = @ss.scan(LEQ)
66
- @tokens.push [:tLEQ, text]
67
-
68
- when text = @ss.scan(GT)
69
- @tokens.push [:tGT, text]
70
-
71
- when text = @ss.scan(LT)
72
- @tokens.push [:tLT, text]
73
-
74
- when text = @ss.scan(EQ)
75
- @tokens.push [:tEQ, text]
76
-
77
- when text = @ss.scan(BANG)
78
- @tokens.push [:tBANG, text]
79
-
80
- when text = @ss.scan(DATE)
81
- args = [ @ss[1], @ss[2], @ss[3] ].map(&:to_i)
82
- @tokens.push [:tDATE, args]
83
-
84
- when text = @ss.scan(FLOAT)
85
- @tokens.push [:tFLOAT, text]
86
-
87
- when text = @ss.scan(INTEGER)
88
- @tokens.push [:tINTEGER, text]
89
-
90
- when text = @ss.scan(TRUE)
91
- @tokens.push [:tTRUE, text]
92
-
93
- when text = @ss.scan(FALSE)
94
- @tokens.push [:tFALSE, text]
95
-
96
- when text = @ss.scan(AND)
97
- @tokens.push [:tAND, text]
98
-
99
- when text = @ss.scan(OR)
100
- @tokens.push [:tOR, text]
101
-
102
- when text = @ss.scan(BETWEEN)
103
- @tokens.push [:tBETWEEN, text]
104
-
105
- when text = @ss.scan(BLANK)
106
- @tokens.push [:tBLANK, text]
107
-
108
- when text = @ss.scan(PRESENT)
109
- @tokens.push [:tPRESENT, text]
110
-
111
- when text = @ss.scan(STRING)
112
- @tokens.push [:tSTRING, text[1..-2]]
113
-
114
- when text = @ss.scan(IDENTIFIER)
115
- @tokens.push [:tIDENTIFIER, text]
116
-
117
- else
118
- raise "Unexpected characters: #{@ss.peek(5).inspect}"
119
- end
120
- end
121
-
122
- @tokens.push [false, false]
123
- end
124
- end
125
- end
@@ -1,6 +0,0 @@
1
- require "predicator/nodes/base_node"
2
- require "predicator/nodes/date_node"
3
- require "predicator/nodes/fixnum_node"
4
- require "predicator/nodes/float_node"
5
- require "predicator/nodes/nil_class_node"
6
- require "predicator/nodes/string_node"
@@ -1,53 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class BaseNode
4
- attr_reader :value
5
-
6
- def self.class_for value
7
- class_name = "#{value.class.name}Node"
8
- if ::Predicator::Nodes.const_defined? class_name
9
- ::Predicator::Nodes.const_get class_name
10
- else
11
- raise UnknownNodeTypeError, "Unknown node type for #{value.class} (#{value.inspect})"
12
- end
13
- end
14
-
15
- def initialize value
16
- @value = value
17
- end
18
-
19
- def blank?
20
- value.respond_to?(:empty?) ?
21
- !!value.empty? :
22
- !value
23
- end
24
-
25
- def present?
26
- !blank?
27
- end
28
-
29
- def comparison_method
30
- "compare_to_#{type}"
31
- end
32
-
33
- def compare_to_nil
34
- raise NilValueError
35
- end
36
-
37
- #def compare_to_date
38
- #end
39
-
40
- def compare_to_fixnum
41
- value.to_i
42
- end
43
-
44
- def compare_to_float
45
- value.to_f
46
- end
47
-
48
- def compare_to_string
49
- value.to_s
50
- end
51
- end
52
- end
53
- end
@@ -1,13 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class DateNode < BaseNode
4
- def type
5
- :date
6
- end
7
-
8
- def compare_to_date
9
- value
10
- end
11
- end
12
- end
13
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class FixnumNode < BaseNode
4
- def type
5
- :fixnum
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class FloatNode < BaseNode
4
- def type
5
- :float
6
- end
7
- end
8
- end
9
- end
@@ -1,25 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class NilClassNode < BaseNode
4
- def type
5
- :nil
6
- end
7
-
8
- def compare_to_date
9
- raise NilValueError
10
- end
11
-
12
- def compare_to_fixnum
13
- raise NilValueError
14
- end
15
-
16
- def compare_to_float
17
- raise NilValueError
18
- end
19
-
20
- def compare_to_string
21
- raise NilValueError
22
- end
23
- end
24
- end
25
- end
@@ -1,13 +0,0 @@
1
- module Predicator
2
- module Nodes
3
- class StringNode < BaseNode
4
- def type
5
- :string
6
- end
7
-
8
- def compare_to_date
9
- Date.parse value
10
- end
11
- end
12
- end
13
- end
@@ -1,14 +0,0 @@
1
- require "predicator/predicates/relation"
2
- require "predicator/predicates/equal"
3
- require "predicator/predicates/not_equal"
4
- require "predicator/predicates/greater_than"
5
- require "predicator/predicates/less_than"
6
- require "predicator/predicates/greater_than_or_equal"
7
- require "predicator/predicates/less_than_or_equal"
8
- require "predicator/predicates/between"
9
- require "predicator/predicates/true"
10
- require "predicator/predicates/false"
11
- require "predicator/predicates/and"
12
- require "predicator/predicates/or"
13
- require "predicator/predicates/not"
14
- require "predicator/predicates/method"
@@ -1,20 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class And
4
- attr_reader :predicates
5
-
6
- def initialize predicates
7
- @predicates = predicates
8
- end
9
-
10
- def satisfied? context=Predicator::Context.new
11
- predicates.all?{ |pred| pred.satisfied? context }
12
- end
13
-
14
- def == other
15
- other.kind_of?(self.class) &&
16
- other.predicates == predicates
17
- end
18
- end
19
- end
20
- end
@@ -1,31 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class Between
4
- attr_reader :value, :left, :right
5
-
6
- def initialize value, left, right
7
- @value, @left, @right = value, left, right
8
- end
9
-
10
- def satisfied? context=Predicator::Context.new
11
- value_node = context.node_for value
12
- left_node = context.node_for left
13
- right_node = context.node_for right
14
- method = "compare_to_#{value_node.type}"
15
-
16
- left_value = left_node.send method
17
- right_value = right_node.send method
18
-
19
- (value_node.value >= left_value) &&
20
- (value_node.value <= right_value)
21
- end
22
-
23
- def == other
24
- other.kind_of?(self.class) &&
25
- other.value == value &&
26
- other.left == left &&
27
- other.right == right
28
- end
29
- end
30
- end
31
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class Equal < Predicator::Predicates::Relation
4
- def compare_values lhs, rhs
5
- lhs == rhs
6
- end
7
- end
8
- end
9
- end
@@ -1,13 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class False
4
- def satisfied? context=Predicator::Context.new
5
- false
6
- end
7
-
8
- def == other
9
- other.kind_of?(self.class)
10
- end
11
- end
12
- end
13
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class GreaterThan < Predicator::Predicates::Relation
4
- def compare_values lhs, rhs
5
- lhs > rhs
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class GreaterThanOrEqual < Predicator::Predicates::Relation
4
- def compare_values lhs, rhs
5
- lhs >= rhs
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class LessThan < Predicator::Predicates::Relation
4
- def compare_values lhs, rhs
5
- lhs < rhs
6
- end
7
- end
8
- end
9
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class LessThanOrEqual < Predicator::Predicates::Relation
4
- def compare_values lhs, rhs
5
- lhs <= rhs
6
- end
7
- end
8
- end
9
- end
@@ -1,17 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class Method
4
- attr_reader :value, :method
5
-
6
- def initialize value, method
7
- @value = value
8
- @method = method
9
- end
10
-
11
- def satisfied? context=Predicator::Context.new
12
- node = context.node_for value
13
- node.send method
14
- end
15
- end
16
- end
17
- end
@@ -1,20 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class Not
4
- attr_reader :predicate
5
-
6
- def initialize predicate
7
- @predicate = predicate
8
- end
9
-
10
- def satisfied? context=Predicator::Context.new
11
- !predicate.satisfied? context
12
- end
13
-
14
- def == other
15
- other.kind_of?(self.class) &&
16
- other.predicate == predicate
17
- end
18
- end
19
- end
20
- end