delorean_lang 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f51984247bdded71f32757212ebef7550f047308
4
- data.tar.gz: d7ad1108229516517af20540716b7779f9ae1405
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NjRmOWNjNTZjNTM5MWE0ZmE3OTM4MGE3MTY1MjRjZDgzNDdjZWRlMQ==
5
+ data.tar.gz: !binary |-
6
+ ZDlhMDJkNjhmODM4Yjg0OTAxYWZhMDk1MDE2M2M2NGU4ZTQ4Yzc2ZA==
5
7
  SHA512:
6
- metadata.gz: ab67c2085eced7cc1745437b8137eadec5fc9f1de17e8ab5ab4962239b2b948c47d5f5d95e9f8595bb24dccd84da398a90842e27ae578e3b70faec5445727812
7
- data.tar.gz: 0e07256b63586bd26ce0ecb429af36636e81123c5e59e310d55eaa9ebff241ab5310c7dda1ab3b1ed596949ee2fa27b19b03a2e333d2933aee06beb0bbe71f66
8
+ metadata.gz: !binary |-
9
+ YmQ4NjNlMDgyMDBkMTczNzc5NGU5YjE1NmJlMDAzODhkMWJmMTkwNzIzZDc4
10
+ ZDQzZTVmMmQ4MTlmYzllOTc3ZDdhZGJiNjk5NDA3MmUwNTY4OGFkNmRjODYw
11
+ YjM2ZWEyMTliMjY4OWUxOTg5NGUzODVkMzQxODVhMmFlYTJjYTY=
12
+ data.tar.gz: !binary |-
13
+ NzE3NWI2ZGE2OTVjMDQ2NDg4YTAwN2ZmNjRkOWE4YTRmZjI3NDY1ZGI5N2Vk
14
+ ODU2MmZjMzM0YzYyNDgwYzlmODlmZDc1YjFhYjQyMWI5N2JjOTZlOTgxMDBi
15
+ ZTQwNzEyY2M4ZjA2ZmEzMDAwZTQ0M2M4MGQzNjM3ODQ2MTk4ODk=
@@ -18,6 +18,17 @@ module Delorean
18
18
  sort: [Array],
19
19
  split: [String, String],
20
20
  uniq: [Array],
21
+ sum: [Array],
22
+ zip: [Array, [Array, Array, Array]],
23
+ index: [Array, [Integer, Numeric, String, Array, Fixnum]],
24
+ product: [Array, Array],
25
+ first: [Enumerable, [nil, Fixnum]],
26
+
27
+ keys: [Hash],
28
+ values: [Hash],
29
+ upcase: [String],
30
+ downcase: [String],
31
+ match: [String, [String], [nil, Fixnum]],
21
32
 
22
33
  hour: [[Date, Time, ActiveSupport::TimeWithZone]],
23
34
  min: [[Date, Time, ActiveSupport::TimeWithZone, Array]],
@@ -28,6 +39,24 @@ module Delorean
28
39
  day: [[Date, Time, ActiveSupport::TimeWithZone]],
29
40
  year: [[Date, Time, ActiveSupport::TimeWithZone]],
30
41
 
42
+ next_month: [[Date, Time, ActiveSupport::TimeWithZone],
43
+ [nil, Fixnum],
44
+ ],
45
+ prev_month: [[Date, Time, ActiveSupport::TimeWithZone],
46
+ [nil, Fixnum],
47
+ ],
48
+
49
+ beginning_of_month: [[Date, Time, ActiveSupport::TimeWithZone]],
50
+
51
+ end_of_month: [[Date, Time, ActiveSupport::TimeWithZone]],
52
+
53
+ next_day: [[Date, Time, ActiveSupport::TimeWithZone],
54
+ [nil, Fixnum],
55
+ ],
56
+ prev_day: [[Date, Time, ActiveSupport::TimeWithZone],
57
+ [nil, Fixnum],
58
+ ],
59
+
31
60
  to_i: [[Numeric, String]],
32
61
  to_f: [[Numeric, String]],
33
62
  to_d: [[Numeric, String]],
@@ -37,12 +66,7 @@ module Delorean
37
66
  }
38
67
 
39
68
  module BaseModule
40
- class NodeCall
41
- attr_reader :engine, :node, :params
42
- def initialize(engine, node, params)
43
- @engine, @node, @params = engine, node, params
44
- end
45
-
69
+ class NodeCall < Struct.new(:_e, :engine, :node, :params)
46
70
  def evaluate(attr)
47
71
  engine.evaluate(node, attr, params)
48
72
  end
@@ -57,7 +81,6 @@ module Delorean
57
81
  end
58
82
 
59
83
  class BaseClass
60
-
61
84
  def self._get_attr(obj, attr, _e)
62
85
  return nil if obj.nil?
63
86
 
@@ -114,10 +137,14 @@ module Delorean
114
137
  raise str
115
138
  end
116
139
 
117
- def self._node_call(node, mname, _e, params)
140
+ def self._node_call(node, _e, params)
118
141
  context = _e[:_engine]
119
- engine = mname ? context.get_import_engine(mname) : context
120
- NodeCall.new(engine, node || self, params)
142
+
143
+ engine = node.is_a?(Class) &&
144
+ context.module_name != node.module_name ?
145
+ context.get_import_engine(node.module_name) : context
146
+
147
+ NodeCall.new(_e, engine, node || self, params)
121
148
  end
122
149
 
123
150
  ######################################################################
@@ -150,7 +177,7 @@ module Delorean
150
177
  break
151
178
  end
152
179
  }
153
- raise "bad arg #{i} to method #{method}: #{ai}/#{ai.class} #{s}" unless ok
180
+ raise "bad arg #{i}, method #{method}: #{ai}/#{ai.class} #{s}" if !ok
154
181
  }
155
182
 
156
183
  obj.send(msg, *args)
@@ -5,11 +5,12 @@ require 'pp'
5
5
 
6
6
  module Delorean
7
7
  class Engine
8
- attr_reader :last_node, :module_name, :line_no, :comp_set, :pm, :m, :imports
8
+ attr_reader :last_node, :module_name, :version,
9
+ :line_no, :comp_set, :pm, :m, :imports
9
10
 
10
- def initialize(module_name)
11
+ def initialize(module_name, version=nil)
11
12
  # name of current module
12
- @module_name = module_name
13
+ @module_name, @version = module_name, version
13
14
  reset
14
15
  end
15
16
 
@@ -142,13 +143,14 @@ module Delorean
142
143
  @node_attrs[@last_node].member? name
143
144
 
144
145
  @node_attrs[@last_node] << name
145
-
146
+
146
147
  checks = spec.map { |a|
147
- n = a.index('.') ? a : (@last_node + "." + a)
148
+ n = a.index('.') ? a : "#{@last_node}.#{a}"
148
149
  "_x.member?('#{n}') ? raise('#{n}') : #{a}#{POST}(_x + ['#{n}'])"
149
150
  }.join(';')
150
151
 
151
- code = "class #{@last_node}; def self.#{name}#{POST}(_x); #{checks}; end; end"
152
+ code =
153
+ "class #{@last_node}; def self.#{name}#{POST}(_x); #{checks}; end; end"
152
154
 
153
155
  # pp code
154
156
 
@@ -213,8 +215,12 @@ module Delorean
213
215
  def generate(t, sset=nil)
214
216
  t.check(self, sset)
215
217
 
216
- # generate ruby code
217
- gen = t.rewrite(self)
218
+ begin
219
+ # generate ruby code
220
+ gen = t.rewrite(self)
221
+ rescue RuntimeError => exc
222
+ err(ParseError, "codegen error: " + exc.message)
223
+ end
218
224
 
219
225
  # puts gen
220
226
 
@@ -251,7 +257,7 @@ module Delorean
251
257
  # Inside a multiline and next line doesn't look like a
252
258
  # continuation => syntax error.
253
259
  err(ParseError, "syntax error") unless line =~ /^\s+/
254
-
260
+
255
261
  multi_line += line
256
262
  t = parser.parse(multi_line)
257
263
 
@@ -362,16 +368,14 @@ module Delorean
362
368
  }
363
369
  end
364
370
 
365
- # FIXME: should be renamed to grok_runtime_exception so as to not
366
- # be confused with other parse_* calls which occur at parse time.
367
- def parse_runtime_exception(exc)
371
+ def self.grok_runtime_exception(exc)
368
372
  # parse out the delorean-related backtrace records
369
373
  bt = exc.backtrace.map{ |x|
370
374
  x.match(/^#{MOD}(.+?):(\d+)(|:in `(.+)')$/);
371
375
  $1 && [$1, $2.to_i, $4.sub(/#{POST}$/, '')]
372
376
  }.reject(&:!)
373
377
 
374
- [exc.message, bt]
378
+ {"error" => exc.message, "backtrace" => bt}
375
379
  end
376
380
 
377
381
  ######################################################################
@@ -68,15 +68,20 @@ eos
68
68
  context.parse_define_node(n.text_value, nil)
69
69
  end
70
70
 
71
- def rewrite(context)
71
+ def def_class(context, base_name)
72
72
  # Nodes are simply translated to classes. Define our own
73
73
  # self.name() since it's extremely slow in MRI 2.0.
74
- "class #{n.text_value} < BaseClass; " +
74
+ "class #{n.text_value} < #{base_name}; " +
75
+ "def self.module_name; '#{context.module_name}'; end;" +
75
76
  "def self.name; '#{n.text_value}'; end; end"
76
77
  end
78
+
79
+ def rewrite(context)
80
+ def_class(context, "BaseClass")
81
+ end
77
82
  end
78
83
 
79
- class SubNode < SNode
84
+ class SubNode < BaseNode
80
85
  def check(context, *)
81
86
  mname = mod.m.text_value if defined?(mod.m)
82
87
  context.parse_define_node(n.text_value, p.text_value, mname)
@@ -87,8 +92,7 @@ eos
87
92
  sname = context.super_name(p.text_value, mname)
88
93
 
89
94
  # A sub-node (derived node) is just a subclass.
90
- "class #{n.text_value} < #{sname}; " +
91
- "def self.name; '#{n.text_value}'; end; end"
95
+ def_class(context, sname)
92
96
  end
93
97
  end
94
98
 
@@ -302,9 +306,9 @@ eos
302
306
  raise "No positional arguments to node call" unless
303
307
  args.empty?
304
308
 
305
- kw_str = '{' + kw.map {|k, v| "'#{k}' => #{v}" }.join(',') + '}'
309
+ kw_str = kw.map {|k, v| "'#{k}' => #{v}"}.join(',')
306
310
 
307
- "_node_call(#{node_name}, nil, _e, #{kw_str})"
311
+ "_node_call(#{node_name}, _e, {#{kw_str}})"
308
312
  end
309
313
  end
310
314
 
@@ -1,3 +1,3 @@
1
1
  module Delorean
2
- VERSION = "0.1.6"
2
+ VERSION = "0.1.7"
3
3
  end
@@ -23,7 +23,7 @@ describe "Delorean" do
23
23
  " b = -(a + 1)",
24
24
  " c = -a + 1",
25
25
  )
26
-
26
+
27
27
  engine.evaluate_attrs("A", ["a"]).should == [123]
28
28
 
29
29
  r = engine.evaluate_attrs("A", ["x", "b"])
@@ -143,28 +143,31 @@ describe "Delorean" do
143
143
  " a = 1/0",
144
144
  " b = 10 * a",
145
145
  )
146
-
146
+
147
147
  begin
148
148
  engine.evaluate("A", "b")
149
149
  rescue => exc
150
- res = engine.parse_runtime_exception(exc)
150
+ res = Delorean::Engine.grok_runtime_exception(exc)
151
151
  end
152
152
 
153
- res.should == ["divided by 0", [["XXX", 2, "/"], ["XXX", 2, "a"], ["XXX", 3, "b"]]]
153
+ res.should == {
154
+ "error" => "divided by 0",
155
+ "backtrace" => [["XXX", 2, "/"], ["XXX", 2, "a"], ["XXX", 3, "b"]],
156
+ }
154
157
  end
155
158
 
156
159
  it "should handle runtime errors 2" do
157
160
  engine.parse defn("A:",
158
161
  " b = Dummy.call_me_maybe('a', 'b')",
159
162
  )
160
-
163
+
161
164
  begin
162
165
  engine.evaluate("A", "b")
163
166
  rescue => exc
164
- res = engine.parse_runtime_exception(exc)
167
+ res = Delorean::Engine.grok_runtime_exception(exc)
165
168
  end
166
169
 
167
- res[1].should == [["XXX", 2, "b"]]
170
+ res["backtrace"].should == [["XXX", 2, "b"]]
168
171
  end
169
172
 
170
173
  it "should handle operator precedence properly" do
@@ -190,7 +193,7 @@ describe "Delorean" do
190
193
 
191
194
  engine.parse text
192
195
  r = engine.evaluate("A", "e", {"d" => -100})
193
- r.should == "gungam"+"style"
196
+ r.should == "gungamstyle"
194
197
 
195
198
  r = engine.evaluate("A", "e")
196
199
  r.should == "korea"
@@ -206,7 +209,7 @@ describe "Delorean" do
206
209
  "C:",
207
210
  " c = A.c + B.c",
208
211
  )
209
-
212
+
210
213
  r = engine.evaluate("B", "c")
211
214
  r.should == 123*123
212
215
  r = engine.evaluate("C", "c", {"c" => 5})
@@ -369,13 +372,13 @@ eoc
369
372
 
370
373
  r = engine.evaluate("B", "b", {"a" => 10})
371
374
  r.should == 10*3
372
-
375
+
373
376
  lambda {
374
377
  r = engine.evaluate("B", "b")
375
378
  }.should raise_error(Delorean::UndefinedParamError)
376
379
 
377
380
  end
378
-
381
+
379
382
  sample_script = <<eof
380
383
  A:
381
384
  a = 2
@@ -618,7 +621,7 @@ eof
618
621
  " n =?",
619
622
  " fact = if n <= 1 then 1 else n * A(n: n-1).fact",
620
623
  )
621
-
624
+
622
625
  engine.evaluate("A", "fact", "n" => 10).should == 3628800
623
626
  end
624
627
 
@@ -648,6 +648,17 @@ describe "Delorean" do
648
648
  )
649
649
  end
650
650
 
651
+ it "should not allow positional args to node calls" do
652
+ begin
653
+ engine.parse defn("A:",
654
+ " d = A(1, 2, 3)",
655
+ )
656
+ raise "fail"
657
+ rescue Delorean::ParseError => exc
658
+ exc.line.should == 2
659
+ end
660
+ end
661
+
651
662
  it "should parse instance calls" do
652
663
  engine.parse defn("A:",
653
664
  " a = [1,2,[4]].flatten(1)",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delorean_lang
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arman Bostani
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-20 00:00:00.000000000 Z
11
+ date: 2014-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: treetop
@@ -42,28 +42,28 @@ dependencies:
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ! '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: sqlite3
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ! '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ! '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  description: A "compiler" for the Delorean programming language
@@ -105,12 +105,12 @@ require_paths:
105
105
  - lib
106
106
  required_ruby_version: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ! '>='
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  required_rubygems_version: !ruby/object:Gem::Requirement
112
112
  requirements:
113
- - - '>='
113
+ - - ! '>='
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  requirements: []
@@ -125,3 +125,4 @@ test_files:
125
125
  - spec/func_spec.rb
126
126
  - spec/parse_spec.rb
127
127
  - spec/spec_helper.rb
128
+ has_rdoc: