predicator 0.3.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +46 -0
  4. data/.travis.yml +3 -2
  5. data/HISTORY.md +31 -0
  6. data/README.md +33 -12
  7. data/Rakefile +14 -5
  8. data/lib/predicator.rb +18 -4
  9. data/lib/predicator/ast.rb +190 -0
  10. data/lib/predicator/context.rb +7 -12
  11. data/lib/predicator/evaluator.rb +153 -0
  12. data/lib/predicator/lexer.rex +69 -0
  13. data/lib/predicator/lexer.rex.rb +187 -0
  14. data/lib/predicator/parser.rb +427 -26
  15. data/lib/predicator/parser.y +103 -35
  16. data/lib/predicator/version.rb +1 -1
  17. data/lib/predicator/visitors.rb +5 -0
  18. data/lib/predicator/visitors/dot.rb +113 -0
  19. data/lib/predicator/visitors/each.rb +16 -0
  20. data/lib/predicator/visitors/instructions.rb +183 -0
  21. data/lib/predicator/visitors/string.rb +76 -0
  22. data/lib/predicator/visitors/visitor.rb +100 -0
  23. data/predicator.gemspec +10 -2
  24. metadata +67 -28
  25. data/lib/predicator/generated_parser.rb +0 -307
  26. data/lib/predicator/lexer.rb +0 -117
  27. data/lib/predicator/predicates/and.rb +0 -20
  28. data/lib/predicator/predicates/between.rb +0 -23
  29. data/lib/predicator/predicates/equal.rb +0 -9
  30. data/lib/predicator/predicates/false.rb +0 -13
  31. data/lib/predicator/predicates/greater_than.rb +0 -9
  32. data/lib/predicator/predicates/greater_than_or_equal.rb +0 -9
  33. data/lib/predicator/predicates/less_than.rb +0 -9
  34. data/lib/predicator/predicates/less_than_or_equal.rb +0 -9
  35. data/lib/predicator/predicates/not.rb +0 -20
  36. data/lib/predicator/predicates/not_equal.rb +0 -9
  37. data/lib/predicator/predicates/or.rb +0 -20
  38. data/lib/predicator/predicates/relation.rb +0 -17
  39. data/lib/predicator/predicates/true.rb +0 -13
  40. data/lib/predicator/variable.rb +0 -26
@@ -1,117 +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
- STRING = /(["])(?:\\?.)*?\1/
26
- IDENTIFIER = /[a-z][A-Za-z0-9_]*/
27
-
28
- def initialize string_or_io
29
- io = string_or_io.is_a?(String) ?
30
- StringIO.new(string_or_io) :
31
- string_or_io
32
-
33
- @ss = StringScanner.new io.read
34
- @tokens = []
35
- tokenize
36
- end
37
-
38
- def next_token
39
- @tokens.shift
40
- end
41
-
42
- def tokenize
43
- until @ss.eos?
44
- case
45
- when @ss.scan(SPACE)
46
- # ignore space
47
-
48
- when text = @ss.scan(DOT)
49
- @tokens.push [:tDOT, text]
50
-
51
- when text = @ss.scan(LPAREN)
52
- @tokens.push [:tLPAREN, text]
53
-
54
- when text = @ss.scan(RPAREN)
55
- @tokens.push [:tRPAREN, text]
56
-
57
- when text = @ss.scan(NEQ)
58
- @tokens.push [:tNEQ, text]
59
-
60
- when text = @ss.scan(GEQ)
61
- @tokens.push [:tGEQ, text]
62
-
63
- when text = @ss.scan(LEQ)
64
- @tokens.push [:tLEQ, text]
65
-
66
- when text = @ss.scan(GT)
67
- @tokens.push [:tGT, text]
68
-
69
- when text = @ss.scan(LT)
70
- @tokens.push [:tLT, text]
71
-
72
- when text = @ss.scan(EQ)
73
- @tokens.push [:tEQ, text]
74
-
75
- when text = @ss.scan(BANG)
76
- @tokens.push [:tBANG, text]
77
-
78
- when text = @ss.scan(DATE)
79
- args = [ @ss[1], @ss[2], @ss[3] ].map(&:to_i)
80
- @tokens.push [:tDATE, args]
81
-
82
- when text = @ss.scan(FLOAT)
83
- @tokens.push [:tFLOAT, text]
84
-
85
- when text = @ss.scan(INTEGER)
86
- @tokens.push [:tINTEGER, text]
87
-
88
- when text = @ss.scan(TRUE)
89
- @tokens.push [:tTRUE, text]
90
-
91
- when text = @ss.scan(FALSE)
92
- @tokens.push [:tFALSE, text]
93
-
94
- when text = @ss.scan(AND)
95
- @tokens.push [:tAND, text]
96
-
97
- when text = @ss.scan(OR)
98
- @tokens.push [:tOR, text]
99
-
100
- when text = @ss.scan(BETWEEN)
101
- @tokens.push [:tBETWEEN, text]
102
-
103
- when text = @ss.scan(STRING)
104
- @tokens.push [:tSTRING, text[1..-2]]
105
-
106
- when text = @ss.scan(IDENTIFIER)
107
- @tokens.push [:tIDENTIFIER, text]
108
-
109
- else
110
- raise "Unexpected characters: #{@ss.peek(5).inspect}"
111
- end
112
- end
113
-
114
- @tokens.push [false, false]
115
- end
116
- end
117
- end
@@ -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,23 +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
- context.value_for(value) >= context.value_for(left) &&
12
- context.value_for(value) <= context.value_for(right)
13
- end
14
-
15
- def == other
16
- other.kind_of?(self.class) &&
17
- other.value == value &&
18
- other.left == left &&
19
- other.right == right
20
- end
21
- end
22
- end
23
- end
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class Equal < Predicator::Predicates::Relation
4
- def satisfied? context=Predicator::Context.new
5
- context.value_for(left) == context.value_for(right)
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 satisfied? context=Predicator::Context.new
5
- context.value_for(left) > context.value_for(right)
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 satisfied? context=Predicator::Context.new
5
- context.value_for(left) >= context.value_for(right)
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 satisfied? context=Predicator::Context.new
5
- context.value_for(left) < context.value_for(right)
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 satisfied? context=Predicator::Context.new
5
- context.value_for(left) <= context.value_for(right)
6
- end
7
- end
8
- end
9
- 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
@@ -1,9 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class NotEqual < Predicator::Predicates::Relation
4
- def satisfied? context=Predicator::Context.new
5
- context.value_for(left) != context.value_for(right)
6
- end
7
- end
8
- end
9
- end
@@ -1,20 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class Or
4
- attr_reader :predicates
5
-
6
- def initialize predicates
7
- @predicates = predicates
8
- end
9
-
10
- def satisfied? context=Predicator::Context.new
11
- predicates.any?{ |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,17 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class Relation
4
- attr_reader :left, :right
5
-
6
- def initialize left, right
7
- @left, @right = left, right
8
- end
9
-
10
- def == other
11
- other.kind_of?(self.class) &&
12
- other.left == left &&
13
- other.right == right
14
- end
15
- end
16
- end
17
- end
@@ -1,13 +0,0 @@
1
- module Predicator
2
- module Predicates
3
- class True
4
- def satisfied? context=Predicator::Context.new
5
- true
6
- end
7
-
8
- def == other
9
- other.kind_of?(self.class)
10
- end
11
- end
12
- end
13
- end
@@ -1,26 +0,0 @@
1
- module Predicator
2
- class Variable
3
- attr_reader :model, :attribute
4
-
5
- def initialize model, attribute
6
- @model = model
7
- @attribute = attribute
8
- end
9
-
10
- def value_in context
11
- entity_name = model.to_s
12
- entity = context.bindings[model]
13
- if entity.nil?
14
- raise ArgumentError, "Unknown entity #{entity_name}"
15
- else
16
- entity.send attribute
17
- end
18
- end
19
-
20
- def == other
21
- other.kind_of?(self.class) &&
22
- other.model == model &&
23
- other.attribute == attribute
24
- end
25
- end
26
- end