language-ruby 0.5.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 (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