language-ruby 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (187) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +9 -0
  3. data/.github/workflows/rspec.yml +14 -0
  4. data/.gitignore +2 -0
  5. data/.prettierrc +3 -0
  6. data/.rspec +1 -0
  7. data/CHANGELOG.md +55 -0
  8. data/Gemfile +8 -0
  9. data/Gemfile.lock +48 -0
  10. data/LICENSE +7 -0
  11. data/README.md +103 -0
  12. data/TODO +17 -0
  13. data/bin/code +76 -0
  14. data/bin/format +3 -0
  15. data/bin/template +85 -0
  16. data/bin/test +17 -0
  17. data/code-ruby.gemspec +17 -0
  18. data/docs/class.code +9 -0
  19. data/docs/euler/1.template +10 -0
  20. data/docs/euler/2.template +16 -0
  21. data/docs/euler/3.template +16 -0
  22. data/docs/euler/4.template +10 -0
  23. data/docs/euler/5.template +13 -0
  24. data/docs/fibonnaci.template +14 -0
  25. data/docs/meetup.code +12 -0
  26. data/docs/precedence.template +36 -0
  27. data/docs/rain.code +22 -0
  28. data/docs/slack.code +17 -0
  29. data/docs/stripe.code +7 -0
  30. data/docs/twitter.code +9 -0
  31. data/language-ruby.gemspec +18 -0
  32. data/lib/code/error.rb +18 -0
  33. data/lib/code/node/base_10.rb +29 -0
  34. data/lib/code/node/base_16.rb +13 -0
  35. data/lib/code/node/base_2.rb +13 -0
  36. data/lib/code/node/base_8.rb +13 -0
  37. data/lib/code/node/boolean.rb +22 -0
  38. data/lib/code/node/call.rb +47 -0
  39. data/lib/code/node/call_argument.rb +21 -0
  40. data/lib/code/node/chained_call.rb +23 -0
  41. data/lib/code/node/code.rb +20 -0
  42. data/lib/code/node/decimal.rb +26 -0
  43. data/lib/code/node/dictionnary.rb +33 -0
  44. data/lib/code/node/equal.rb +34 -0
  45. data/lib/code/node/function.rb +20 -0
  46. data/lib/code/node/function_parameter.rb +31 -0
  47. data/lib/code/node/if.rb +59 -0
  48. data/lib/code/node/if_modifier.rb +47 -0
  49. data/lib/code/node/list.rb +16 -0
  50. data/lib/code/node/negation.rb +15 -0
  51. data/lib/code/node/not.rb +15 -0
  52. data/lib/code/node/nothing.rb +12 -0
  53. data/lib/code/node/number.rb +25 -0
  54. data/lib/code/node/operation.rb +38 -0
  55. data/lib/code/node/power.rb +20 -0
  56. data/lib/code/node/rescue.rb +17 -0
  57. data/lib/code/node/splat.rb +15 -0
  58. data/lib/code/node/statement.rb +59 -0
  59. data/lib/code/node/string.rb +53 -0
  60. data/lib/code/node/ternary.rb +24 -0
  61. data/lib/code/node/unary_minus.rb +15 -0
  62. data/lib/code/node/while.rb +35 -0
  63. data/lib/code/node.rb +13 -0
  64. data/lib/code/object/argument.rb +32 -0
  65. data/lib/code/object/boolean.rb +27 -0
  66. data/lib/code/object/decimal.rb +162 -0
  67. data/lib/code/object/dictionnary.rb +96 -0
  68. data/lib/code/object/function.rb +64 -0
  69. data/lib/code/object/global.rb +42 -0
  70. data/lib/code/object/integer.rb +221 -0
  71. data/lib/code/object/list.rb +200 -0
  72. data/lib/code/object/nothing.rb +23 -0
  73. data/lib/code/object/number.rb +6 -0
  74. data/lib/code/object/range.rb +146 -0
  75. data/lib/code/object/ruby_function.rb +31 -0
  76. data/lib/code/object/string.rb +88 -0
  77. data/lib/code/object.rb +197 -0
  78. data/lib/code/parser/addition.rb +21 -0
  79. data/lib/code/parser/and_operator.rb +17 -0
  80. data/lib/code/parser/bitwise_and.rb +17 -0
  81. data/lib/code/parser/bitwise_or.rb +21 -0
  82. data/lib/code/parser/boolean.rb +17 -0
  83. data/lib/code/parser/call.rb +122 -0
  84. data/lib/code/parser/chained_call.rb +47 -0
  85. data/lib/code/parser/class.rb +45 -0
  86. data/lib/code/parser/code.rb +25 -0
  87. data/lib/code/parser/dictionnary.rb +67 -0
  88. data/lib/code/parser/equal.rb +94 -0
  89. data/lib/code/parser/equality.rb +35 -0
  90. data/lib/code/parser/equality_lower.rb +9 -0
  91. data/lib/code/parser/function.rb +85 -0
  92. data/lib/code/parser/greater.rb +25 -0
  93. data/lib/code/parser/group.rb +22 -0
  94. data/lib/code/parser/if.rb +63 -0
  95. data/lib/code/parser/if_modifier.rb +55 -0
  96. data/lib/code/parser/list.rb +42 -0
  97. data/lib/code/parser/multiplication.rb +25 -0
  98. data/lib/code/parser/name.rb +101 -0
  99. data/lib/code/parser/negation.rb +30 -0
  100. data/lib/code/parser/not_keyword.rb +23 -0
  101. data/lib/code/parser/nothing.rb +22 -0
  102. data/lib/code/parser/number.rb +154 -0
  103. data/lib/code/parser/operation.rb +35 -0
  104. data/lib/code/parser/or_keyword.rb +21 -0
  105. data/lib/code/parser/or_operator.rb +17 -0
  106. data/lib/code/parser/power.rb +43 -0
  107. data/lib/code/parser/range.rb +17 -0
  108. data/lib/code/parser/rescue.rb +39 -0
  109. data/lib/code/parser/shift.rb +21 -0
  110. data/lib/code/parser/splat.rb +31 -0
  111. data/lib/code/parser/statement.rb +9 -0
  112. data/lib/code/parser/string.rb +78 -0
  113. data/lib/code/parser/ternary.rb +46 -0
  114. data/lib/code/parser/unary_minus.rb +31 -0
  115. data/lib/code/parser/while.rb +36 -0
  116. data/lib/code/parser/whitespace.rb +49 -0
  117. data/lib/code/parser.rb +19 -0
  118. data/lib/code/ruby.rb +162 -0
  119. data/lib/code-ruby.rb +10 -0
  120. data/lib/code.rb +47 -0
  121. data/lib/language/atom.rb +343 -0
  122. data/lib/language/output.rb +130 -0
  123. data/lib/language/parser/absent/present.rb +8 -0
  124. data/lib/language/parser/absent.rb +6 -0
  125. data/lib/language/parser/end_of_input.rb +6 -0
  126. data/lib/language/parser/interuption.rb +38 -0
  127. data/lib/language/parser/not_end_of_input.rb +6 -0
  128. data/lib/language/parser/str/not_found.rb +16 -0
  129. data/lib/language/parser/str.rb +6 -0
  130. data/lib/language/parser.rb +53 -0
  131. data/lib/language-ruby.rb +10 -0
  132. data/lib/language.rb +80 -0
  133. data/lib/template/node/code_part.rb +13 -0
  134. data/lib/template/node/part.rb +19 -0
  135. data/lib/template/node/template.rb +15 -0
  136. data/lib/template/node/text_part.rb +13 -0
  137. data/lib/template/node.rb +4 -0
  138. data/lib/template/parser/template.rb +39 -0
  139. data/lib/template/parser.rb +19 -0
  140. data/lib/template/version.rb +3 -0
  141. data/lib/template-ruby.rb +10 -0
  142. data/lib/template.rb +50 -0
  143. data/spec/code/addition_spec.rb +13 -0
  144. data/spec/code/and_operator_spec.rb +13 -0
  145. data/spec/code/bitwise_and_spec.rb +13 -0
  146. data/spec/code/bitwise_or_spec.rb +13 -0
  147. data/spec/code/boolean_spec.rb +13 -0
  148. data/spec/code/call_spec.rb +21 -0
  149. data/spec/code/chained_call_spec.rb +16 -0
  150. data/spec/code/dictionnary_spec.rb +17 -0
  151. data/spec/code/equal_spec.rb +26 -0
  152. data/spec/code/equality_spec.rb +13 -0
  153. data/spec/code/function_spec.rb +18 -0
  154. data/spec/code/greater_spec.rb +18 -0
  155. data/spec/code/group_spec.rb +12 -0
  156. data/spec/code/if_modifier_spec.rb +20 -0
  157. data/spec/code/if_spec.rb +25 -0
  158. data/spec/code/list_spec.rb +17 -0
  159. data/spec/code/multiplication_spec.rb +18 -0
  160. data/spec/code/negation_spec.rb +20 -0
  161. data/spec/code/not_keyword_spec.rb +13 -0
  162. data/spec/code/nothing_spec.rb +17 -0
  163. data/spec/code/number_spec.rb +22 -0
  164. data/spec/code/or_keyword_spec.rb +17 -0
  165. data/spec/code/or_operator_spec.rb +16 -0
  166. data/spec/code/parser/boolean_spec.rb +16 -0
  167. data/spec/code/parser/call_spec.rb +26 -0
  168. data/spec/code/parser/chained_call.rb +17 -0
  169. data/spec/code/parser/dictionnary_spec.rb +18 -0
  170. data/spec/code/parser/function_spec.rb +16 -0
  171. data/spec/code/parser/group_spec.rb +18 -0
  172. data/spec/code/parser/list_spec.rb +18 -0
  173. data/spec/code/parser/number_spec.rb +12 -0
  174. data/spec/code/parser/string_spec.rb +21 -0
  175. data/spec/code/parser_spec.rb +23 -0
  176. data/spec/code/power_spec.rb +13 -0
  177. data/spec/code/range_spec.rb +16 -0
  178. data/spec/code/rescue_spec.rb +13 -0
  179. data/spec/code/shift_spec.rb +13 -0
  180. data/spec/code/splat_spec.rb +13 -0
  181. data/spec/code/string_spec.rb +25 -0
  182. data/spec/code/ternary_spec.rb +18 -0
  183. data/spec/code/unary_minus_spec.rb +13 -0
  184. data/spec/code/while_spec.rb +18 -0
  185. data/spec/spec_helper.rb +6 -0
  186. data/template-ruby.gemspec +19 -0
  187. metadata +284 -0
@@ -0,0 +1,197 @@
1
+ class Code
2
+ class Object
3
+ include Comparable
4
+
5
+ def call(**args)
6
+ operator = args.fetch(:operator, nil)
7
+ arguments = args.fetch(:arguments, [])
8
+ value = arguments.first&.value
9
+
10
+ if operator == "=="
11
+ sig(arguments) { ::Code::Object }
12
+ equal(value)
13
+ elsif operator == "==="
14
+ sig(arguments) { ::Code::Object }
15
+ strict_equal(value)
16
+ elsif operator == "!="
17
+ sig(arguments) { ::Code::Object }
18
+ different(value)
19
+ elsif operator == "<=>"
20
+ sig(arguments) { ::Code::Object }
21
+ compare(value)
22
+ elsif operator == "&&" || operator == "and"
23
+ sig(arguments) { ::Code::Object }
24
+ and_operator(value)
25
+ elsif operator == "||" || operator == "or"
26
+ sig(arguments) { ::Code::Object }
27
+ or_operator(value)
28
+ elsif operator == "!" || operator == "not"
29
+ sig(arguments)
30
+ exclamation_point
31
+ elsif operator == "+"
32
+ sig(arguments)
33
+ self
34
+ elsif operator == ".."
35
+ sig(arguments) { ::Code::Object }
36
+ inclusive_range(value)
37
+ elsif operator == "..."
38
+ sig(arguments) { ::Code::Object }
39
+ exclusive_range(value)
40
+ elsif operator == "to_string"
41
+ sig(arguments)
42
+ to_string
43
+ else
44
+ raise(
45
+ Code::Error::Undefined.new("#{operator} not defined on #{inspect}")
46
+ )
47
+ end
48
+ end
49
+
50
+ def truthy?
51
+ true
52
+ end
53
+
54
+ def falsy?
55
+ !truthy?
56
+ end
57
+
58
+ def <=>(other)
59
+ if respond_to?(:raw)
60
+ other.respond_to?(:raw) ? raw <=> other.raw : raw <=> other
61
+ else
62
+ other <=> self
63
+ end
64
+ end
65
+
66
+ def ==(other)
67
+ if respond_to?(:raw)
68
+ other.respond_to?(:raw) ? raw == other.raw : raw == other
69
+ else
70
+ other == self
71
+ end
72
+ end
73
+ alias_method :eql?, :==
74
+
75
+ def hash
76
+ if respond_to?(:raw)
77
+ [self.class, raw].hash
78
+ else
79
+ raise NotImplementedError.new(self.class.name)
80
+ end
81
+ end
82
+
83
+ def to_s
84
+ raise NotImplementedError.new(self.class.name)
85
+ end
86
+
87
+ private
88
+
89
+ def multi_fetch(hash, *keys)
90
+ keys.map { |key| [key, hash.fetch(key)] }.to_h
91
+ end
92
+
93
+ def deep_dup(object)
94
+ if object.is_a?(Array)
95
+ object.map { |element| deep_dup(o) }
96
+ elsif object.is_a?(Hash)
97
+ object.map { |key, value| [deep_dup(key), deep_dup(value)] }.to_h
98
+ elsif object.is_a?(::Code::Object::List)
99
+ ::Code::Object::List.new(object.raw.map { |element| deep_dup(o) })
100
+ elsif object.is_a?(::Code::Object::Dictionnary)
101
+ ::Code::Object::Dictionnary.new(
102
+ object.raw.map { |key, value| [deep_dup(key), deep_dup(value)] }.to_h
103
+ )
104
+ else
105
+ object.dup
106
+ end
107
+ end
108
+
109
+ def sig(actual_arguments, &block)
110
+ if block
111
+ expected_arguments = block.call
112
+ expected_arguments = [
113
+ expected_arguments
114
+ ] unless expected_arguments.is_a?(Array)
115
+ else
116
+ expected_arguments = []
117
+ end
118
+
119
+ if actual_arguments.size != expected_arguments.size
120
+ raise(
121
+ ::Code::Error::ArgumentError.new(
122
+ "Expected #{expected_arguments.size} arguments, " \
123
+ "got #{actual_arguments.size} arguments"
124
+ )
125
+ )
126
+ end
127
+
128
+ expected_arguments.each.with_index do |expected_argument, index|
129
+ actual_argument = actual_arguments[index].value
130
+
131
+ if expected_argument.is_a?(Array)
132
+ if expected_argument.none? { |expected_arg|
133
+ actual_argument.is_a?(expected_arg)
134
+ }
135
+ raise(
136
+ ::Code::Error::TypeError.new(
137
+ "Expected #{expected_argument}, got #{actual_argument.class}"
138
+ )
139
+ )
140
+ end
141
+ else
142
+ if !actual_argument.is_a?(expected_argument)
143
+ raise(
144
+ ::Code::Error::TypeError.new(
145
+ "Expected #{expected_argument}, got #{actual_argument.class}"
146
+ )
147
+ )
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ def equal(other)
154
+ ::Code::Object::Boolean.new(self == other)
155
+ end
156
+
157
+ def strict_equal(other)
158
+ ::Code::Object::Boolean.new(self === other)
159
+ end
160
+
161
+ def different(other)
162
+ ::Code::Object::Boolean.new(self != other)
163
+ end
164
+
165
+ def compare(other)
166
+ ::Code::Object::Integer.new(self <=> other)
167
+ end
168
+
169
+ def and_operator(other)
170
+ truthy? ? other : self
171
+ end
172
+
173
+ def or_operator(other)
174
+ truthy? ? self : other
175
+ end
176
+
177
+ def to_string
178
+ ::Code::Object::String.new(to_s)
179
+ end
180
+
181
+ def inclusive_range(value)
182
+ ::Code::Object::Range.new(self, value, exclude_end: false)
183
+ end
184
+
185
+ def exclusive_range(value)
186
+ ::Code::Object::Range.new(self, value, exclude_end: true)
187
+ end
188
+
189
+ def exclamation_point
190
+ if truthy?
191
+ ::Code::Object::Boolean.new(false)
192
+ else
193
+ ::Code::Object::Boolean.new(true)
194
+ end
195
+ end
196
+ end
197
+ end
@@ -0,0 +1,21 @@
1
+ class Code
2
+ class Parser
3
+ class Addition < Operation
4
+ def statement
5
+ ::Code::Parser::Multiplication
6
+ end
7
+
8
+ def plus
9
+ str("+")
10
+ end
11
+
12
+ def minus
13
+ str("-")
14
+ end
15
+
16
+ def operator
17
+ plus | minus
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ class Code
2
+ class Parser
3
+ class AndOperator < Operation
4
+ def statement
5
+ ::Code::Parser::EqualityLower
6
+ end
7
+
8
+ def ampersand
9
+ str("&")
10
+ end
11
+
12
+ def operator
13
+ ampersand << ampersand
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ class Code
2
+ class Parser
3
+ class BitwiseAnd < Operation
4
+ def statement
5
+ ::Code::Parser::Shift
6
+ end
7
+
8
+ def ampersand
9
+ str("&")
10
+ end
11
+
12
+ def operator
13
+ ampersand
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ class Code
2
+ class Parser
3
+ class BitwiseOr < Operation
4
+ def statement
5
+ ::Code::Parser::BitwiseAnd
6
+ end
7
+
8
+ def pipe
9
+ str("|")
10
+ end
11
+
12
+ def caret
13
+ str("^")
14
+ end
15
+
16
+ def operator
17
+ pipe | caret
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ class Code
2
+ class Parser
3
+ class Boolean < Language
4
+ def true_keyword
5
+ str("true")
6
+ end
7
+
8
+ def false_keyword
9
+ str("false")
10
+ end
11
+
12
+ def root
13
+ (true_keyword | false_keyword).aka(:boolean) | ::Code::Parser::Nothing
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,122 @@
1
+ class Code
2
+ class Parser
3
+ class Call < Language
4
+ def name
5
+ ::Code::Parser::Name
6
+ end
7
+
8
+ def whitespace
9
+ ::Code::Parser::Whitespace
10
+ end
11
+
12
+ def whitespace?
13
+ whitespace.maybe
14
+ end
15
+
16
+ def code
17
+ ::Code::Parser::Code
18
+ end
19
+
20
+ def code_present
21
+ ::Code::Parser::Code.new.present
22
+ end
23
+
24
+ def colon
25
+ str(":")
26
+ end
27
+
28
+ def comma
29
+ str(",")
30
+ end
31
+
32
+ def pipe
33
+ str("|")
34
+ end
35
+
36
+ def equal
37
+ str("=")
38
+ end
39
+
40
+ def opening_curly_bracket
41
+ str("{")
42
+ end
43
+
44
+ def closing_curly_bracket
45
+ str("}")
46
+ end
47
+
48
+ def opening_parenthesis
49
+ str("(")
50
+ end
51
+
52
+ def closing_parenthesis
53
+ str(")")
54
+ end
55
+
56
+ def do_keyword
57
+ str("do")
58
+ end
59
+
60
+ def end_keyword
61
+ str("end")
62
+ end
63
+
64
+ def keyword_argument
65
+ name.aka(:name) << colon << code_present.aka(:value)
66
+ end
67
+
68
+ def regular_argument
69
+ code_present.aka(:value)
70
+ end
71
+
72
+ def argument
73
+ keyword_argument | regular_argument
74
+ end
75
+
76
+ def arguments
77
+ opening_parenthesis.ignore << whitespace? << argument.repeat(0, 1) <<
78
+ (comma << whitespace? << argument << whitespace?).repeat <<
79
+ whitespace? << closing_parenthesis.ignore.maybe
80
+ end
81
+
82
+ def keyword_parameter
83
+ name.aka(:name) << whitespace? << colon.aka(:keyword) <<
84
+ code_present.aka(:default).maybe
85
+ end
86
+
87
+ def regular_parameter
88
+ name.aka(:name) << whitespace? <<
89
+ (equal << whitespace? << code_present.aka(:default)).maybe
90
+ end
91
+
92
+ def parameter
93
+ keyword_parameter | regular_parameter
94
+ end
95
+
96
+ def parameters
97
+ pipe.ignore << whitespace? << parameter.repeat(0, 1) <<
98
+ (whitespace? << comma << whitespace? << parameter).repeat <<
99
+ whitespace? << pipe.ignore.maybe
100
+ end
101
+
102
+ def block
103
+ (
104
+ do_keyword << whitespace? << parameters.aka(:parameters).maybe <<
105
+ code.aka(:body) << end_keyword.maybe
106
+ ) |
107
+ (
108
+ opening_curly_bracket << whitespace? <<
109
+ parameters.aka(:parameters).maybe << code.aka(:body) <<
110
+ closing_curly_bracket.maybe
111
+ )
112
+ end
113
+
114
+ def root
115
+ (
116
+ name.aka(:name) << (whitespace? << arguments.aka(:arguments)).maybe <<
117
+ (whitespace? << block.aka(:block)).maybe
118
+ ).aka(:call)
119
+ end
120
+ end
121
+ end
122
+ end
@@ -0,0 +1,47 @@
1
+ class Code
2
+ class Parser
3
+ class ChainedCall < Operation
4
+ def statement
5
+ ::Code::Parser::Dictionnary
6
+ end
7
+
8
+ def whitespace
9
+ ::Code::Parser::Whitespace
10
+ end
11
+
12
+ def whitespace?
13
+ whitespace.maybe
14
+ end
15
+
16
+ def dot
17
+ str(".")
18
+ end
19
+
20
+ def colon
21
+ str(":")
22
+ end
23
+
24
+ def operator
25
+ dot | (colon << colon)
26
+ end
27
+
28
+ def root
29
+ (
30
+ statement.aka(:first) <<
31
+ (whitespace? << operator << whitespace? << statement)
32
+ .repeat(1)
33
+ .aka(:others)
34
+ .maybe
35
+ )
36
+ .aka(:chained_call)
37
+ .then do |output|
38
+ if output[:chained_call][:others]
39
+ output
40
+ else
41
+ output[:chained_call][:first]
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,45 @@
1
+ class Code
2
+ class Parser
3
+ class Class < Language
4
+ def statement
5
+ ::Code::Parser::While
6
+ end
7
+
8
+ def name
9
+ ::Code::Parser::Name
10
+ end
11
+
12
+ def code
13
+ ::Code::Parser::Code
14
+ end
15
+
16
+ def whitespace
17
+ ::Code::Parser::Whitespace
18
+ end
19
+
20
+ def whitespace?
21
+ whitespace.maybe
22
+ end
23
+
24
+ def class_keyword
25
+ str("class")
26
+ end
27
+
28
+ def end_keyword
29
+ str("end")
30
+ end
31
+
32
+ def lesser
33
+ str("<")
34
+ end
35
+
36
+ def root
37
+ (
38
+ class_keyword << whitespace? << name.aka(:name) <<
39
+ (whitespace? << lesser << name.aka(:superclass)).maybe <<
40
+ code.aka(:body) << end_keyword.maybe
41
+ ).aka(:class) | statement
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,25 @@
1
+ class Code
2
+ class Parser
3
+ class Code < Language
4
+ def whitespace
5
+ ::Code::Parser::Whitespace
6
+ end
7
+
8
+ def whitespace?(&block)
9
+ whitespace.maybe(&block)
10
+ end
11
+
12
+ def statement
13
+ ::Code::Parser::Statement
14
+ end
15
+
16
+ def present
17
+ (whitespace? << statement << whitespace?).repeat(1)
18
+ end
19
+
20
+ def root
21
+ present | whitespace?.then { [] }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,67 @@
1
+ class Code
2
+ class Parser
3
+ class Dictionnary < Language
4
+ def code
5
+ ::Code::Parser::Code.new.present
6
+ end
7
+
8
+ def statement
9
+ ::Code::Parser::Statement
10
+ end
11
+
12
+ def name
13
+ ::Code::Parser::Name
14
+ end
15
+
16
+ def whitespace
17
+ ::Code::Parser::Whitespace
18
+ end
19
+
20
+ def whitespace?
21
+ whitespace.maybe
22
+ end
23
+
24
+ def opening_curly_bracket
25
+ str("{")
26
+ end
27
+
28
+ def closing_curly_bracket
29
+ str("}")
30
+ end
31
+
32
+ def comma
33
+ str(",")
34
+ end
35
+
36
+ def colon
37
+ str(":")
38
+ end
39
+
40
+ def equal
41
+ str("=")
42
+ end
43
+
44
+ def greater
45
+ str(">")
46
+ end
47
+
48
+ def key_value
49
+ (name.aka(:name) << colon << code.aka(:value)) |
50
+ (statement.aka(:statement) << colon << code.aka(:value)) |
51
+ (
52
+ statement.aka(:statement) << whitespace? << equal << greater <<
53
+ code.aka(:value)
54
+ )
55
+ end
56
+
57
+ def root
58
+ (
59
+ opening_curly_bracket.ignore << whitespace? <<
60
+ key_value.repeat(0, 1) <<
61
+ (whitespace? << comma << whitespace? << key_value).repeat <<
62
+ (whitespace? << closing_curly_bracket.ignore).maybe
63
+ ).aka(:dictionnary) | ::Code::Parser::List
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,94 @@
1
+ class Code
2
+ class Parser
3
+ class Equal < Language
4
+ def statement
5
+ ::Code::Parser::Rescue
6
+ end
7
+
8
+ def name
9
+ ::Code::Parser::Name
10
+ end
11
+
12
+ def equal_class
13
+ ::Code::Parser::Equal
14
+ end
15
+
16
+ def whitespace
17
+ ::Code::Parser::Whitespace
18
+ end
19
+
20
+ def whitespace?
21
+ whitespace.maybe
22
+ end
23
+
24
+ def equal
25
+ str("=")
26
+ end
27
+
28
+ def plus
29
+ str("+")
30
+ end
31
+
32
+ def minus
33
+ str("-")
34
+ end
35
+
36
+ def asterisk
37
+ str("*")
38
+ end
39
+
40
+ def slash
41
+ str("/")
42
+ end
43
+
44
+ def percent
45
+ str("%")
46
+ end
47
+
48
+ def greater
49
+ str(">")
50
+ end
51
+
52
+ def lesser
53
+ str("<")
54
+ end
55
+
56
+ def ampersand
57
+ str("&")
58
+ end
59
+
60
+ def pipe
61
+ str("|")
62
+ end
63
+
64
+ def caret
65
+ str("^")
66
+ end
67
+
68
+ def dot
69
+ str(".")
70
+ end
71
+
72
+ def operator
73
+ equal.ignore | (plus << equal.ignore) | (minus << equal.ignore) |
74
+ (asterisk << equal.ignore) | (slash << equal.ignore) |
75
+ (percent << equal.ignore) | (greater << greater << equal.ignore) |
76
+ (lesser << lesser << equal.ignore) | (ampersand << equal.ignore) |
77
+ (pipe << equal.ignore) | (caret << equal.ignore) |
78
+ (pipe << pipe << equal.ignore) |
79
+ (ampersand << ampersand << equal.ignore)
80
+ end
81
+
82
+ def names
83
+ name << (dot << name).repeat
84
+ end
85
+
86
+ def root
87
+ (
88
+ names.aka(:left) << whitespace? << operator.aka(:operator) <<
89
+ whitespace? << equal_class.aka(:right)
90
+ ).aka(:equal) | statement
91
+ end
92
+ end
93
+ end
94
+ end