template-ruby 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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