eleetscript 0.0.8a → 0.0.9a

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.
@@ -28,4 +28,47 @@ module EleetScript
28
28
  @hash_value.clear
29
29
  end
30
30
  end
31
+
32
+ class ESRegex < Regexp
33
+ attr_writer :global
34
+
35
+ class << self
36
+ def from_regex(regex)
37
+ ESRegex.new(regex.source, regex.flags)
38
+ end
39
+ end
40
+
41
+ def initialize(pattern, flags = nil)
42
+ flag_num = 0
43
+ if flags.is_a?(String)
44
+ flags = flags ? flags.chars : []
45
+ @global = true if flags.include?("g")
46
+ flag_num |= Regexp::IGNORECASE if flags.include?("i")
47
+ flag_num |= Regexp::MULTILINE if flags.include?("m")
48
+ else
49
+ flag_num = flags
50
+ end
51
+ super(pattern, flag_num)
52
+ end
53
+
54
+ def global?
55
+ @global || false
56
+ end
57
+
58
+ def ignorecase?
59
+ options & Regexp::IGNORECASE == Regexp::IGNORECASE
60
+ end
61
+
62
+ def multiline?
63
+ options & Regexp::MULTILINE == Regexp::MULTILINE
64
+ end
65
+
66
+ def flags
67
+ flags = ""
68
+ flags += "m" if options & Regexp::MULTILINE == Regexp::MULTILINE
69
+ flags += "i" if options & Regexp::IGNORECASE == Regexp::IGNORECASE
70
+ flags += "g" if global?
71
+ flags
72
+ end
73
+ end
31
74
  end
@@ -37,6 +37,10 @@ class Object
37
37
  to_string
38
38
  end
39
39
 
40
+ =~ do
41
+ false
42
+ end
43
+
40
44
  no_method do |name|
41
45
  cls_name = class_name
42
46
  Errors < "Undefined method \"%name\" called on instance of %cls_name."
@@ -0,0 +1,11 @@
1
+ class Regex
2
+ to_string do
3
+ pat = pattern
4
+ flgs = flags
5
+ "r\"%pat\"%flgs"
6
+ end
7
+
8
+ =~ do |str|
9
+ str =~ self
10
+ end
11
+ end
@@ -28,6 +28,28 @@ class String
28
28
  self
29
29
  end
30
30
 
31
+ replace_all do |pattern, replacement|
32
+ if pattern.kind_of?(Regex)
33
+ pattern.global = yes
34
+ replace(pattern, replacement)
35
+ else
36
+ pattern = r"%pattern"g
37
+ replace(pattern, replacement)
38
+ end
39
+ end
40
+
41
+ =~ do |rx|
42
+ if rx.kind_of?(Regex)
43
+ match?(rx)
44
+ else
45
+ false
46
+ end
47
+ end
48
+
49
+ match? do |rx|
50
+ match(rx).length > 0
51
+ end
52
+
31
53
  inspect do
32
54
  "\"" + self + "\""
33
55
  end
@@ -16,6 +16,7 @@ module EleetScript
16
16
  "Enumerable" => nil,
17
17
  "List" => "Enumerable",
18
18
  "String" => "Enumerable",
19
+ "Regex" => nil,
19
20
  "IO" => nil,
20
21
  "Lambda" => nil,
21
22
  "TrueClass" => nil,
@@ -54,6 +55,7 @@ module EleetScript
54
55
  load_object_methods
55
56
  load_io_methods
56
57
  load_string_methods
58
+ load_regex_methods
57
59
  load_number_methods
58
60
  load_boolean_methods
59
61
  load_nil_methods
@@ -78,8 +80,7 @@ module EleetScript
78
80
  end
79
81
 
80
82
  object.def :kind_of? do |receiver, arguments|
81
- t = @root_namespace["true"]
82
- f = @root_namespace["false"]
83
+ t, f = @root_namespace["true"], @root_namespace["false"]
83
84
  if arguments.length == 0 || !arguments.first.class?
84
85
  f
85
86
  else
@@ -96,6 +97,10 @@ module EleetScript
96
97
  end
97
98
  end
98
99
 
100
+ object.def :class do |receiver, arguments|
101
+ receiver.runtime_class
102
+ end
103
+
99
104
  object.def :class_name do |receiver, arguments|
100
105
  @root_namespace["String"].new_with_value(receiver.runtime_class.name)
101
106
  end
@@ -225,6 +230,76 @@ module EleetScript
225
230
  @root_namespace.es_nil
226
231
  end
227
232
  end
233
+
234
+ string.def :replace do |receiver, arguments|
235
+ if arguments.length < 2
236
+ string.new_with_value(receiver.ruby_value)
237
+ else
238
+ pattern, replacement = arguments
239
+ if !pattern.is_a?("Regex")
240
+ pattern = @root_namespace["Regex"].call(:new, [pattern.call(:to_string)])
241
+ end
242
+ if replacement.is_a?("Lambda")
243
+ new_str = if pattern.ruby_value.global?
244
+ receiver.ruby_value.gsub(pattern.ruby_value) do |*args|
245
+ args = args.map { |arg| string.new_with_value(arg) }
246
+ replacement.call(:call, args).call(:to_string).ruby_value
247
+ end
248
+ else
249
+ receiver.ruby_value.sub(pattern.ruby_value) do |*args|
250
+ args = args.map { |arg| string.new_with_value(arg) }
251
+ replacement.call(:call, args).call(:to_string).ruby_value
252
+ end
253
+ end
254
+ else
255
+ new_str = if pattern.ruby_value.global?
256
+ receiver.ruby_value.gsub(pattern.ruby_value, replacement.call(:to_string).ruby_value)
257
+ else
258
+ receiver.ruby_value.sub(pattern.ruby_value, replacement.call(:to_string).ruby_value)
259
+ end
260
+ string.new_with_value(new_str)
261
+ end
262
+ end
263
+ end
264
+
265
+ string.def :match do |receiver, arguments|
266
+ str_cls, list_cls = @root_namespace["String"], @root_namespace["List"]
267
+ rx = arguments.first
268
+ if rx.is_a?("Regex")
269
+ if rx.ruby_value.global?
270
+ matches = receiver.ruby_value.scan(rx.ruby_value)
271
+ list_args = matches.map do |match|
272
+ args = match.map do |a|
273
+ str_cls.new_with_value(a)
274
+ end
275
+ list_cls.call(:new, args)
276
+ end
277
+ list_cls.call(:new, args)
278
+ else
279
+ matches = receiver.ruby_value.match(rx.ruby_value)
280
+ if matches.nil?
281
+ list_cls.call(:new)
282
+ else
283
+ args = [str_cls.new_with_value(matches[0])]
284
+ if matches.names.length > 0
285
+ args += matches.names.map do |name|
286
+ n, v = str_cls.new_with_value(name), str_cls.new_with_value(matches[name])
287
+ @root_namespace["Pair"].call(:new, [n, v])
288
+ end
289
+ else
290
+ group_matches = matches.to_a
291
+ group_matches.shift # Remove full match
292
+ args += group_matches.map do |res|
293
+ str_cls.new_with_value(res)
294
+ end
295
+ end
296
+ list_cls.call(:new, args)
297
+ end
298
+ end
299
+ else
300
+ @root_namespace["List"].call(:new)
301
+ end
302
+ end
228
303
  end
229
304
 
230
305
  def load_number_methods
@@ -372,6 +447,63 @@ module EleetScript
372
447
  end
373
448
  end
374
449
 
450
+ def load_regex_methods
451
+ regex = @root_namespace["Regex"]
452
+
453
+ regex.class_def :new do |receiver, arguments|
454
+ pattern, flags = arguments
455
+ pattern = (pattern ? pattern.ruby_value : "")
456
+ flags = (flags ? flags.ruby_value : nil)
457
+ regex.new_with_value(ESRegex.new(pattern, flags))
458
+ end
459
+
460
+ regex.def :pattern do |receiver, arguments|
461
+ @root_namespace["String"].new_with_value(receiver.ruby_value.source)
462
+ end
463
+
464
+ regex.def :flags do |receiver, arguments|
465
+ @root_namespace["String"].new_with_value(receiver.ruby_value.flags)
466
+ end
467
+
468
+ regex.def :global= do |receiver, arguments|
469
+ t, f = @root_namespace["true"], @root_namespace["false"]
470
+ receiver.ruby_value.global = arguments.first == t ? true : false
471
+ receiver
472
+ end
473
+
474
+ regex.def :multiline? do |receiver, arguments|
475
+ t, f = @root_namespace["true"], @root_namespace["false"]
476
+ receiver.ruby_value.multiline? ? t : f
477
+ end
478
+
479
+ regex.def :multiline= do |receiver, arguments|
480
+ t, f = @root_namespace["true"], @root_namespace["false"]
481
+ rx = receiver.ruby_value
482
+ if arguments.first == t
483
+ receiver.ruby_value = ESRegex.new(rx.source, rx.flags + "m")
484
+ else
485
+ receiver.ruby_value = ESRegex.new(rx.source, rx.flags.gsub("m", ""))
486
+ end
487
+ receiver
488
+ end
489
+
490
+ regex.def :ignorecase? do |receiver, arguments|
491
+ t, f = @root_namespace["true"], @root_namespace["false"]
492
+ receiver.ruby_value.ignorecase? ? t : f
493
+ end
494
+
495
+ regex.def :ignorecase= do |receiver, arguments|
496
+ t, f = @root_namespace["true"], @root_namespace["false"]
497
+ rx = receiver.ruby_value
498
+ if arguments.first == t
499
+ receiver.ruby_value = ESRegex.new(rx.source, rx.flags + "i")
500
+ else
501
+ receiver.ruby_value = ESRegex.new(rx.source, rx.flags.gsub("i", ""))
502
+ end
503
+ receiver
504
+ end
505
+ end
506
+
375
507
  def load_boolean_methods
376
508
  true_cls = @root_namespace["TrueClass"]
377
509
  false_cls = @root_namespace["FalseClass"]
@@ -545,9 +677,23 @@ module EleetScript
545
677
 
546
678
  def load_lambda_methods
547
679
  lambda = @root_namespace["Lambda"]
680
+
548
681
  lambda.def :call do |receiver, arguments, context|
549
682
  receiver.ruby_value.call(nil, arguments, context)
550
683
  end
684
+
685
+ lambda.def :apply do |receiver, arguments, context|
686
+ args = arguments.first
687
+ args = if args.is_a?("List")
688
+ arg_list = args.ruby_value.array_value.dup
689
+ arg_list + args.ruby_value.hash_value.map do |k, v|
690
+ @root_namespace["Pair"].call(:new, [k, v])
691
+ end
692
+ else
693
+ []
694
+ end
695
+ receiver.ruby_value.call(nil, args, context)
696
+ end
551
697
  end
552
698
  end
553
699
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eleetscript
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8a
4
+ version: 0.0.9a
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Buck
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-31 00:00:00.000000000 Z
11
+ date: 2014-02-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: EleetScript scripting engine for use in Ruby applications
14
14
  email: lordizuriel@gmail.com
@@ -46,6 +46,7 @@ files:
46
46
  - lib/lang/runtime/eleetscript/object.es
47
47
  - lib/lang/runtime/eleetscript/pair.es
48
48
  - lib/lang/runtime/eleetscript/que.es
49
+ - lib/lang/runtime/eleetscript/regex.es
49
50
  - lib/lang/runtime/eleetscript/stack.es
50
51
  - lib/lang/runtime/eleetscript/string.es
51
52
  - lib/lang/runtime/eleetscript/trueclass.es