delorean_lang 0.1.6 → 0.1.7

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,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: