code-ruby 0.10.4 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/bin/code +6 -0
  4. data/bin/console +5 -0
  5. data/lib/code/node/base_10.rb +10 -10
  6. data/lib/code/node/base_16.rb +3 -2
  7. data/lib/code/node/base_2.rb +3 -2
  8. data/lib/code/node/base_8.rb +3 -2
  9. data/lib/code/node/boolean.rb +5 -4
  10. data/lib/code/node/call.rb +13 -19
  11. data/lib/code/node/call_argument.rb +8 -4
  12. data/lib/code/node/code.rb +4 -2
  13. data/lib/code/node/decimal.rb +8 -10
  14. data/lib/code/node/dictionary.rb +15 -8
  15. data/lib/code/node/function.rb +5 -9
  16. data/lib/code/node/function_parameter.rb +8 -4
  17. data/lib/code/node/if.rb +14 -12
  18. data/lib/code/node/left_operation.rb +10 -10
  19. data/lib/code/node/list.rb +4 -3
  20. data/lib/code/node/negation.rb +8 -4
  21. data/lib/code/node/not.rb +8 -4
  22. data/lib/code/node/nothing.rb +4 -3
  23. data/lib/code/node/number.rb +3 -3
  24. data/lib/code/node/right_operation.rb +19 -16
  25. data/lib/code/node/splat.rb +8 -4
  26. data/lib/code/node/square_bracket.rb +8 -11
  27. data/lib/code/node/statement.rb +27 -27
  28. data/lib/code/node/string.rb +14 -11
  29. data/lib/code/node/ternary.rb +8 -8
  30. data/lib/code/node/unary_minus.rb +8 -4
  31. data/lib/code/node/while.rb +15 -13
  32. data/lib/code/node.rb +1 -7
  33. data/lib/code/object/argument.rb +4 -3
  34. data/lib/code/object/boolean.rb +5 -4
  35. data/lib/code/object/class.rb +4 -3
  36. data/lib/code/object/code.rb +33 -0
  37. data/lib/code/object/context.rb +7 -5
  38. data/lib/code/object/date.rb +31 -6
  39. data/lib/code/object/decimal.rb +36 -31
  40. data/lib/code/object/dictionary.rb +4 -4
  41. data/lib/code/object/duration.rb +8 -5
  42. data/lib/code/object/function.rb +42 -28
  43. data/lib/code/object/global.rb +58 -38
  44. data/lib/code/object/integer.rb +23 -26
  45. data/lib/code/object/list.rb +5 -5
  46. data/lib/code/object/nothing.rb +2 -4
  47. data/lib/code/object/parameter.rb +43 -0
  48. data/lib/code/object/range.rb +13 -11
  49. data/lib/code/object/string.rb +7 -7
  50. data/lib/code/object/time.rb +15 -8
  51. data/lib/code/object.rb +104 -11
  52. data/lib/code/parser/code.rb +1 -1
  53. data/lib/code/parser/left_operation.rb +2 -2
  54. data/lib/code/parser/list.rb +2 -2
  55. data/lib/code/parser/right_operation.rb +2 -2
  56. data/lib/code/parser/whitespace.rb +2 -2
  57. data/lib/code/parser.rb +1 -1
  58. data/lib/code/type/sig.rb +2 -2
  59. data/lib/code/type.rb +12 -4
  60. data/lib/code/version.rb +1 -1
  61. data/lib/code-ruby.rb +7 -0
  62. data/lib/code.rb +8 -5
  63. data/spec/code/object/dictionary_spec.rb +0 -2
  64. data/spec/code_spec.rb +122 -16
  65. metadata +5 -3
  66. data/lib/code/object/number.rb +0 -11
@@ -2,19 +2,16 @@
2
2
 
3
3
  class Code
4
4
  class Object
5
- class Decimal < ::Code::Object::Number
6
- attr_reader :raw
7
-
8
- def initialize(decimal, exponent: nil)
9
- decimal = decimal.raw if decimal.is_a?(Decimal)
10
- @raw = BigDecimal(decimal)
11
-
12
- return unless exponent
13
- unless exponent.is_a?(Number)
14
- raise ::Code::Error::TypeError, "exponent is not a number"
15
- end
16
-
17
- @raw *= 10**exponent.raw
5
+ class Decimal < Object
6
+ def initialize(*args, **_kargs, &_block)
7
+ decimal = args.first || "0"
8
+ exponent = args.second || "0"
9
+ decimal = decimal.raw if decimal.is_an?(Object)
10
+ exponent = exponent.raw if exponent.is_an?(Object)
11
+ @raw = decimal.to_d * 10**exponent.to_d
12
+ super
13
+ rescue FloatDomainError => e
14
+ raise Error, "#{decimal.inspect} * 10**#{exponent.inspect} is invalid"
18
15
  end
19
16
 
20
17
  def self.name
@@ -28,49 +25,49 @@ class Code
28
25
 
29
26
  case operator.to_s
30
27
  when "%", "modulo"
31
- sig(args) { Number }
28
+ sig(args) { Integer | Decimal }
32
29
  code_modulo(value)
33
30
  when "&", "bitwise_and"
34
- sig(args) { Number }
31
+ sig(args) { Integer | Decimal }
35
32
  code_bitwise_and(value)
36
33
  when "*", "multiplication"
37
- sig(args) { Number }
34
+ sig(args) { Integer | Decimal }
38
35
  code_multiplication(value)
39
36
  when "**", "power"
40
- sig(args) { Number }
37
+ sig(args) { Integer | Decimal }
41
38
  code_power(value)
42
39
  when "+", "plus"
43
40
  sig(args) { Object.maybe }
44
41
  value ? code_plus(value) : self
45
42
  when "-", "minus"
46
- sig(args) { Number.maybe }
43
+ sig(args) { (Integer | Decimal).maybe }
47
44
  value ? code_minus(value) : code_unary_minus
48
45
  when "/", "division"
49
- sig(args) { Number }
46
+ sig(args) { Integer | Decimal }
50
47
  code_division(value)
51
48
  when "<", "inferior"
52
- sig(args) { Number }
49
+ sig(args) { Integer | Decimal }
53
50
  code_inferior(value)
54
51
  when "<<", "left_shift"
55
- sig(args) { Number }
52
+ sig(args) { Integer | Decimal }
56
53
  code_left_shift(value)
57
54
  when "<=", "inferior_or_equal"
58
- sig(args) { Number }
55
+ sig(args) { Integer | Decimal }
59
56
  code_inferior_or_equal(value)
60
57
  when "<=>", "compare"
61
- sig(args) { Number }
58
+ sig(args) { Integer | Decimal }
62
59
  code_compare(value)
63
60
  when ">", "superior"
64
- sig(args) { Number }
61
+ sig(args) { Integer | Decimal }
65
62
  code_superior(value)
66
63
  when ">=", "superior_or_equal"
67
- sig(args) { Number }
64
+ sig(args) { Integer | Decimal }
68
65
  code_superior_or_equal(value)
69
66
  when ">>", "right_shift"
70
- sig(args) { Number }
67
+ sig(args) { Integer | Decimal }
71
68
  code_right_shift(value)
72
69
  when "^", "bitwise_xor"
73
- sig(args) { Number }
70
+ sig(args) { Integer | Decimal }
74
71
  code_bitwise_xor(value)
75
72
  when "abs"
76
73
  sig(args)
@@ -136,7 +133,7 @@ class Code
136
133
  sig(args)
137
134
  code_zero?
138
135
  when "|", "bitwise_or"
139
- sig(args) { Number }
136
+ sig(args) { Integer | Decimal }
140
137
  code_bitwise_or(value)
141
138
  else
142
139
  super
@@ -226,7 +223,7 @@ class Code
226
223
  end
227
224
 
228
225
  def code_plus(other)
229
- if other.is_a?(Number)
226
+ if other.is_an?(Integer) || other.is_a?(Decimal)
230
227
  Decimal.new(raw + other.raw)
231
228
  else
232
229
  String.new(to_s + other.to_s)
@@ -307,12 +304,20 @@ class Code
307
304
  to_s
308
305
  end
309
306
 
307
+ def whole?
308
+ whole == raw
309
+ end
310
+
311
+ def whole
312
+ raw.round
313
+ end
314
+
310
315
  def to_s
311
- raw.to_s("F")
316
+ whole? ? raw.to_i.to_s : raw.to_s("F")
312
317
  end
313
318
 
314
319
  def as_json(...)
315
- raw.as_json(...)
320
+ whole? ? whole.as_json(...) : raw.as_json(...)
316
321
  end
317
322
  end
318
323
  end
@@ -3,11 +3,11 @@
3
3
  class Code
4
4
  class Object
5
5
  class Dictionary < ::Code::Object
6
- attr_reader :raw
7
-
8
- def initialize(raw = {})
9
- raw = raw.raw if raw.is_a?(Dictionary)
6
+ def initialize(*args, **_kargs, &_block)
7
+ raw = args.first || {}
8
+ raw = raw.raw if raw.is_a?(Object)
10
9
  @raw = raw.to_h
10
+ super
11
11
  end
12
12
 
13
13
  def self.name
@@ -3,11 +3,14 @@
3
3
  class Code
4
4
  class Object
5
5
  class Duration < Object
6
- attr_reader :raw
7
-
8
- def initialize(duration)
9
- duration = duration.raw if duration.is_a?(Duration)
10
- @raw = duration
6
+ def initialize(*args, **_kargs, &_block)
7
+ raw = args.first || 0.seconds
8
+ raw = raw.raw if raw.is_an?(Object)
9
+ raw = raw.iso8601 if raw.is_an?(::ActiveSupport::Duration)
10
+ @raw = ::ActiveSupport::Duration.parse(raw.to_s)
11
+ super
12
+ rescue ::ActiveSupport::Duration::ISO8601Parser::ParsingError
13
+ raise Error, "#{raw.inspect} is not a valid duration"
11
14
  end
12
15
 
13
16
  def self.name
@@ -2,12 +2,30 @@
2
2
 
3
3
  class Code
4
4
  class Object
5
- class Function < ::Code::Object
5
+ class Function < Object
6
6
  attr_reader :parameters, :body
7
7
 
8
- def initialize(parameters:, body:)
9
- @parameters = parameters
10
- @body = body
8
+ def initialize(*args, **_kargs, &_block)
9
+ parameters = args.first.presence || List.new
10
+ parameters = parameters.raw if parameters.is_an?(Object)
11
+ @parameters = List.new(parameters)
12
+ @parameters.raw.map! do |parameter|
13
+ if parameter.is_a?(Node::FunctionParameter)
14
+ Parameter.new(
15
+ Dictionary.new({
16
+ String.new(:name) => String.new(parameter.name),
17
+ String.new(:keyword) => Boolean.new(parameter.keyword?),
18
+ String.new(:regular_splat) => Boolean.new(parameter.regular_splat?),
19
+ String.new(:keyword_splat) => Boolean.new(parameter.keyword_splat?),
20
+ String.new(:default) => Code.new(parameter.default),
21
+ })
22
+ )
23
+ else
24
+ Parameter.new(parameter)
25
+ end
26
+ end
27
+ @body = Code.new(args.second.presence || Nothing.new)
28
+ super
11
29
  end
12
30
 
13
31
  def self.name
@@ -17,7 +35,7 @@ class Code
17
35
  def call(**args)
18
36
  operator = args.fetch(:operator, nil)
19
37
  arguments = args.fetch(:arguments, [])
20
- globals = multi_fetch(args, *::Code::GLOBALS)
38
+ globals = multi_fetch(args, *GLOBALS)
21
39
 
22
40
  case operator.to_s
23
41
  when "", "call"
@@ -29,27 +47,21 @@ class Code
29
47
  end
30
48
 
31
49
  def code_call(*arguments, **globals)
32
- context = Context.new({}, parent: globals[:context])
50
+ context = Context.new({}, globals[:context])
33
51
 
34
- parameters.each.with_index do |parameter, index|
35
- if parameter.regular?
36
- if parameter.regular_splat?
37
- context.code_set(
38
- parameter.name,
39
- List.new(arguments.select(&:regular?).map(&:value))
52
+ parameters.raw.each.with_index do |parameter, index|
53
+ if parameter.regular_splat?
54
+ context.code_set(
55
+ parameter.name,
56
+ List.new(arguments.select(&:regular?).map(&:value))
57
+ )
58
+ elsif parameter.keyword_splat?
59
+ context.code_set(
60
+ parameter.name,
61
+ Dictionary.new(
62
+ arguments.select(&:keyword?).map(&:name_value).to_h
40
63
  )
41
- elsif parameter.keyword_splat?
42
- context.code_set(
43
- parameter.name,
44
- Dictionary.new(
45
- arguments.select(&:keyword?).map(&:name_value).to_h
46
- )
47
- )
48
- else
49
- argument = arguments[index]&.value
50
- argument = parameter.evaluate(**globals) if argument.nil?
51
- context.code_set(parameter.name, argument)
52
- end
64
+ )
53
65
  elsif parameter.keyword?
54
66
  argument =
55
67
  arguments
@@ -57,8 +69,10 @@ class Code
57
69
  &.value
58
70
  argument = parameter.evaluate(**globals) if argument.nil?
59
71
  context.code_set(parameter.name, argument)
60
- else
61
- raise NotImplementedError
72
+ elsif parameter.regular?
73
+ argument = arguments[index]&.value
74
+ argument = parameter.evaluate(**globals) if argument.nil?
75
+ context.code_set(parameter.name, argument)
62
76
  end
63
77
  end
64
78
 
@@ -70,10 +84,10 @@ class Code
70
84
  end
71
85
 
72
86
  def signature_for_call
73
- parameters.inject([]) do |signature, parameter|
87
+ parameters.raw.inject([]) do |signature, parameter|
74
88
  if parameter.keyword?
75
89
  if signature.last.is_a?(::Hash)
76
- signature.last[parameter.name] = Object
90
+ signature.last.code_set(parameter.name, Object)
77
91
  signature
78
92
  else
79
93
  signature + [{ parameter.name => Object }]
@@ -2,11 +2,15 @@
2
2
 
3
3
  class Code
4
4
  class Object
5
- class Global < ::Code::Object
5
+ class Global < Object
6
6
  def self.name
7
7
  "Global"
8
8
  end
9
9
 
10
+ def initialize(...)
11
+ super
12
+ end
13
+
10
14
  def call(**args)
11
15
  operator = args.fetch(:operator, nil)
12
16
  arguments = args.fetch(:arguments, [])
@@ -14,62 +18,78 @@ class Code
14
18
  context = args.fetch(:context)
15
19
  globals = multi_fetch(args, *GLOBALS)
16
20
  value = arguments.first&.value
21
+ values = arguments.map(&:value)
17
22
 
18
23
  case operator.to_s
19
24
  when "Boolean"
20
- sig(args) { Object.maybe }
21
- value ? value.code_to_boolean : Class.new(Boolean)
25
+ sig(args) { Object.repeat }
26
+ value ? Boolean.new(*values) : Class.new(Boolean)
22
27
  when "break"
23
- sig(args) { Object.maybe }
28
+ sig(args) { Object.repeat }
24
29
  raise Error::Break, value || Nothing.new
25
30
  when "next"
26
- sig(args) { Object.maybe }
31
+ sig(args) { Object.repeat }
27
32
  raise Error::Next, value || Nothing.new
28
33
  when "Class"
29
- sig(args) { Object.maybe }
30
- value ? value.code_to_class : Class.new(Class)
34
+ sig(args) { Object.repeat }
35
+ value ? Class.new(*values) : Class.new(Class)
31
36
  when "Date"
32
- sig(args) { Object.maybe }
33
- value ? value.code_to_date : Class.new(Date)
37
+ sig(args) { Object.repeat }
38
+ value ? Date.new(*values) : Class.new(Date)
34
39
  when "Decimal"
35
- sig(args) { Object.maybe }
36
- value ? value.code_to_decimal : Class.new(Decimal)
40
+ sig(args) { Object.repeat }
41
+ value ? Decimal.new(*values) : Class.new(Decimal)
37
42
  when "Dictionary"
38
- sig(args) { Object.maybe }
39
- value ? value.code_to_dictionnary : Class.new(Dictionary)
40
- when "fetch"
41
- sig(args) { [Object, Function.maybe] }
42
- context.code_fetch(*arguments.map(&:value), **globals)
43
+ sig(args) { Object.repeat }
44
+ value ? Dictionary.new(*values) : Class.new(Dictionary)
45
+ when "Duration"
46
+ sig(args) { Object.repeat }
47
+ value ? Duration.new(*values) : Class.new(Duration)
43
48
  when "Function"
44
- sig(args) { Object.maybe }
45
- value ? value.code_to_function : Class.new(Function)
49
+ sig(args)
50
+ Class.new(Function)
46
51
  when "Integer"
47
- sig(args) { Object.maybe }
48
- value ? value.code_to_integer : Class.new(Integer)
52
+ sig(args) { Object.repeat }
53
+ value ? Integer.new(*values) : Class.new(Integer)
49
54
  when "List"
50
- sig(args) { Object.maybe }
51
- value ? value.code_to_list : Class.new(List)
55
+ sig(args) { Object.repeat }
56
+ value ? List.new(*values) : Class.new(List)
52
57
  when "Nothing"
53
- sig(args) { Object.maybe }
54
- value ? value.code_to_nothing : Class.new(Nothing)
55
- when "Number"
56
- sig(args) { Object.maybe }
57
- value ? value.code_to_number : Class.new(Number)
58
+ sig(args) { Object.repeat }
59
+ value ? Nothing.new(*values) : Class.new(Nothing)
60
+ when "context"
61
+ sig(args)
62
+ context
58
63
  when "Object"
59
- sig(args) { Object.maybe }
60
- value ? value.code_to_object : Class.new(Object)
64
+ sig(args)
65
+ Class.new(Object)
61
66
  when "Range"
62
- sig(args) { Object.maybe }
63
- value ? value.code_to_range : Class.new(Range)
67
+ sig(args) { Object.repeat }
68
+ value ? Range.new(*values) : Class.new(Range)
64
69
  when "String"
65
- sig(args) { Object.maybe }
66
- value ? value.code_to_string : Class.new(String)
70
+ sig(args) { Object.repeat }
71
+ value ? String.new(*values) : Class.new(String)
67
72
  when "Time"
68
- sig(args) { Object.maybe }
69
- value ? value.code_to_time : Class.new(Time)
70
- when "context"
71
- sig(args) { String.maybe }
72
- value ? context.code_get(value) || Nothing.new : context
73
+ sig(args) { Object.repeat }
74
+ value ? Time.new(*values) : Class.new(Time)
75
+ when "Context"
76
+ sig(args) { Object.repeat }
77
+ value ? Context.new(*values) : Class.new(Context)
78
+ when "Code"
79
+ sig(args) { Object.repeat }
80
+ value ? Code.new(*values) : Class.new(Code)
81
+ when "Argument"
82
+ sig(args) { Object.repeat }
83
+ value ? Argument.new(*values) : Class.new(Argument)
84
+ when "Parameter"
85
+ sig(args) { Object.repeat }
86
+ value ? Parameter.new(*values) : Class.new(Parameter)
87
+ when "Range"
88
+ sig(args) { Object.repeat }
89
+ value ? Range.new(*values) : Class.new(Range)
90
+ when "IdentifierList"
91
+ sig(args) { Object.repeat }
92
+ value ? IdentifierList.new(*values) : Class.new(IdentifierList)
73
93
  when "evaluate"
74
94
  sig(args) { Object }
75
95
  Code.evaluate(value.to_s)
@@ -2,18 +2,15 @@
2
2
 
3
3
  class Code
4
4
  class Object
5
- class Integer < Number
6
- attr_reader :raw
7
-
8
- def initialize(whole, exponent: nil)
9
- whole = whole.raw if whole.is_a?(Integer)
10
- @raw = whole.to_i
11
- return unless exponent
12
-
13
- exponent = exponent.raw if exponent.is_a?(Number)
14
- @raw *= 10**exponent
5
+ class Integer < Object
6
+ def initialize(*args, **_kargs, &_block)
7
+ whole = args.first || 0
8
+ exponent = args.second || 0
9
+ whole = whole.raw if whole.is_an?(Object)
10
+ exponent = exponent.raw if exponent.is_an?(Object)
11
+ @raw = whole.to_i * 10**exponent
15
12
  rescue FloatDomainError => e
16
- raise Error, e.message
13
+ raise Error, "#{decimal.inspect} * 10**#{exponent.inspect} is invalid"
17
14
  end
18
15
 
19
16
  def self.name
@@ -28,49 +25,49 @@ class Code
28
25
 
29
26
  case operator.to_s
30
27
  when "%", "modulo"
31
- sig(args) { Number }
28
+ sig(args) { Integer | Decimal }
32
29
  code_modulo(value)
33
30
  when "&", "bitwise_and"
34
- sig(args) { Number }
31
+ sig(args) { Integer | Decimal }
35
32
  code_bitwise_and(value)
36
33
  when "*", "multiplication", "×"
37
- sig(args) { Number | String }
34
+ sig(args) { Integer | Decimal | String }
38
35
  code_multiplication(value)
39
36
  when "**", "power"
40
- sig(args) { Number }
37
+ sig(args) { Integer | Decimal }
41
38
  code_power(value)
42
39
  when "+", "plus", "self"
43
40
  sig(args) { Object.maybe }
44
41
  value ? code_plus(value) : code_self
45
42
  when "-", "minus", "unary_minus"
46
- sig(args) { Number.maybe }
43
+ sig(args) { Integer | Decimal.maybe }
47
44
  value ? code_minus(value) : code_unary_minus
48
45
  when "/", "division", "÷"
49
- sig(args) { Number }
46
+ sig(args) { Integer | Decimal }
50
47
  code_division(value)
51
48
  when "<", "inferior"
52
- sig(args) { Number }
49
+ sig(args) { Integer | Decimal }
53
50
  code_inferior(value)
54
51
  when "<<", "left_shift"
55
- sig(args) { Number }
52
+ sig(args) { Integer | Decimal }
56
53
  code_left_shift(value)
57
54
  when "<=", "inferior_or_equal"
58
- sig(args) { Number }
55
+ sig(args) { Integer | Decimal }
59
56
  code_inferior_or_equal(value)
60
57
  when "<=>", "compare"
61
- sig(args) { Number }
58
+ sig(args) { Integer | Decimal }
62
59
  code_compare(value)
63
60
  when ">", "superior"
64
- sig(args) { Number }
61
+ sig(args) { Integer | Decimal }
65
62
  code_superior(value)
66
63
  when ">=", "superior_or_equal"
67
- sig(args) { Number }
64
+ sig(args) { Integer | Decimal }
68
65
  code_superior_or_equal(value)
69
66
  when ">>", "right_shift"
70
- sig(args) { Number }
67
+ sig(args) { Integer | Decimal }
71
68
  code_right_shift(value)
72
69
  when "^", "bitwise_xor"
73
- sig(args) { Number }
70
+ sig(args) { Integer | Decimal }
74
71
  code_bitwise_xor(value)
75
72
  when "abs"
76
73
  sig(args)
@@ -163,7 +160,7 @@ class Code
163
160
  sig(args)
164
161
  code_zero?
165
162
  when "|", "bitwise_or"
166
- sig(args) { Number }
163
+ sig(args) { Integer | Decimal }
167
164
  code_bitwise_or(value)
168
165
  else
169
166
  super
@@ -2,12 +2,12 @@
2
2
 
3
3
  class Code
4
4
  class Object
5
- class List < ::Code::Object
6
- attr_reader :raw
7
-
8
- def initialize(raw = [])
9
- raw = raw.raw if raw.is_a?(List)
5
+ class List < Object
6
+ def initialize(*args, **_kargs, &_block)
7
+ raw = args.first || Nothing.new
8
+ raw = raw.raw if raw.is_an?(Object)
10
9
  @raw = raw.to_a
10
+ super
11
11
  end
12
12
 
13
13
  def self.name
@@ -2,10 +2,8 @@
2
2
 
3
3
  class Code
4
4
  class Object
5
- class Nothing < ::Code::Object
6
- attr_reader :raw
7
-
8
- def initialize
5
+ class Nothing < Object
6
+ def initialize(*_args, **_kargs, &_block)
9
7
  @raw = nil
10
8
  end
11
9
 
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Code
4
+ class Object
5
+ class Parameter < Object
6
+ attr_reader :name, :keyword, :regular_splat, :keyword_splat, :default
7
+
8
+ def self.name
9
+ "Parameter"
10
+ end
11
+
12
+ def initialize(*args, **_kargs, &_block)
13
+ @raw = Dictionary.new(args.first.presence || {})
14
+ @name = String.new(@raw.code_get(String.new(:name)))
15
+ @keyword = Boolean.new(@raw.code_get(String.new(:keyword)))
16
+ @regular_splat = Boolean.new(@raw.code_get(String.new(:regular_splat)))
17
+ @keyword_splat = Boolean.new(@raw.code_get(String.new(:keyword_splat)))
18
+ @default = Code.new(@raw.code_get(String.new(:default)))
19
+ super
20
+ end
21
+
22
+ def evaluate(...)
23
+ default.evaluate(...)
24
+ end
25
+
26
+ def regular?
27
+ !keyword?
28
+ end
29
+
30
+ def keyword?
31
+ keyword.truthy?
32
+ end
33
+
34
+ def regular_splat?
35
+ regular_splat.truthy?
36
+ end
37
+
38
+ def keyword_splat?
39
+ keyword_splat.truthy?
40
+ end
41
+ end
42
+ end
43
+ end
@@ -3,13 +3,15 @@
3
3
  class Code
4
4
  class Object
5
5
  class Range < Object
6
- attr_reader :raw, :exclude_end, :left, :right
6
+ attr_reader :left, :right, :options, :exclude_end
7
7
 
8
- def initialize(left, right, exclude_end: false)
9
- @left = left
10
- @right = right
11
- @exclude_end = !exclude_end.nil?
12
- @raw = ::Range.new(left, right, exclude_end)
8
+ def initialize(*args, **_kargs, &_block)
9
+ @left = args.first.presence || Integer.new(0)
10
+ @right = args.second.presence || Integer.new(0)
11
+ @options = Dictionary.new(args.third.presence || Dictionary.new)
12
+ @exclude_end = Boolean.new(@options.code_get(String.new(:exclude_end)))
13
+ @raw = ::Range.new(left, right, exclude_end?)
14
+ super
13
15
  end
14
16
 
15
17
  def self.name
@@ -45,7 +47,7 @@ class Code
45
47
  sig(args) { Function }
46
48
  code_select(value, **globals)
47
49
  when "step"
48
- sig(args) { Number }
50
+ sig(args) { Integer | Decimal }
49
51
  code_step(value)
50
52
  when "to_list"
51
53
  sig(args)
@@ -102,6 +104,10 @@ class Code
102
104
  )
103
105
  end
104
106
 
107
+ def exclude_end?
108
+ exclude_end.truthy?
109
+ end
110
+
105
111
  def code_step(argument)
106
112
  list = List.new
107
113
  element = left
@@ -127,10 +133,6 @@ class Code
127
133
  List.new(raw.to_a)
128
134
  end
129
135
 
130
- def exclude_end?
131
- !!exclude_end
132
- end
133
-
134
136
  def inspect
135
137
  to_s
136
138
  end