template-ruby 0.1.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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.call(
58
+ arguments: [::Code::Object::Argument.new(element)],
59
+ context: context,
60
+ io: io,
61
+ ).truthy?
62
+ end,
63
+ )
64
+ end
65
+
66
+ def all?(arguments, context:, io:)
67
+ sig(arguments, ::Code::Object::Function)
68
+ argument = arguments.first.value
69
+ ::Code::Object::Boolean.new(
70
+ raw.all? do |element|
71
+ argument.call(
72
+ arguments: [::Code::Object::Argument.new(element)],
73
+ context: context,
74
+ io: io,
75
+ ).truthy?
76
+ end,
77
+ )
78
+ end
79
+
80
+ def each(arguments, context:, io:)
81
+ sig(arguments, ::Code::Object::Function)
82
+ argument = arguments.first.value
83
+ raw.each do |element|
84
+ argument.call(
85
+ arguments: [::Code::Object::Argument.new(element)],
86
+ context: context,
87
+ io: io,
88
+ )
89
+ end
90
+ self
91
+ end
92
+
93
+ def select(arguments, context:, io:)
94
+ sig(arguments, ::Code::Object::Function)
95
+ argument = arguments.first.value
96
+ ::Code::Object::List.new(
97
+ raw.select do |element|
98
+ argument.call(
99
+ arguments: [::Code::Object::Argument.new(element)],
100
+ context: context,
101
+ io: io,
102
+ ).truthy?
103
+ end,
104
+ )
105
+ end
106
+
107
+ def map(arguments, context:, io:)
108
+ sig(arguments, ::Code::Object::Function)
109
+ argument = arguments.first.value
110
+ ::Code::Object::List.new(
111
+ raw.map do |element|
112
+ argument.call(
113
+ arguments: [::Code::Object::Argument.new(element)],
114
+ context: context,
115
+ io: io,
116
+ )
117
+ end,
118
+ )
119
+ end
120
+
121
+ def step(arguments)
122
+ sig(arguments, ::Code::Object::Number)
123
+ argument = arguments.first.value
124
+
125
+ list = ::Code::Object::List.new
126
+ element = @left
127
+ list << element
128
+
129
+ if @exlucde_end
130
+ while (element = element + argument) < @right
131
+ list << element
132
+ end
133
+ else
134
+ while (element = element + argument) <= @right
135
+ list << element
136
+ end
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,130 @@
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
+ other.respond_to?(:raw) ? raw <=> other.raw : raw <=> other
49
+ else
50
+ other <=> self
51
+ end
52
+ end
53
+
54
+ def ==(other)
55
+ if respond_to?(:raw)
56
+ other.respond_to?(:raw) ? raw == other.raw : raw == other
57
+ else
58
+ other == self
59
+ end
60
+ end
61
+ alias_method :eql?, :==
62
+
63
+ def hash
64
+ if respond_to?(:raw)
65
+ [self.class, raw].hash
66
+ else
67
+ raise NotImplementedError
68
+ end
5
69
  end
6
70
 
7
71
  def to_s
8
72
  raise NotImplementedError
9
73
  end
74
+
75
+ private
76
+
77
+ def sig(actual_arguments, *expected_arguments)
78
+ if actual_arguments.size != expected_arguments.size
79
+ raise ::Code::Error::ArgumentError.new(
80
+ "Expected #{expected_arguments.size} arguments, " \
81
+ "got #{actual_arguments.size} arguments",
82
+ )
83
+ end
84
+
85
+ expected_arguments.each.with_index do |expected_argument, index|
86
+ actual_argument = actual_arguments[index].value
87
+
88
+ if expected_argument.is_a?(Array)
89
+ if expected_argument.none? { |expected_arg|
90
+ actual_argument.is_a?(expected_arg)
91
+ }
92
+ raise ::Code::Error::TypeError.new(
93
+ "Expected #{expected_argument}, got #{actual_argument.class}",
94
+ )
95
+ end
96
+ else
97
+ if !actual_argument.is_a?(expected_argument)
98
+ raise ::Code::Error::TypeError.new(
99
+ "Expected #{expected_argument}, got #{actual_argument.class}",
100
+ )
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ def comparaison(operator, arguments)
107
+ sig(arguments, ::Code::Object)
108
+ other = arguments.first.value
109
+ ::Code::Object::Boolean.new(public_send(operator, other))
110
+ end
111
+
112
+ def compare(arguments)
113
+ sig(arguments, ::Code::Object)
114
+ other = arguments.first.value
115
+ ::Code::Object::Integer.new(self <=> other)
116
+ end
117
+
118
+ def and_operator(arguments)
119
+ sig(arguments, ::Code::Object)
120
+ other = arguments.first.value
121
+ truthy? ? other : self
122
+ end
123
+
124
+ def or_operator(arguments)
125
+ sig(arguments, ::Code::Object)
126
+ other = arguments.first.value
127
+ truthy? ? self : other
128
+ end
10
129
  end
11
130
  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