interrotron 0.0.4 → 0.0.5

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.
data/README.md CHANGED
@@ -35,7 +35,9 @@ compiled.call(:my_param => 'bar')
35
35
  # Since interrotron is meant for business rules, it handles dates as a
36
36
  # native type as instances of ruby's DateTime class. You can use literals
37
37
  # for that like so:
38
- Interrotron.run('(> #dt{2010-09-04} start_date)', start_date: DateTime.parse('2012-12-12'))
38
+ Interrotron.run('(> #t{2010-09-04} start_date)', start_date: DateTime.parse('2012-12-12').to_time)
39
+ # => true
40
+ Interrotron.run('(> (now) (ago (hours 12)))')
39
41
  # => true
40
42
 
41
43
  # You can, of course, create arbitarily complex exprs
@@ -64,12 +66,11 @@ The following functions and variables are built in to Interrotron (and more are
64
66
  (floor expr) ; equiv to num.floor
65
67
  (ceil expr) ; equiv to num.ceil
66
68
  (round expr) ; equiv to num.round
67
- (to_i expr) ; int conversion
68
- (to_f expr) ; float conversion
69
+ (int expr) ; int conversion
70
+ (float expr) ; float conversion
69
71
  (rand) ; returns a random float between 0 and 1
70
72
  (upcase str) ; uppercases a string
71
73
  (downcase) ; lowercases a string
72
- (now) ; returns the current DateTime
73
74
  (array e1, e2, ...) ; creates an array
74
75
  (max arr) ; returns the largest element of an array
75
76
  (min arr) ; returns the smallest element of an array
@@ -78,6 +79,14 @@ The following functions and variables are built in to Interrotron (and more are
78
79
  (last arr) ; get arr tail
79
80
  (nth pos arr) ; get array at index
80
81
  (member? val arr) ; check if the array has a member with value 'val'
82
+ (now) ; returns the current DateTime
83
+ (seconds n); n, for completeness
84
+ (minutes n); n * secs_in_a_minute
85
+ (hours n); n * secs_in_a_hour
86
+ (months n) ; n * secs_in_a_month
87
+ (ago n) ; yields a time in seconds from now
88
+ (from-now n) ; yields a time in seconds from now
89
+ (time 'str') ; parses a string to a Time
81
90
  ```
82
91
 
83
92
  ## Contributing
data/Rakefile CHANGED
@@ -2,7 +2,8 @@
2
2
  require "bundler/gem_tasks"
3
3
  require "rspec/core/rake_task"
4
4
 
5
- Bundler::GemHelper.install_tasks
5
+ # This seems to deplicate tasks
6
+ #Bundler::GemHelper.install_tasks
6
7
 
7
8
  RSpec::Core::RakeTask.new('spec') do |t|
8
9
  t.rspec_opts = '--tag ~integration'
@@ -12,5 +13,4 @@ RSpec::Core::RakeTask.new('spec:integration') do |t|
12
13
  t.pattern = 'spec/integration/*_spec.rb'
13
14
  end
14
15
 
15
- task :default => :spec
16
-
16
+ task :default => :spec
data/bin/interrotron ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'interrotron'
4
+
5
+ puts Interrotron.run(ARGV[0]).inspect
data/interrotron.gemspec CHANGED
@@ -9,7 +9,8 @@ Gem::Specification.new do |gem|
9
9
  gem.homepage = ""
10
10
 
11
11
  gem.files = `git ls-files`.split($\)
12
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
12
+ gem.executables << 'interrotron'
13
+ #gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
14
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
15
  gem.name = "interrotron"
15
16
  gem.require_paths = ["lib"]
data/lib/interrotron.rb CHANGED
@@ -44,17 +44,17 @@ class Interrotron
44
44
  end
45
45
 
46
46
  TOKENS = [
47
- [:lpar, /\(/],
48
- [:rpar, /\)/],
49
- [:fn, /fn/],
50
- [:var, /[A-Za-z_><\+\>\<\!\=\*\/\%\-\?]+/],
51
- [:num, /(\-?[0-9]+(\.[0-9]+)?)/,
47
+ [:lpar, /\A\(/],
48
+ [:rpar, /\A\)/],
49
+ [:fn, /\Afn/],
50
+ [:var, /\A[A-Za-z_><\+\>\<\!\=\*\/\%\-\?]+/],
51
+ [:num, /\A(\-?[0-9]+(\.[0-9]+)?)/,
52
52
  {cast: proc {|v| v =~ /\./ ? v.to_f : v.to_i }}],
53
- [:datetime, /#dt\{([^\{]+)\}/,
54
- {capture: 1, cast: proc {|v| DateTime.parse(v) }}],
55
- [:spc, /\s+/, {discard: true}],
56
- [:str, /"([^"\\]*(\\.[^"\\]*)*)"/, {capture: 1}],
57
- [:str, /'([^'\\]*(\\.[^'\\]*)*)'/, {capture: 1}]
53
+ [:time, /\A#t\{([^\{]+)\}/,
54
+ {capture: 1, cast: proc {|v| DateTime.parse(v).to_time }}],
55
+ [:spc, /\A\s+/, {discard: true}],
56
+ [:str, /\A"([^"\\]*(\\.[^"\\]*)*)"/, {capture: 1}],
57
+ [:str, /\A'([^'\\]*(\\.[^'\\]*)*)'/, {capture: 1}]
58
58
  ]
59
59
 
60
60
  # Quote a ruby variable as a interrotron one
@@ -76,6 +76,7 @@ class Interrotron
76
76
  },
77
77
  'and' => Macro.new {|i,*args| args.all? {|a| i.iro_eval(a)} ? args.last : qvar('false') },
78
78
  'or' => Macro.new {|i,*args| args.detect {|a| i.iro_eval(a) } || qvar('false') },
79
+ 'apply' => proc {|fn,arr| fn.call(*arr) },
79
80
  'array' => proc {|*args| args},
80
81
  'identity' => proc {|a| a},
81
82
  'not' => proc {|a| !a},
@@ -104,13 +105,22 @@ class Interrotron
104
105
  'nth' => proc {|pos, arr| arr[pos]},
105
106
  'length' => proc {|arr| arr.length},
106
107
  'member?' => proc {|v,arr| arr.member? v},
107
- 'to_i' => proc {|a| a.to_i},
108
- 'to_f' => proc {|a| a.to_f},
109
- 'rand' => proc { rand },
108
+ 'int' => proc {|a| a.to_i},
109
+ 'float' => proc {|a| a.to_f},
110
+ 'time' => proc {|s| DateTime.parse(s).to_time},
111
+ 'rand' => proc {|n| rand n },
112
+ 'str' => proc {|*args| args.reduce("") {|m,a| m + a.to_s}},
113
+ 'strip' => proc {|s| s.strip},
110
114
  'upcase' => proc {|a| a.upcase},
111
115
  'downcase' => proc {|a| a.downcase},
112
- 'now' => proc { DateTime.now },
113
- 'str' => proc {|*args| args.reduce("") {|m,a| m + a.to_s}}
116
+ 'now' => proc { Time.now },
117
+ 'seconds' => proc {|n| n.to_i},
118
+ 'minutes' => proc {|n| n.to_i * 60},
119
+ 'hours' => proc {|n| n.to_i * 3600 },
120
+ 'days' => proc {|n| n.to_i * 86400},
121
+ 'months' => proc {|n| n.to_i * 2592000},
122
+ 'ago' => proc {|t| Time.now - t},
123
+ 'from-now' => proc {|t| Time.now + t}
114
124
  })
115
125
 
116
126
  def initialize(vars={},max_ops=nil)
@@ -131,7 +141,7 @@ class Interrotron
131
141
  matched_any = TOKENS.any? {|name,matcher,opts|
132
142
  opts ||= {}
133
143
  matches = matcher.match(str)
134
- if !matches || !matches.pre_match.empty?
144
+ if !matches
135
145
  false
136
146
  else
137
147
  str = str[matches[0].length..-1]
@@ -1,3 +1,3 @@
1
1
  class Interrotron
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -59,9 +59,22 @@ describe "running" do
59
59
  end
60
60
  end
61
61
 
62
- describe "date times" do
62
+ describe "times" do
63
63
  it "should parse and compare them properly" do
64
- run('(> #dt{2010-09-04} start_date)', start_date: DateTime.parse('2012-12-12'))
64
+ run('(> #t{2010-09-04} start_date)', start_date: DateTime.parse('2012-12-12').to_time)
65
+ end
66
+ it "should understand days, minutes, seconds, and hours, as integers" do
67
+ run("(+ (days 1) (minutes 1) (hours 1) (seconds 1))").should == 90061
68
+ end
69
+
70
+ it "should add the time using from-now" do
71
+ n = Time.now
72
+ Time.should_receive(:now).twice().and_return(n)
73
+ run("(from-now (minutes 1))").to_i.should == (Time.now + 60).to_i
74
+ end
75
+
76
+ it "should compare times using convenience multipliers correctly" do
77
+ run('(> (now) (ago (hours 12)))').should be_true
65
78
  end
66
79
  end
67
80
 
@@ -171,4 +184,28 @@ describe "running" do
171
184
  run("").should be_nil
172
185
  end
173
186
  end
187
+
188
+ describe "apply macro" do
189
+ it "should spat an array into another function" do
190
+ run("(apply + (array 1 2 3))").should == 6
191
+ end
192
+ end
193
+
194
+ describe "conversions" do
195
+ it "should convert ints" do
196
+ res = run("(int '2')")
197
+ res.should == 2
198
+ res.should be_a(Fixnum)
199
+ end
200
+
201
+ it "should convert floats" do
202
+ res = run("(float '2.5')")
203
+ res.should == 2.5
204
+ res.should be_a(Float)
205
+ end
206
+
207
+ it "should parse dates and times" do
208
+ run("(time '2012-05-01')").should == DateTime.parse("2012-05-01").to_time
209
+ end
210
+ end
174
211
  end
metadata CHANGED
@@ -1,31 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: interrotron
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
5
- prerelease:
4
+ prerelease:
5
+ version: 0.0.5
6
6
  platform: ruby
7
7
  authors:
8
8
  - Andrew Cholakian
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-27 00:00:00.000000000 Z
12
+ date: 2012-05-27 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70187372115860 !ruby/object:Gem::Requirement
17
- none: false
16
+ version_requirements: &2056 !ruby/object:Gem::Requirement
18
17
  requirements:
19
18
  - - ~>
20
19
  - !ruby/object:Gem::Version
21
20
  version: '2.6'
22
- type: :development
21
+ none: false
22
+ requirement: *2056
23
23
  prerelease: false
24
- version_requirements: *70187372115860
24
+ type: :development
25
25
  description: A tiny, embeddable, lisp VM
26
26
  email:
27
27
  - andrew@andrewvc.com
28
- executables: []
28
+ executables:
29
+ - interrotron
29
30
  extensions: []
30
31
  extra_rdoc_files: []
31
32
  files:
@@ -35,33 +36,35 @@ files:
35
36
  - LICENSE
36
37
  - README.md
37
38
  - Rakefile
39
+ - bin/interrotron
38
40
  - interrotron.gemspec
39
41
  - lib/interrotron.rb
40
42
  - lib/interrotron/version.rb
41
43
  - spec/interrotron_spec.rb
42
44
  homepage: ''
43
45
  licenses: []
44
- post_install_message:
46
+ post_install_message:
45
47
  rdoc_options: []
46
48
  require_paths:
47
49
  - lib
48
50
  required_ruby_version: !ruby/object:Gem::Requirement
49
- none: false
50
51
  requirements:
51
52
  - - ! '>='
52
53
  - !ruby/object:Gem::Version
53
54
  version: '0'
54
- required_rubygems_version: !ruby/object:Gem::Requirement
55
55
  none: false
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
57
  requirements:
57
58
  - - ! '>='
58
59
  - !ruby/object:Gem::Version
59
60
  version: '0'
61
+ none: false
60
62
  requirements: []
61
- rubyforge_project:
62
- rubygems_version: 1.8.10
63
- signing_key:
63
+ rubyforge_project:
64
+ rubygems_version: 1.8.9
65
+ signing_key:
64
66
  specification_version: 3
65
67
  summary: A lisp VM meant to run with guarantees on execution for business rules
66
68
  test_files:
67
69
  - spec/interrotron_spec.rb
70
+ ...