template-ruby 0.1.0 → 0.2.2

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.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +9 -0
  3. data/.gitignore +1 -0
  4. data/.prettierrc +3 -0
  5. data/CHANGELOG.md +22 -0
  6. data/Gemfile.lock +5 -5
  7. data/README.md +10 -0
  8. data/bin/template +39 -0
  9. data/docs/euler/1.template +14 -0
  10. data/docs/euler/2.template +16 -0
  11. data/docs/euler/3.template +16 -0
  12. data/docs/euler/4.template +11 -0
  13. data/docs/euler/5.template +14 -0
  14. data/docs/precedence.template +94 -0
  15. data/lib/code/error.rb +15 -0
  16. data/lib/code/node/base_10_decimal.rb +12 -7
  17. data/lib/code/node/base_10_integer.rb +13 -4
  18. data/lib/code/node/base_10_number.rb +3 -3
  19. data/lib/code/node/base_16_number.rb +2 -2
  20. data/lib/code/node/base_2_number.rb +2 -2
  21. data/lib/code/node/base_8_number.rb +2 -2
  22. data/lib/code/node/block.rb +17 -0
  23. data/lib/code/node/boolean.rb +13 -4
  24. data/lib/code/node/call.rb +41 -8
  25. data/lib/code/node/call_argument.rb +37 -0
  26. data/lib/code/node/chained_call.rb +38 -0
  27. data/lib/code/node/code.rb +4 -7
  28. data/lib/code/node/defined.rb +19 -0
  29. data/lib/code/node/dictionnary.rb +11 -7
  30. data/lib/code/node/dictionnary_key_value.rb +3 -3
  31. data/lib/code/node/equal.rb +36 -0
  32. data/lib/code/node/function.rb +17 -0
  33. data/lib/code/node/function_argument.rb +45 -0
  34. data/lib/code/node/group.rb +13 -0
  35. data/lib/code/node/if.rb +55 -0
  36. data/lib/code/node/if_modifier.rb +48 -0
  37. data/lib/code/node/keyword_call_argument.rb +30 -0
  38. data/lib/code/node/keyword_function_argument.rb +33 -0
  39. data/lib/code/node/list.rb +10 -4
  40. data/lib/code/node/name.rb +37 -4
  41. data/lib/code/node/negation.rb +33 -0
  42. data/lib/code/node/not_keyword.rb +13 -0
  43. data/lib/code/node/nothing.rb +2 -2
  44. data/lib/code/node/number.rb +3 -3
  45. data/lib/code/node/operation.rb +33 -0
  46. data/lib/code/node/or_keyword.rb +34 -0
  47. data/lib/code/node/power.rb +16 -0
  48. data/lib/code/node/range.rb +31 -0
  49. data/lib/code/node/regular_call_argument.rb +34 -0
  50. data/lib/code/node/regular_function_argument.rb +36 -0
  51. data/lib/code/node/rescue.rb +16 -0
  52. data/lib/code/node/statement.rb +53 -3
  53. data/lib/code/node/string.rb +2 -2
  54. data/lib/code/node/ternary.rb +26 -0
  55. data/lib/code/node/unary_minus.rb +22 -0
  56. data/lib/code/node/while.rb +42 -0
  57. data/lib/code/node.rb +10 -0
  58. data/lib/code/object/argument.rb +41 -0
  59. data/lib/code/object/boolean.rb +8 -9
  60. data/lib/code/object/decimal.rb +32 -9
  61. data/lib/code/object/dictionnary.rb +33 -10
  62. data/lib/code/object/function.rb +64 -0
  63. data/lib/code/object/integer.rb +94 -7
  64. data/lib/code/object/list.rb +190 -10
  65. data/lib/code/object/nothing.rb +10 -9
  66. data/lib/code/object/number.rb +6 -0
  67. data/lib/code/object/range.rb +158 -0
  68. data/lib/code/object/string.rb +37 -7
  69. data/lib/code/object.rb +121 -2
  70. data/lib/code/parser/addition.rb +29 -0
  71. data/lib/code/parser/and_operator.rb +28 -0
  72. data/lib/code/parser/bitwise_and.rb +28 -0
  73. data/lib/code/parser/bitwise_or.rb +29 -0
  74. data/lib/code/parser/call.rb +77 -3
  75. data/lib/code/parser/code.rb +2 -1
  76. data/lib/code/parser/defined.rb +20 -0
  77. data/lib/code/parser/equal.rb +42 -0
  78. data/lib/code/parser/equality.rb +36 -0
  79. data/lib/code/parser/function.rb +57 -0
  80. data/lib/code/parser/greater_than.rb +33 -0
  81. data/lib/code/parser/group.rb +17 -0
  82. data/lib/code/parser/if.rb +33 -0
  83. data/lib/code/parser/if_modifier.rb +28 -0
  84. data/lib/code/parser/multiplication.rb +30 -0
  85. data/lib/code/parser/name.rb +44 -4
  86. data/lib/code/parser/negation.rb +19 -0
  87. data/lib/code/parser/not_keyword.rb +21 -0
  88. data/lib/code/parser/nothing.rb +2 -2
  89. data/lib/code/parser/or_keyword.rb +29 -0
  90. data/lib/code/parser/or_operator.rb +28 -0
  91. data/lib/code/parser/power.rb +25 -0
  92. data/lib/code/parser/range.rb +25 -0
  93. data/lib/code/parser/rescue.rb +23 -0
  94. data/lib/code/parser/shift.rb +31 -0
  95. data/lib/code/parser/statement.rb +1 -4
  96. data/lib/code/parser/string.rb +7 -1
  97. data/lib/code/parser/ternary.rb +25 -0
  98. data/lib/code/parser/unary_minus.rb +13 -0
  99. data/lib/code/parser/while.rb +25 -0
  100. data/lib/code.rb +5 -7
  101. data/lib/template/node/code_part.rb +2 -2
  102. data/lib/template/node/part.rb +2 -2
  103. data/lib/template/node/template.rb +4 -2
  104. data/lib/template/node/text_part.rb +1 -1
  105. data/lib/template/parser/template.rb +6 -2
  106. data/lib/template-ruby.rb +4 -0
  107. data/lib/template.rb +9 -4
  108. data/spec/call_spec.rb +22 -0
  109. data/spec/code/error/type_error_spec.rb +65 -0
  110. data/spec/code/parser/boolean_spec.rb +1 -1
  111. data/spec/code/parser/call_spec.rb +38 -11
  112. data/spec/code/parser/dictionnary_spec.rb +11 -11
  113. data/spec/code/parser/function_spec.rb +32 -0
  114. data/spec/code/parser/list_spec.rb +5 -5
  115. data/spec/code/parser/nothing_spec.rb +1 -1
  116. data/spec/code/parser/number_spec.rb +35 -35
  117. data/spec/code/parser/string_spec.rb +3 -2
  118. data/spec/code_spec.rb +75 -3
  119. data/spec/function_spec.rb +26 -0
  120. data/spec/spec_helper.rb +2 -0
  121. data/spec/template/parser/template_spec.rb +1 -1
  122. data/spec/template_spec.rb +3 -6
  123. data/template-ruby.gemspec +6 -3
  124. metadata +76 -4
@@ -0,0 +1,16 @@
1
+ class Code
2
+ class Node
3
+ class Rescue < Node
4
+ def initialize(power)
5
+ @left = ::Code::Node::Statement.new(power.fetch(:left))
6
+ @right = ::Code::Node::Statement.new(power.fetch(:right))
7
+ end
8
+
9
+ def evaluate(**args)
10
+ @left.evaluate(**args)
11
+ rescue ::Code::Error
12
+ @right.evaluate(**args)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,6 +1,8 @@
1
1
  class Code
2
2
  class Node
3
- class Statement
3
+ class Statement < Node
4
+ attr_reader :statement
5
+
4
6
  def initialize(statement)
5
7
  if statement.key?(:nothing)
6
8
  @statement = ::Code::Node::Nothing.new
@@ -18,13 +20,61 @@ class Code
18
20
  @statement = ::Code::Node::List.new(statement[:list])
19
21
  elsif statement.key?(:dictionnary)
20
22
  @statement = ::Code::Node::Dictionnary.new(statement[:dictionnary])
23
+ elsif statement.key?(:negation)
24
+ @statement = ::Code::Node::Negation.new(statement[:negation])
25
+ elsif statement.key?(:power)
26
+ @statement = ::Code::Node::Power.new(statement[:power])
27
+ elsif statement.key?(:unary_minus)
28
+ @statement = ::Code::Node::UnaryMinus.new(statement[:unary_minus])
29
+ elsif statement.key?(:multiplication)
30
+ @statement = ::Code::Node::Operation.new(statement[:multiplication])
31
+ elsif statement.key?(:addition)
32
+ @statement = ::Code::Node::Operation.new(statement[:addition])
33
+ elsif statement.key?(:shift)
34
+ @statement = ::Code::Node::Operation.new(statement[:shift])
35
+ elsif statement.key?(:bitwise_and)
36
+ @statement = ::Code::Node::Operation.new(statement[:bitwise_and])
37
+ elsif statement.key?(:bitwise_or)
38
+ @statement = ::Code::Node::Operation.new(statement[:bitwise_or])
39
+ elsif statement.key?(:greater_than)
40
+ @statement = ::Code::Node::Operation.new(statement[:greater_than])
41
+ elsif statement.key?(:equality)
42
+ @statement = ::Code::Node::Operation.new(statement[:equality])
43
+ elsif statement.key?(:and_operator)
44
+ @statement = ::Code::Node::Operation.new(statement[:and_operator])
45
+ elsif statement.key?(:or_operator)
46
+ @statement = ::Code::Node::Operation.new(statement[:or_operator])
47
+ elsif statement.key?(:range)
48
+ @statement = ::Code::Node::Range.new(statement[:range])
49
+ elsif statement.key?(:ternary)
50
+ @statement = ::Code::Node::Ternary.new(statement[:ternary])
51
+ elsif statement.key?(:rescue)
52
+ @statement = ::Code::Node::Rescue.new(statement[:rescue])
53
+ elsif statement.key?(:equal)
54
+ @statement = ::Code::Node::Equal.new(statement[:equal])
55
+ elsif statement.key?(:defined)
56
+ @statement = ::Code::Node::Defined.new(statement[:defined])
57
+ elsif statement.key?(:not_keyword)
58
+ @statement = ::Code::Node::NotKeyword.new(statement[:not_keyword])
59
+ elsif statement.key?(:or_keyword)
60
+ @statement = ::Code::Node::OrKeyword.new(statement[:or_keyword])
61
+ elsif statement.key?(:if_modifier)
62
+ @statement = ::Code::Node::IfModifier.new(statement[:if_modifier])
63
+ elsif statement.key?(:if)
64
+ @statement = ::Code::Node::If.new(statement[:if])
65
+ elsif statement.key?(:while)
66
+ @statement = ::Code::Node::While.new(statement[:while])
67
+ elsif statement.key?(:group)
68
+ @statement = ::Code::Node::Group.new(statement[:group])
69
+ elsif statement.key?(:function)
70
+ @statement = ::Code::Node::Function.new(statement[:function])
21
71
  else
22
72
  raise NotImplementedError.new(statement.inspect)
23
73
  end
24
74
  end
25
75
 
26
- def evaluate(context)
27
- @statement.evaluate(context)
76
+ def evaluate(**args)
77
+ @statement.evaluate(**args)
28
78
  end
29
79
  end
30
80
  end
@@ -1,11 +1,11 @@
1
1
  class Code
2
2
  class Node
3
- class String
3
+ class String < Node
4
4
  def initialize(string)
5
5
  @string = string
6
6
  end
7
7
 
8
- def evaluate(context)
8
+ def evaluate(**args)
9
9
  ::Code::Object::String.new(string.to_s)
10
10
  end
11
11
 
@@ -0,0 +1,26 @@
1
+ class Code
2
+ class Node
3
+ class Ternary < Node
4
+ def initialize(ternary)
5
+ @left = ::Code::Node::Statement.new(ternary.fetch(:left))
6
+ @middle = ::Code::Node::Statement.new(ternary.fetch(:middle))
7
+
8
+ if ternary.key?(:right)
9
+ @right = ::Code::Node::Statement.new(ternary.fetch(:right))
10
+ end
11
+ end
12
+
13
+ def evaluate(**args)
14
+ left = @left.evaluate(**args)
15
+
16
+ if left.truthy?
17
+ @middle.evaluate(**args)
18
+ elsif @right
19
+ @right.evaluate(**args)
20
+ else
21
+ ::Code::Object::Nothing.new
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ class Code
2
+ class Node
3
+ class UnaryMinus < Node
4
+ def initialize(unary_minus)
5
+ @statement = ::Code::Node::Statement.new(unary_minus)
6
+ end
7
+
8
+ def evaluate(**args)
9
+ object = @statement.evaluate(**args)
10
+
11
+ case object
12
+ when ::Code::Object::Integer
13
+ ::Code::Object::Integer.new(-object.raw)
14
+ when ::Code::Object::Decimal
15
+ ::Code::Object::Decimal.new(-object.raw)
16
+ else
17
+ ::Code::Object::Nothing.new
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,42 @@
1
+ class Code
2
+ class Node
3
+ class While < Node
4
+ WHILE_KEYWORD = :while
5
+ UNTIL_KEYWORD = :until
6
+
7
+ def initialize(while_parsed)
8
+ @operator = while_parsed.fetch(:operator)
9
+ @statement = ::Code::Node::Statement.new(while_parsed.fetch(:statement))
10
+ @body = ::Code::Node::Code.new(while_parsed.fetch(:body))
11
+ end
12
+
13
+ def evaluate(**args)
14
+ if operator == WHILE_KEYWORD
15
+ object = ::Code::Object::Nothing.new
16
+
17
+ while @statement.evaluate(**args).truthy?
18
+ object = @body.evaluate(**args)
19
+ end
20
+
21
+ object
22
+ elsif operator == UNTIL_KEYWORD
23
+ object = ::Code::Object::Nothing.new
24
+
25
+ until @statement.evaluate(**args).truthy?
26
+ object = @body.evaluate(**args)
27
+ end
28
+
29
+ object
30
+ else
31
+ raise NotImplementedError.new(operator.inspect)
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def operator
38
+ @operator.to_sym
39
+ end
40
+ end
41
+ end
42
+ end
data/lib/code/node.rb CHANGED
@@ -1,4 +1,14 @@
1
1
  class Code
2
2
  class Node
3
+ private
4
+
5
+ def simple_call(object, operator = nil, value = nil, **args)
6
+ object.call(
7
+ operator: operator && ::Code::Object::String.new(operator.to_s),
8
+ arguments: [value && ::Code::Object::Argument.new(value)].compact,
9
+ context: args.fetch(:context),
10
+ io: args.fetch(:io),
11
+ )
12
+ end
3
13
  end
4
14
  end
@@ -0,0 +1,41 @@
1
+ class Code
2
+ class Object
3
+ class Argument < ::Code::Object
4
+ attr_reader :value, :name, :splat, :keyword_splat, :block
5
+
6
+ def initialize(
7
+ value,
8
+ name: nil,
9
+ splat: false,
10
+ keyword_splat: false,
11
+ block: false
12
+ )
13
+ @value = value
14
+ @name = name
15
+ @splat = !!splat
16
+ @keyword_splat = !!keyword_splat
17
+ @block = !!block
18
+ end
19
+
20
+ def regular?
21
+ !name
22
+ end
23
+
24
+ def keyword?
25
+ !regular?
26
+ end
27
+
28
+ def name_value
29
+ [name, value]
30
+ end
31
+
32
+ def to_s
33
+ "argument"
34
+ end
35
+
36
+ def inspect
37
+ to_s
38
+ end
39
+ end
40
+ end
41
+ end
@@ -7,21 +7,20 @@ class Code
7
7
  @raw = raw
8
8
  end
9
9
 
10
- def to_s
11
- raw.to_s
10
+ def truthy?
11
+ raw
12
12
  end
13
13
 
14
- def inspect
15
- to_s
14
+ def succ
15
+ ::Code::Object::Boolean.new(!raw)
16
16
  end
17
17
 
18
- def ==(other)
19
- raw == other.raw
18
+ def to_s
19
+ raw.to_s
20
20
  end
21
- alias_method :eql?, :==
22
21
 
23
- def hash
24
- [self.class, raw].hash
22
+ def inspect
23
+ to_s
25
24
  end
26
25
  end
27
26
  end
@@ -1,13 +1,31 @@
1
- require "bigdecimal"
2
-
3
1
  class Code
4
2
  class Object
5
- class Decimal < ::Code::Object
3
+ class Decimal < ::Code::Object::Number
6
4
  attr_reader :raw
7
5
 
8
6
  def initialize(decimal, exponent: nil)
9
7
  @raw = BigDecimal(decimal)
10
- @raw = @raw * 10**exponent.raw if exponent
8
+
9
+ if exponent
10
+ if exponent.is_a?(::Code::Object::Number)
11
+ @raw = @raw * 10**exponent.raw
12
+ else
13
+ raise ::Code::Error::TypeError.new("exponent is not a number")
14
+ end
15
+ end
16
+ end
17
+
18
+ def call(**args)
19
+ operator = args.fetch(:operator, nil)
20
+ arguments = args.fetch(:arguments, [])
21
+
22
+ if %w[% - + / * **].detect { |o| operator == o }
23
+ number_operation(operator.to_sym, arguments)
24
+ elsif %w[< <= > >=].detect { |o| operator == o }
25
+ comparaison(operator.to_sym, arguments)
26
+ else
27
+ super
28
+ end
11
29
  end
12
30
 
13
31
  def to_s
@@ -18,13 +36,18 @@ class Code
18
36
  to_s
19
37
  end
20
38
 
21
- def ==(other)
22
- raw == other.raw
39
+ private
40
+
41
+ def number_operation(operator, arguments)
42
+ sig(arguments, ::Code::Object::Number)
43
+ other = arguments.first.value
44
+ ::Code::Object::Decimal.new(raw.public_send(operator, other.raw))
23
45
  end
24
- alias_method :eql?, :==
25
46
 
26
- def hash
27
- [self.class, raw].hash
47
+ def comparaison(operator, arguments)
48
+ sig(arguments, ::Code::Object::Number)
49
+ other = arguments.first.value
50
+ ::Code::Object::Boolean.new(raw.public_send(operator, other.raw))
28
51
  end
29
52
  end
30
53
  end
@@ -7,6 +7,35 @@ class Code
7
7
  @raw = raw
8
8
  end
9
9
 
10
+ def call(**args)
11
+ operator = args.fetch(:operator, nil)
12
+ arguments = args.fetch(:arguments, [])
13
+
14
+ if operator == "values"
15
+ values(arguments)
16
+ elsif key?(operator)
17
+ fetch(operator)
18
+ else
19
+ super
20
+ end
21
+ end
22
+
23
+ def fetch(key)
24
+ raw.fetch(key)
25
+ end
26
+
27
+ def [](key)
28
+ raw[key]
29
+ end
30
+
31
+ def []=(key, value)
32
+ raw[key] = value
33
+ end
34
+
35
+ def key?(key)
36
+ raw.key?(key)
37
+ end
38
+
10
39
  def to_s
11
40
  "{#{raw.map { |key, value| "#{key.inspect} => #{value.inspect}" }.join(", ")}}"
12
41
  end
@@ -15,17 +44,11 @@ class Code
15
44
  to_s
16
45
  end
17
46
 
18
- def fetch(key, default = ::Code::Object::Nothing.new)
19
- raw.fetch(key, default)
20
- end
21
-
22
- def ==(other)
23
- raw == other.raw
24
- end
25
- alias_method :eql?, :==
47
+ private
26
48
 
27
- def hash
28
- [self.class, raw].hash
49
+ def values(arguments)
50
+ sig(arguments)
51
+ ::Code::Object::List.new(raw.values)
29
52
  end
30
53
  end
31
54
  end
@@ -0,0 +1,64 @@
1
+ class Code
2
+ class Object
3
+ class Function < ::Code::Object
4
+ def initialize(arguments:, body:)
5
+ @arguments = arguments
6
+ @body = body
7
+ end
8
+
9
+ def call(**args)
10
+ operator = args.fetch(:operator, nil)
11
+ arguments = args.fetch(:arguments, [])
12
+ context = args.fetch(:context)
13
+ io = args.fetch(:io)
14
+
15
+ if operator.nil?
16
+ call_function(args: arguments, context: context, io: io)
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ def to_s
23
+ ""
24
+ end
25
+
26
+ def inspect
27
+ "function"
28
+ end
29
+
30
+ private
31
+
32
+ attr_reader :arguments, :body
33
+
34
+ def call_function(args:, context:, io:)
35
+ new_context = context.dup
36
+ arguments.each.with_index do |argument, index|
37
+ if argument.regular?
38
+ if argument.splat?
39
+ new_context[argument.name] = ::Code::Object::List.new(
40
+ args.select(&:regular?).map(&:value),
41
+ )
42
+ elsif argument.keyword_splat?
43
+ new_context[argument.name] = ::Code::Object::Dictionnary.new(
44
+ args.select(&:keyword?).map(&:name_value).to_h,
45
+ )
46
+ else
47
+ arg = args[index]&.value
48
+ arg = argument.evaluate(context: new_context, io: io) if arg.nil?
49
+ new_context[argument.name] = arg
50
+ end
51
+ elsif argument.keyword?
52
+ arg = args.detect { |arg| arg.name == argument.name }&.value
53
+ arg = argument.evaluate(context: new_context, io: io) if arg.nil?
54
+ new_context[argument.name] = arg
55
+ else
56
+ raise NotImplementedError
57
+ end
58
+ end
59
+
60
+ body.evaluate(context: new_context, io: io)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -1,11 +1,55 @@
1
1
  class Code
2
2
  class Object
3
- class Integer < ::Code::Object
3
+ class Integer < ::Code::Object::Number
4
4
  attr_reader :raw
5
5
 
6
6
  def initialize(whole, exponent: nil)
7
7
  @raw = whole.to_i
8
- @raw = @raw * 10**exponent.raw if exponent
8
+
9
+ if exponent
10
+ if exponent.is_a?(::Code::Object::Number)
11
+ @raw = @raw * 10**exponent.raw
12
+ else
13
+ raise ::Code::Error::TypeError.new("exponent is not a number")
14
+ end
15
+ end
16
+ end
17
+
18
+ def call(**args)
19
+ operator = args.fetch(:operator, nil)
20
+ arguments = args.fetch(:arguments, [])
21
+
22
+ if operator == "even?"
23
+ even?(arguments)
24
+ elsif operator == "to_string"
25
+ code_to_s(arguments)
26
+ elsif operator == "*"
27
+ multiplication(arguments)
28
+ elsif operator == "/"
29
+ division(arguments)
30
+ elsif %w[% - + **].detect { |o| operator == o }
31
+ integer_or_decimal_operation(operator.to_sym, arguments)
32
+ elsif %w[> >= < <=].detect { |o| operator == o }
33
+ comparaison(operator.to_sym, arguments)
34
+ elsif %w[<< >> & | ^].detect { |o| operator == o }
35
+ integer_operation(operator.to_sym, arguments)
36
+ else
37
+ super
38
+ end
39
+ end
40
+
41
+ def +(other)
42
+ if other.is_a?(::Code::Object::Integer)
43
+ ::Code::Object::Integer.new(raw + other.raw)
44
+ elsif other.is_a?(::Code::Object::Decimal)
45
+ ::Code::Object::Decimal.new(raw + other.raw)
46
+ else
47
+ raise ::Code::Error::TypeError
48
+ end
49
+ end
50
+
51
+ def succ
52
+ ::Code::Object::Integer.new(raw + 1)
9
53
  end
10
54
 
11
55
  def to_s
@@ -16,13 +60,56 @@ class Code
16
60
  to_s
17
61
  end
18
62
 
19
- def ==(other)
20
- raw == other.raw
63
+ private
64
+
65
+ def even?(arguments)
66
+ sig(arguments)
67
+ ::Code::Object::Boolean.new(raw.even?)
68
+ end
69
+
70
+ def code_to_s(arguments)
71
+ sig(arguments)
72
+ ::Code::Object::String.new(raw.to_s)
73
+ end
74
+
75
+ def multiplication(arguments)
76
+ sig(arguments, [::Code::Object::Number, ::Code::Object::String])
77
+ other = arguments.first.value
78
+ if other.is_a?(::Code::Object::Integer)
79
+ ::Code::Object::Integer.new(raw * other.raw)
80
+ elsif other.is_a?(::Code::Object::Decimal)
81
+ ::Code::Object::Decimal.new(raw * other.raw)
82
+ else
83
+ ::Code::Object::String.new(other.raw * raw)
84
+ end
85
+ end
86
+
87
+ def division(arguments)
88
+ sig(arguments, ::Code::Object::Number)
89
+ other = arguments.first.value
90
+ ::Code::Object::Decimal.new(BigDecimal(raw) / other.raw)
91
+ end
92
+
93
+ def integer_or_decimal_operation(operator, arguments)
94
+ sig(arguments, ::Code::Object::Number)
95
+ other = arguments.first.value
96
+ if other.is_a?(::Code::Object::Integer)
97
+ ::Code::Object::Integer.new(raw.public_send(operator, other.raw))
98
+ else
99
+ ::Code::Object::Decimal.new(raw.public_send(operator, other.raw))
100
+ end
101
+ end
102
+
103
+ def integer_operation(operator, arguments)
104
+ sig(arguments, ::Code::Object::Integer)
105
+ other = arguments.first.value
106
+ ::Code::Object::Integer.new(raw.public_send(operator, other.raw))
21
107
  end
22
- alias_method :eql?, :==
23
108
 
24
- def hash
25
- [self.class, raw].hash
109
+ def comparaison(operator, arguments)
110
+ sig(arguments, ::Code::Object::Number)
111
+ other = arguments.first.value
112
+ ::Code::Object::Boolean.new(raw.public_send(operator, other.raw))
26
113
  end
27
114
  end
28
115
  end