factbase 0.0.26 → 0.0.28

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1be768141fbb97e4753b38b4b8c438a8cf870957744868af05ab325bec94582c
4
- data.tar.gz: bcef0970b79fba877d7f677440e595382a64cab724b00d7df101a0a2bf66d146
3
+ metadata.gz: ffdf62af221a65ab9efa6097b01dab23edba0399bc8551757d450ff828f14367
4
+ data.tar.gz: 175dd8ead3a933305d46c8c4bb657a46efc507db3ad1045bb7495614dedfc1c2
5
5
  SHA512:
6
- metadata.gz: 2b705bad3bc10f08a9865217f015069c34e679c6718382f321926d6ae76b96db6e56dd4c76540eeec8fb0511a8e7a40077d7ac8092fbe6588d75cefaf9e5f4d1
7
- data.tar.gz: 3e4c1a563194008beb1697f5a4e146a0a88713fb876c8414893bff69db34b33a10d812135f85cac8ef9655d50d40d7186a3b00aa4c863f5ce4ba4a52429d9c37
6
+ metadata.gz: ccade318b2db8568b72fcd29dd8d8cc301a791911a749bba8154485e8e95d1a00c2466477ff7e798f8a5146e87e03c69af8493fd05ae38c9463a8ffc9e29da62
7
+ data.tar.gz: 30730a5e848923b73c98f188142f30f56fd8eec95d8839561a6be01956922f60d9fe46a9dcf361b2f6b4bffca993fd20471bd51f1e2840659ba7bc252c9853b2
@@ -43,6 +43,7 @@ class Factbase::Syntax
43
43
  @ast ||= to_ast(@tokens, 0)
44
44
  term = @ast[0]
45
45
  raise 'No terms found' if term.nil?
46
+ raise 'Not a term' unless term.is_a?(Factbase::Term)
46
47
  term
47
48
  end
48
49
 
@@ -81,7 +82,7 @@ class Factbase::Syntax
81
82
  list = []
82
83
  acc = ''
83
84
  string = false
84
- @query.to_s.chars.each do |c|
85
+ @query.to_s.gsub(/#.*$/, '').chars.each do |c|
85
86
  if ['\'', '"'].include?(c)
86
87
  if string && acc[acc.length - 1] == '\\'
87
88
  acc = acc[0..-2]
data/lib/factbase/term.rb CHANGED
@@ -97,18 +97,12 @@ class Factbase::Term
97
97
 
98
98
  def exists(fact)
99
99
  assert_args(1)
100
- o = @operands[0]
101
- raise "A symbol expected: #{o}" unless o.is_a?(Symbol)
102
- k = o.to_s
103
- !fact[k].nil?
100
+ !by_symbol(0, fact).nil?
104
101
  end
105
102
 
106
103
  def absent(fact)
107
104
  assert_args(1)
108
- o = @operands[0]
109
- raise "A symbol expected: #{o}" unless o.is_a?(Symbol)
110
- k = o.to_s
111
- fact[k].nil?
105
+ by_symbol(0, fact).nil?
112
106
  end
113
107
 
114
108
  def eq(fact)
@@ -125,29 +119,31 @@ class Factbase::Term
125
119
 
126
120
  def size(fact)
127
121
  assert_args(1)
128
- o = @operands[0]
129
- raise "A symbol expected: #{o}" unless o.is_a?(Symbol)
130
- k = o.to_s
131
- return 0 if fact[k].nil?
132
- return 1 unless fact[k].is_a?(Array)
133
- fact[k].size
122
+ v = by_symbol(0, fact)
123
+ return 0 if v.nil?
124
+ return 1 unless v.is_a?(Array)
125
+ v.size
126
+ end
127
+
128
+ def type(fact)
129
+ assert_args(1)
130
+ v = by_symbol(0, fact)
131
+ return 'nil' if v.nil?
132
+ v.class.to_s
134
133
  end
135
134
 
136
135
  def arithmetic(op, fact)
137
136
  assert_args(2)
138
- o = @operands[0]
139
- if o.is_a?(Factbase::Term)
140
- v = o.eval(fact)
141
- else
142
- raise "A symbol expected by #{op}: #{o}" unless o.is_a?(Symbol)
143
- k = o.to_s
144
- v = fact[k]
145
- end
146
- return false if v.nil?
147
- v = [v] unless v.is_a?(Array)
148
- v.any? do |vv|
149
- vv = vv.floor if vv.is_a?(Time) && op == :==
150
- vv.send(op, @operands[1])
137
+ lefts = the_value(0, fact)
138
+ return false if lefts.nil?
139
+ rights = the_value(1, fact)
140
+ return false if rights.nil?
141
+ lefts.any? do |l|
142
+ l = l.floor if l.is_a?(Time) && op == :==
143
+ rights.any? do |r|
144
+ r = r.floor if r.is_a?(Time) && op == :==
145
+ l.send(op, r)
146
+ end
151
147
  end
152
148
  end
153
149
 
@@ -156,4 +152,20 @@ class Factbase::Term
156
152
  raise "Too many (#{c}) operands for '#{@op}' (#{num} expected)" if c > num
157
153
  raise "Too few (#{c}) operands for '#{@op}' (#{num} expected)" if c < num
158
154
  end
155
+
156
+ def by_symbol(pos, fact)
157
+ o = @operands[pos]
158
+ raise "A symbol expected at ##{pos}, but provided: #{o}" unless o.is_a?(Symbol)
159
+ k = o.to_s
160
+ fact[k]
161
+ end
162
+
163
+ def the_value(pos, fact)
164
+ v = @operands[pos]
165
+ v = v.eval(fact) if v.is_a?(Factbase::Term)
166
+ v = fact[v.to_s] if v.is_a?(Symbol)
167
+ return v if v.nil?
168
+ v = [v] unless v.is_a?(Array)
169
+ v
170
+ end
159
171
  end
data/lib/factbase.rb CHANGED
@@ -29,7 +29,7 @@ require 'yaml'
29
29
  # License:: MIT
30
30
  class Factbase
31
31
  # Current version of the gem (changed by .rultor.yml on every release)
32
- VERSION = '0.0.26'
32
+ VERSION = '0.0.28'
33
33
 
34
34
  # Constructor.
35
35
  def initialize(facts = [])
@@ -54,9 +54,11 @@ class TestQuery < Minitest::Test
54
54
  "(and (lt pi 100) \n\n (gt num 1000))" => 0,
55
55
  '(exists pi)' => 1,
56
56
  '(not (exists hello))' => 3,
57
+ '(eq "Integer" (type num))' => 2,
57
58
  '(gt (size num) 2)' => 1,
58
59
  '(lt (size num) 2)' => 2,
59
60
  '(eq (size hello) 0)' => 3,
61
+ '(eq num pi)' => 0,
60
62
  '(absent time)' => 2,
61
63
  '(and (absent time) (exists pi))' => 1,
62
64
  "(and (exists time) (not (\t\texists pi)))" => 1,
@@ -45,6 +45,7 @@ class TestSyntax < Minitest::Test
45
45
  '(foo)',
46
46
  '(foo (bar) (zz 77) )',
47
47
  "(eq foo \n\n 'Hello, world!'\n)\n",
48
+ "# this is a comment\n(eq foo # test\n 42)\n\n# another comment\n",
48
49
  "(or ( a 4) (b 5) () (and () (c 5) \t\t(r 7 8s 8is 'Foo')))"
49
50
  ].each do |q|
50
51
  Factbase::Syntax.new(q).to_term
@@ -90,6 +91,7 @@ class TestSyntax < Minitest::Test
90
91
  [
91
92
  '',
92
93
  '(foo',
94
+ 'some text',
93
95
  '"hello, world!',
94
96
  '(foo 7',
95
97
  "(foo 7 'Dude'",
@@ -111,6 +111,16 @@ class TestTerm < Minitest::Test
111
111
  assert(!t.eval(fact('foo' => 100)))
112
112
  end
113
113
 
114
+ def test_type_matching
115
+ t = Factbase::Term.new(:type, [:foo])
116
+ assert_equal('Integer', t.eval(fact('foo' => 42)))
117
+ assert_equal('Array', t.eval(fact('foo' => [1, 2, 3])))
118
+ assert_equal('String', t.eval(fact('foo' => 'Hello, world!')))
119
+ assert_equal('Float', t.eval(fact('foo' => 3.14)))
120
+ assert_equal('Time', t.eval(fact('foo' => Time.now)))
121
+ assert_equal('nil', t.eval(fact))
122
+ end
123
+
114
124
  def test_or_matching
115
125
  t = Factbase::Term.new(
116
126
  :or,
@@ -139,7 +149,7 @@ class TestTerm < Minitest::Test
139
149
 
140
150
  private
141
151
 
142
- def fact(map)
152
+ def fact(map = {})
143
153
  Factbase::Fact.new(Mutex.new, map)
144
154
  end
145
155
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.26
4
+ version: 0.0.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko