template-ruby 0.1.0 → 0.2.0

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 (122) 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 +15 -0
  6. data/Gemfile.lock +1 -1
  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 +40 -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 +129 -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/defined.rb +20 -0
  76. data/lib/code/parser/equal.rb +42 -0
  77. data/lib/code/parser/equality.rb +36 -0
  78. data/lib/code/parser/function.rb +57 -0
  79. data/lib/code/parser/greater_than.rb +33 -0
  80. data/lib/code/parser/group.rb +17 -0
  81. data/lib/code/parser/if.rb +33 -0
  82. data/lib/code/parser/if_modifier.rb +28 -0
  83. data/lib/code/parser/multiplication.rb +30 -0
  84. data/lib/code/parser/name.rb +44 -4
  85. data/lib/code/parser/negation.rb +19 -0
  86. data/lib/code/parser/not_keyword.rb +21 -0
  87. data/lib/code/parser/nothing.rb +2 -2
  88. data/lib/code/parser/or_keyword.rb +29 -0
  89. data/lib/code/parser/or_operator.rb +28 -0
  90. data/lib/code/parser/power.rb +25 -0
  91. data/lib/code/parser/range.rb +25 -0
  92. data/lib/code/parser/rescue.rb +23 -0
  93. data/lib/code/parser/shift.rb +31 -0
  94. data/lib/code/parser/statement.rb +1 -4
  95. data/lib/code/parser/string.rb +7 -1
  96. data/lib/code/parser/ternary.rb +25 -0
  97. data/lib/code/parser/unary_minus.rb +13 -0
  98. data/lib/code/parser/while.rb +25 -0
  99. data/lib/code.rb +5 -7
  100. data/lib/template/node/code_part.rb +2 -2
  101. data/lib/template/node/part.rb +2 -2
  102. data/lib/template/node/template.rb +4 -2
  103. data/lib/template/node/text_part.rb +1 -1
  104. data/lib/template-ruby.rb +4 -0
  105. data/lib/template.rb +9 -4
  106. data/spec/call_spec.rb +22 -0
  107. data/spec/code/error/type_error_spec.rb +65 -0
  108. data/spec/code/parser/boolean_spec.rb +1 -1
  109. data/spec/code/parser/call_spec.rb +40 -11
  110. data/spec/code/parser/dictionnary_spec.rb +11 -11
  111. data/spec/code/parser/function_spec.rb +32 -0
  112. data/spec/code/parser/list_spec.rb +5 -5
  113. data/spec/code/parser/nothing_spec.rb +1 -1
  114. data/spec/code/parser/number_spec.rb +35 -35
  115. data/spec/code/parser/string_spec.rb +3 -2
  116. data/spec/code_spec.rb +75 -3
  117. data/spec/function_spec.rb +26 -0
  118. data/spec/spec_helper.rb +2 -0
  119. data/spec/template/parser/template_spec.rb +1 -1
  120. data/spec/template_spec.rb +6 -6
  121. data/template-ruby.gemspec +6 -3
  122. metadata +76 -4
@@ -3,10 +3,66 @@ class Code
3
3
  class List < ::Code::Object
4
4
  attr_reader :raw
5
5
 
6
- def initialize(raw)
6
+ def initialize(raw = [])
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
+ context = args.fetch(:context)
14
+ io = args.fetch(:io)
15
+
16
+ if operator == "any?"
17
+ any?(arguments, context: context, io: io)
18
+ elsif operator == "none?"
19
+ none?(arguments, context: context, io: io)
20
+ elsif operator == "detect"
21
+ detect(arguments, context: context, io: io)
22
+ elsif operator == "reduce"
23
+ reduce(arguments, context: context, io: io)
24
+ elsif operator == "each"
25
+ each(arguments, context: context, io: io)
26
+ elsif operator == "select"
27
+ select(arguments, context: context, io: io)
28
+ elsif operator == "map"
29
+ map(arguments, context: context, io: io)
30
+ elsif operator == "max"
31
+ max(arguments)
32
+ elsif operator == "flatten"
33
+ flatten(arguments)
34
+ elsif operator == "reverse"
35
+ reverse(arguments)
36
+ elsif operator == "first"
37
+ first(arguments)
38
+ elsif operator == "last"
39
+ last(arguments)
40
+ elsif operator == "max_by"
41
+ max_by(arguments, context: context, io: io)
42
+ elsif operator == "<<"
43
+ append(arguments)
44
+ else
45
+ super
46
+ end
47
+ end
48
+
49
+ def <<(element)
50
+ raw << element
51
+ end
52
+
53
+ def flatten(arguments)
54
+ sig(arguments)
55
+ ::Code::Object::List.new(
56
+ raw.reduce([]) do |acc, element|
57
+ if element.is_a?(::Code::Object::List)
58
+ acc + element.flatten(arguments).raw
59
+ else
60
+ acc + [element]
61
+ end
62
+ end
63
+ )
64
+ end
65
+
10
66
  def to_s
11
67
  "[#{raw.map(&:inspect).join(", ")}]"
12
68
  end
@@ -15,22 +71,146 @@ class Code
15
71
  to_s
16
72
  end
17
73
 
18
- def map(&block)
19
- @raw = raw.map(&block)
74
+ private
75
+
76
+ def any?(arguments, context:, io:)
77
+ sig(arguments, ::Code::Object::Function)
78
+ argument = arguments.first
79
+ ::Code::Object::Boolean.new(
80
+ raw.any? do |element|
81
+ argument
82
+ .value
83
+ .call(
84
+ arguments: [::Code::Object::Argument.new(element)],
85
+ context: context,
86
+ io: io,
87
+ )
88
+ .truthy?
89
+ end,
90
+ )
91
+ end
92
+
93
+ def none?(arguments, context:, io:)
94
+ sig(arguments, ::Code::Object::Function)
95
+ argument = arguments.first
96
+ ::Code::Object::Boolean.new(
97
+ raw.none? do |element|
98
+ argument
99
+ .value
100
+ .call(
101
+ arguments: [::Code::Object::Argument.new(element)],
102
+ context: context,
103
+ io: io,
104
+ )
105
+ .truthy?
106
+ end,
107
+ )
108
+ end
109
+
110
+ def max_by(arguments, context:, io:)
111
+ sig(arguments, ::Code::Object::Function)
112
+ argument = arguments.first.value
113
+ raw.max_by do |element|
114
+ argument.call(
115
+ arguments: [::Code::Object::Argument.new(element)],
116
+ context: context,
117
+ io: io,
118
+ )
119
+ end || ::Code::Object::Nothing.new
120
+ end
121
+
122
+ def detect(arguments, context:, io:)
123
+ sig(arguments, ::Code::Object::Function)
124
+ argument = arguments.first.value
125
+ raw.detect do |element|
126
+ argument.call(
127
+ arguments: [::Code::Object::Argument.new(element)],
128
+ context: context,
129
+ io: io,
130
+ ).truthy?
131
+ end || ::Code::Object::Nothing.new
132
+ end
133
+
134
+ def reduce(arguments, context:, io:)
135
+ sig(arguments, ::Code::Object::Function)
136
+ argument = arguments.first.value
137
+ raw.reduce do |acc, element|
138
+ argument.call(
139
+ arguments: [
140
+ ::Code::Object::Argument.new(acc),
141
+ ::Code::Object::Argument.new(element)
142
+ ],
143
+ context: context,
144
+ io: io,
145
+ )
146
+ end || ::Code::Object::Nothing.new
147
+ end
148
+
149
+ def each(arguments, context:, io:)
150
+ sig(arguments, ::Code::Object::Function)
151
+ argument = arguments.first.value
152
+ raw.each do |element|
153
+ argument.call(
154
+ arguments: [::Code::Object::Argument.new(element)],
155
+ context: context,
156
+ io: io,
157
+ )
158
+ end
20
159
  self
21
160
  end
22
161
 
23
- def join
24
- raw.join
162
+ def select(arguments, context:, io:)
163
+ sig(arguments, ::Code::Object::Function)
164
+ argument = arguments.first.value
165
+ ::Code::Object::List.new(
166
+ raw.select do |element|
167
+ argument.call(
168
+ arguments: [::Code::Object::Argument.new(element)],
169
+ context: context,
170
+ io: io,
171
+ ).truthy?
172
+ end
173
+ )
174
+ end
175
+
176
+ def map(arguments, context:, io:)
177
+ sig(arguments, ::Code::Object::Function)
178
+ argument = arguments.first.value
179
+ ::Code::Object::List.new(
180
+ raw.map do |element|
181
+ argument.call(
182
+ arguments: [::Code::Object::Argument.new(element)],
183
+ context: context,
184
+ io: io,
185
+ )
186
+ end
187
+ )
188
+ end
189
+
190
+ def append(arguments)
191
+ sig(arguments, ::Code::Object)
192
+ raw << arguments.first.value
193
+ self
194
+ end
195
+
196
+ def first(arguments)
197
+ sig(arguments)
198
+ raw.first
199
+ end
200
+
201
+ def max(arguments)
202
+ sig(arguments)
203
+ raw.max || ::Code::Object::Nothing.new
25
204
  end
26
205
 
27
- def ==(other)
28
- raw == other.raw
206
+ def reverse(arguments)
207
+ sig(arguments)
208
+ ::Code::Object::List.new(raw.reverse)
29
209
  end
30
- alias_method :eql?, :==
31
210
 
32
- def hash
33
- [self.class, raw].hash
211
+ def last(arguments)
212
+ sig(arguments)
213
+ raw.last
34
214
  end
35
215
  end
36
216
  end
@@ -1,21 +1,22 @@
1
1
  class Code
2
2
  class Object
3
3
  class Nothing < ::Code::Object
4
- def to_s
5
- ""
4
+ attr_reader :raw
5
+
6
+ def initialize
7
+ @raw = nil
6
8
  end
7
9
 
8
- def inspect
9
- "nothing"
10
+ def truthy?
11
+ false
10
12
  end
11
13
 
12
- def ==(other)
13
- other.is_a?(::Code::Object::Nothing)
14
+ def to_s
15
+ ""
14
16
  end
15
- alias_method :eql?, :==
16
17
 
17
- def hash
18
- [self.class, nil].hash
18
+ def inspect
19
+ "nothing"
19
20
  end
20
21
  end
21
22
  end
@@ -0,0 +1,6 @@
1
+ class Code
2
+ class Object
3
+ class Number < ::Code::Object
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,158 @@
1
+ class Code
2
+ class Object
3
+ class Range < ::Code::Object
4
+ attr_reader :raw
5
+
6
+ def initialize(left, right, exclude_end: false)
7
+ @left = left
8
+ @right = right
9
+ @exclude_end = exclude_end
10
+ @raw = ::Range.new(left, right, exclude_end)
11
+ end
12
+
13
+ def call(**args)
14
+ operator = args.fetch(:operator, nil)
15
+ arguments = args.fetch(:arguments, [])
16
+ context = args.fetch(:context)
17
+ io = args.fetch(:io)
18
+
19
+ if operator == "any?"
20
+ any?(arguments, context: context, io: io)
21
+ elsif operator == "all?"
22
+ all?(arguments, context: context, io: io)
23
+ elsif operator == "each"
24
+ each(arguments, context: context, io: io)
25
+ elsif operator == "select"
26
+ select(arguments, context: context, io: io)
27
+ elsif operator == "map"
28
+ map(arguments, context: context, io: io)
29
+ elsif operator == "step"
30
+ step(arguments)
31
+ elsif operator == "to_list"
32
+ to_list(arguments)
33
+ elsif operator == "first"
34
+ first(arguments)
35
+ elsif operator == "last"
36
+ last(arguments)
37
+ else
38
+ super
39
+ end
40
+ end
41
+
42
+ def to_s
43
+ raw.to_s
44
+ end
45
+
46
+ def inspect
47
+ to_s
48
+ end
49
+
50
+ private
51
+
52
+ def any?(arguments, context:, io:)
53
+ sig(arguments, ::Code::Object::Function)
54
+ argument = arguments.first.value
55
+ ::Code::Object::Boolean.new(
56
+ raw.any? do |element|
57
+ argument
58
+ .call(
59
+ arguments: [::Code::Object::Argument.new(element)],
60
+ context: context,
61
+ io: io,
62
+ )
63
+ .truthy?
64
+ end,
65
+ )
66
+ end
67
+
68
+ def all?(arguments, context:, io:)
69
+ sig(arguments, ::Code::Object::Function)
70
+ argument = arguments.first.value
71
+ ::Code::Object::Boolean.new(
72
+ raw.all? do |element|
73
+ argument
74
+ .call(
75
+ arguments: [::Code::Object::Argument.new(element)],
76
+ context: context,
77
+ io: io,
78
+ )
79
+ .truthy?
80
+ end,
81
+ )
82
+ end
83
+
84
+ def each(arguments, context:, io:)
85
+ sig(arguments, ::Code::Object::Function)
86
+ argument = arguments.first.value
87
+ raw.each do |element|
88
+ argument.call(
89
+ arguments: [::Code::Object::Argument.new(element)],
90
+ context: context,
91
+ io: io,
92
+ )
93
+ end
94
+ self
95
+ end
96
+
97
+ def select(arguments, context:, io:)
98
+ sig(arguments, ::Code::Object::Function)
99
+ argument = arguments.first.value
100
+ ::Code::Object::List.new(
101
+ raw.select do |element|
102
+ argument.call(
103
+ arguments: [::Code::Object::Argument.new(element)],
104
+ context: context,
105
+ io: io,
106
+ ).truthy?
107
+ end
108
+ )
109
+ end
110
+
111
+ def map(arguments, context:, io:)
112
+ sig(arguments, ::Code::Object::Function)
113
+ argument = arguments.first.value
114
+ ::Code::Object::List.new(
115
+ raw.map do |element|
116
+ argument.call(
117
+ arguments: [::Code::Object::Argument.new(element)],
118
+ context: context,
119
+ io: io,
120
+ )
121
+ end
122
+ )
123
+ end
124
+
125
+ def step(arguments)
126
+ sig(arguments, ::Code::Object::Number)
127
+ argument = arguments.first.value
128
+
129
+ list = ::Code::Object::List.new
130
+ element = @left
131
+ list << element
132
+
133
+ if @exlucde_end
134
+ list << element while (element = element + argument) < @right
135
+ else
136
+ list << element while (element = element + argument) <= @right
137
+ end
138
+
139
+ list
140
+ end
141
+
142
+ def to_list(arguments)
143
+ sig(arguments)
144
+ ::Code::Object::List.new(raw.to_a)
145
+ end
146
+
147
+ def first(arguments)
148
+ sig(arguments)
149
+ raw.first
150
+ end
151
+
152
+ def last(arguments)
153
+ sig(arguments)
154
+ raw.last
155
+ end
156
+ end
157
+ end
158
+ end
@@ -1,5 +1,3 @@
1
- require "bigdecimal"
2
-
3
1
  class Code
4
2
  class Object
5
3
  class String < ::Code::Object
@@ -9,6 +7,29 @@ class Code
9
7
  @raw = string
10
8
  end
11
9
 
10
+ def call(**args)
11
+ operator = args.fetch(:operator, nil)
12
+ arguments = args.fetch(:arguments, [])
13
+
14
+ if operator == "to_function"
15
+ to_function(arguments)
16
+ elsif operator == "+"
17
+ plus(arguments)
18
+ elsif operator == "reverse"
19
+ reverse(arguments)
20
+ else
21
+ super
22
+ end
23
+ end
24
+
25
+ def succ
26
+ ::Code::Object::String.new(raw.succ)
27
+ end
28
+
29
+ def to_sym
30
+ raw.to_sym
31
+ end
32
+
12
33
  def to_s
13
34
  raw
14
35
  end
@@ -17,13 +38,22 @@ class Code
17
38
  raw.inspect
18
39
  end
19
40
 
20
- def ==(other)
21
- raw == other.raw
41
+ private
42
+
43
+ def to_function(arguments)
44
+ sig(arguments)
45
+ Code.evaluate("(_) => { _.#{raw} }")
46
+ end
47
+
48
+ def plus(arguments)
49
+ sig(arguments, ::Code::Object::String)
50
+ other = arguments.first.value
51
+ ::Code::Object::String.new(raw + other.raw)
22
52
  end
23
- alias_method :eql?, :==
24
53
 
25
- def hash
26
- [self.class, raw].hash
54
+ def reverse(arguments)
55
+ sig(arguments)
56
+ ::Code::Object::String.new(raw.reverse)
27
57
  end
28
58
  end
29
59
  end
data/lib/code/object.rb CHANGED
@@ -1,11 +1,138 @@
1
1
  class Code
2
2
  class Object
3
- def fetch(_key, default = ::Code::Object::Nothing.new)
4
- default
3
+ include Comparable
4
+
5
+ def call(**args)
6
+ operator = args.fetch(:operator, nil)
7
+ arguments = args.fetch(:arguments, [])
8
+ if %w[== === !=].detect { |o| operator == o }
9
+ comparaison(operator.to_sym, arguments)
10
+ elsif operator == "<=>"
11
+ compare(arguments)
12
+ elsif operator == "&&"
13
+ and_operator(arguments)
14
+ elsif operator == "||"
15
+ or_operator(arguments)
16
+ else
17
+ raise ::Code::Error::Undefined.new(
18
+ "#{operator} not defined on #{inspect}",
19
+ )
20
+ end
21
+ end
22
+
23
+ def []=(key, value)
24
+ @attributes ||= {}
25
+ @attributes[key] = value
26
+ end
27
+
28
+ def [](key)
29
+ @attributes ||= {}
30
+ @attributes[key]
31
+ end
32
+
33
+ def key?(key)
34
+ @attributes ||= {}
35
+ @attributes.key?(key)
36
+ end
37
+
38
+ def truthy?
39
+ true
40
+ end
41
+
42
+ def falsy?
43
+ !truthy?
44
+ end
45
+
46
+ def <=>(other)
47
+ if respond_to?(:raw)
48
+ if other.respond_to?(:raw)
49
+ raw <=> other.raw
50
+ else
51
+ raw <=> other
52
+ end
53
+ else
54
+ other <=> self
55
+ end
56
+ end
57
+
58
+ def ==(other)
59
+ if respond_to?(:raw)
60
+ if other.respond_to?(:raw)
61
+ raw == other.raw
62
+ else
63
+ raw == other
64
+ end
65
+ else
66
+ other == self
67
+ end
68
+ end
69
+ alias_method :eql?, :==
70
+
71
+ def hash
72
+ if respond_to?(:raw)
73
+ [self.class, raw].hash
74
+ else
75
+ raise NotImplementedError
76
+ end
5
77
  end
6
78
 
7
79
  def to_s
8
80
  raise NotImplementedError
9
81
  end
82
+
83
+ private
84
+
85
+ def sig(actual_arguments, *expected_arguments)
86
+ if actual_arguments.size != expected_arguments.size
87
+ raise ::Code::Error::ArgumentError.new(
88
+ "Expected #{expected_arguments.size} arguments, " \
89
+ "got #{actual_arguments.size} arguments",
90
+ )
91
+ end
92
+
93
+ expected_arguments.each.with_index do |expected_argument, index|
94
+ actual_argument = actual_arguments[index].value
95
+
96
+ if expected_argument.is_a?(Array)
97
+ if expected_argument.none? { |expected_arg|
98
+ actual_argument.is_a?(expected_arg)
99
+ }
100
+ raise ::Code::Error::TypeError.new(
101
+ "Expected #{expected_argument}, got #{actual_argument.class}",
102
+ )
103
+ end
104
+ else
105
+ if !actual_argument.is_a?(expected_argument)
106
+ raise ::Code::Error::TypeError.new(
107
+ "Expected #{expected_argument}, got #{actual_argument.class}",
108
+ )
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ def comparaison(operator, arguments)
115
+ sig(arguments, ::Code::Object)
116
+ other = arguments.first.value
117
+ ::Code::Object::Boolean.new(public_send(operator, other))
118
+ end
119
+
120
+ def compare(arguments)
121
+ sig(arguments, ::Code::Object)
122
+ other = arguments.first.value
123
+ ::Code::Object::Integer.new(self <=> other)
124
+ end
125
+
126
+ def and_operator(arguments)
127
+ sig(arguments, ::Code::Object)
128
+ other = arguments.first.value
129
+ truthy? ? other : self
130
+ end
131
+
132
+ def or_operator(arguments)
133
+ sig(arguments, ::Code::Object)
134
+ other = arguments.first.value
135
+ truthy? ? self : other
136
+ end
10
137
  end
11
138
  end
@@ -0,0 +1,29 @@
1
+ class Code
2
+ class Parser
3
+ class Addition < Parslet::Parser
4
+ rule(:multiplication) { ::Code::Parser::Multiplication.new }
5
+
6
+ rule(:plus) { str("+") }
7
+ rule(:minus) { str("-") }
8
+
9
+ rule(:operator) { plus | minus }
10
+
11
+ rule(:space) { str(" ") }
12
+ rule(:newline) { str("\n") }
13
+ rule(:whitespace) { (space | newline).repeat(1) }
14
+ rule(:whitespace?) { whitespace.maybe }
15
+
16
+ rule(:addition) do
17
+ (
18
+ multiplication.as(:first) >>
19
+ (
20
+ whitespace? >> operator.as(:operator) >> whitespace? >>
21
+ multiplication.as(:statement)
22
+ ).repeat(1).as(:rest)
23
+ ).as(:addition) | multiplication
24
+ end
25
+
26
+ root(:addition)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,28 @@
1
+ class Code
2
+ class Parser
3
+ class AndOperator < Parslet::Parser
4
+ rule(:equality) { ::Code::Parser::Equality.new }
5
+
6
+ rule(:ampersand) { str("&") }
7
+
8
+ rule(:operator) { ampersand >> ampersand }
9
+
10
+ rule(:space) { str(" ") }
11
+ rule(:newline) { str("\n") }
12
+ rule(:whitespace) { (space | newline).repeat(1) }
13
+ rule(:whitespace?) { whitespace.maybe }
14
+
15
+ rule(:and_operator) do
16
+ (
17
+ equality.as(:first) >>
18
+ (
19
+ whitespace? >> operator.as(:operator) >> whitespace? >>
20
+ equality.as(:statement)
21
+ ).repeat(1).as(:rest)
22
+ ).as(:and_operator) | equality
23
+ end
24
+
25
+ root(:and_operator)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ class Code
2
+ class Parser
3
+ class BitwiseAnd < Parslet::Parser
4
+ rule(:shift) { ::Code::Parser::Shift.new }
5
+
6
+ rule(:ampersand) { str("&") }
7
+
8
+ rule(:operator) { ampersand }
9
+
10
+ rule(:space) { str(" ") }
11
+ rule(:newline) { str("\n") }
12
+ rule(:whitespace) { (space | newline).repeat(1) }
13
+ rule(:whitespace?) { whitespace.maybe }
14
+
15
+ rule(:bitwise_and) do
16
+ (
17
+ shift.as(:first) >>
18
+ (
19
+ whitespace? >> operator.as(:operator) >> whitespace? >>
20
+ shift.as(:statement)
21
+ ).repeat(1).as(:rest)
22
+ ).as(:bitwise_and) | shift
23
+ end
24
+
25
+ root(:bitwise_and)
26
+ end
27
+ end
28
+ end