riml 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/bin/riml CHANGED
@@ -60,7 +60,7 @@ module Riml
60
60
  options.output_dir = dir
61
61
  end
62
62
 
63
- opts.on("-d", "--condensed", "Compiled VimL contains no extraneous newlines") do
63
+ opts.on("-d", "--condensed", "Omit readability improvements such as blank lines.") do
64
64
  options.readable = false
65
65
  end
66
66
 
@@ -91,6 +91,7 @@ module Riml
91
91
  def self.append_filenames_to_list_if_valid(list, *filenames)
92
92
  filenames.each do |fname|
93
93
  expanded = File.expand_path(fname)
94
+ readable = true
94
95
  if File.exists?(expanded) && (readable = File.readable?(expanded))
95
96
  list << fname
96
97
  elsif not readable
@@ -117,7 +118,7 @@ module Riml
117
118
  elsif options.compile_files.any?
118
119
  Riml.compile_files(*options.compile_files, compile_files_options)
119
120
  elsif options.check_syntax_files.any?
120
- files = options.check_syntax_files
121
+ files = options.check_syntax_files.uniq
121
122
  Riml.check_syntax_files(*files)
122
123
  size = files.size
123
124
  # "ok (1 file)" OR "ok (2 files)"
data/lib/compiler.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require File.expand_path('../nodes', __FILE__)
2
+ require File.expand_path('../errors', __FILE__)
2
3
 
3
4
  # visits AST nodes and translates them into VimL
4
5
  module Riml
@@ -42,6 +43,8 @@ module Riml
42
43
 
43
44
  def visitor_for_node(node, params={})
44
45
  Compiler.const_get("#{node.class.name.split('::').last}Visitor").new(params)
46
+ rescue NameError
47
+ raise CompileError, "unexpected construct at #{node.location_info}"
45
48
  end
46
49
 
47
50
  def root_node(node)
@@ -608,7 +611,8 @@ module Riml
608
611
  end
609
612
  node.each_existing_file! do |basename, full_path|
610
613
  riml_src = File.read(full_path)
611
- node.compiled_output << current_compiler(node).compile_include(riml_src, basename)
614
+ output = current_compiler(node).compile_include(riml_src, basename)
615
+ node.compiled_output << output if output
612
616
  end
613
617
  return node.compiled_output
614
618
  end
@@ -773,10 +777,18 @@ module Riml
773
777
  @sourced_files_compiled ||= []
774
778
  end
775
779
 
776
- def compile_include(source, from_file)
777
- root_node = parser.parse(source, parser.ast_rewriter, from_file, true)
778
- output = compile(root_node)
779
- (Riml::INCLUDE_COMMENT_FMT % from_file) + output
780
+ def included_files_compiled
781
+ @included_files_compiled ||= []
782
+ end
783
+
784
+ def compile_include(source, filename)
785
+ return if included_files_compiled.include?(filename)
786
+ Riml.include_cache.fetch(filename) do
787
+ root_node = parser.parse(source, parser.ast_rewriter, filename, true)
788
+ output = compile(root_node)
789
+ included_files_compiled << filename
790
+ (Riml::INCLUDE_COMMENT_FMT % filename) + output
791
+ end
780
792
  end
781
793
 
782
794
  # compiles nodes into output code
data/lib/constants.rb CHANGED
@@ -48,6 +48,10 @@ module Riml
48
48
  '@'
49
49
  ].flatten
50
50
 
51
+ # For when showing source location (file:lineno) during error
52
+ # and no file was given
53
+ COMPILED_STRING_LOCATION = '<String>'
54
+
51
55
  # :help function-list
52
56
  BUILTIN_FUNCTIONS =
53
57
  %w(
data/lib/grammar.y CHANGED
@@ -37,17 +37,17 @@ preclow
37
37
  rule
38
38
 
39
39
  Root:
40
- /* nothing */ { result = Riml::Nodes.new([]) }
40
+ /* nothing */ { result = make_node(val) { |_| Riml::Nodes.new([]) } }
41
41
  | Statements { result = val[0] }
42
42
  ;
43
43
 
44
44
  # any list of expressions
45
45
  Statements:
46
- Statement { result = Riml::Nodes.new([ val[0] ]) }
46
+ Statement { result = make_node(val) { |v| Riml::Nodes.new([ v[0] ]) } }
47
47
  | Statements Terminator Statement { result = val[0] << val[2] }
48
48
  | Statements Terminator { result = val[0] }
49
- | Terminator { result = Riml::Nodes.new([]) }
50
- | Terminator Statements { result = Riml::Nodes.new(val[1]) }
49
+ | Terminator { result = make_node(val) { |_| Riml::Nodes.new([]) } }
50
+ | Terminator Statements { result = make_node(val) { |v| Riml::Nodes.new(v[1]) } }
51
51
  ;
52
52
 
53
53
  # All types of expressions in Riml
@@ -74,12 +74,12 @@ rule
74
74
  Expression:
75
75
  ExpressionWithoutDictLiteral { result = val[0] }
76
76
  | Dictionary { result = val[0] }
77
- | Dictionary DictGetWithDotLiteral { result = Riml::DictGetDotNode.new(val[0], val[1]) }
77
+ | Dictionary DictGetWithDotLiteral { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } }
78
78
  | BinaryOperator { result = val[0] }
79
79
  | Ternary { result = val[0] }
80
80
  | Assign { result = val[0] }
81
81
  | Super { result = val[0] }
82
- | '(' Expression ')' { result = Riml::WrapInParensNode.new(val[1]) }
82
+ | '(' Expression ')' { result = make_node(val) { |v| Riml::WrapInParensNode.new(v[1]) } }
83
83
  ;
84
84
 
85
85
  ExpressionWithoutDictLiteral:
@@ -90,7 +90,7 @@ rule
90
90
  | LiteralWithoutDictLiteral { result = val[0] }
91
91
  | Call { result = val[0] }
92
92
  | ObjectInstantiation { result = val[0] }
93
- | '(' ExpressionWithoutDictLiteral ')' { result = Riml::WrapInParensNode.new(val[1]) }
93
+ | '(' ExpressionWithoutDictLiteral ')' { result = make_node(val) { |v| Riml::WrapInParensNode.new(v[1]) } }
94
94
  ;
95
95
 
96
96
  # for inside curly-brace variable names
@@ -115,35 +115,35 @@ rule
115
115
  | Regexp { result = val[0] }
116
116
  | List { result = val[0] }
117
117
  | ScopeModifierLiteral { result = val[0] }
118
- | TRUE { result = Riml::TrueNode.new }
119
- | FALSE { result = Riml::FalseNode.new }
118
+ | TRUE { result = make_node(val) { |_| Riml::TrueNode.new } }
119
+ | FALSE { result = make_node(val) { |_| Riml::FalseNode.new } }
120
120
  ;
121
121
 
122
122
  Number:
123
- NUMBER { result = Riml::NumberNode.new(val[0]) }
123
+ NUMBER { result = make_node(val) { |v| Riml::NumberNode.new(v[0]) } }
124
124
  ;
125
125
 
126
126
  String:
127
- STRING_S { result = Riml::StringNode.new(val[0], :s) }
128
- | STRING_D { result = Riml::StringNode.new(val[0], :d) }
129
- | String STRING_S { result = Riml::StringLiteralConcatNode.new(val[0], Riml::StringNode.new(val[1], :s)) }
130
- | String STRING_D { result = Riml::StringLiteralConcatNode.new(val[0], Riml::StringNode.new(val[1], :d)) }
127
+ STRING_S { result = make_node(val) { |v| Riml::StringNode.new(v[0], :s) } }
128
+ | STRING_D { result = make_node(val) { |v| Riml::StringNode.new(v[0], :d) } }
129
+ | String STRING_S { result = make_node(val) { |v| Riml::StringLiteralConcatNode.new(v[0], Riml::StringNode.new(v[1], :s)) } }
130
+ | String STRING_D { result = make_node(val) { |v| Riml::StringLiteralConcatNode.new(v[0], Riml::StringNode.new(v[1], :d)) } }
131
131
  ;
132
132
 
133
133
  Regexp:
134
- REGEXP { result = Riml::RegexpNode.new(val[0]) }
134
+ REGEXP { result = make_node(val) { |v| Riml::RegexpNode.new(v[0]) } }
135
135
  ;
136
136
 
137
137
  ScopeModifierLiteral:
138
- SCOPE_MODIFIER_LITERAL { result = Riml::ScopeModifierLiteralNode.new(val[0]) }
138
+ SCOPE_MODIFIER_LITERAL { result = make_node(val) { |v| Riml::ScopeModifierLiteralNode.new(v[0]) } }
139
139
  ;
140
140
 
141
141
  List:
142
- ListLiteral { result = Riml::ListNode.new(val[0]) }
142
+ ListLiteral { result = make_node(val) { |v| Riml::ListNode.new(v[0]) } }
143
143
  ;
144
144
 
145
145
  ListUnpack:
146
- '[' ListItems ';' Expression ']' { result = Riml::ListUnpackNode.new(val[1] << val[3]) }
146
+ '[' ListItems ';' Expression ']' { result = make_node(val) { |v| Riml::ListUnpackNode.new(v[1] << v[3]) } }
147
147
  ;
148
148
 
149
149
  ListLiteral:
@@ -153,12 +153,12 @@ rule
153
153
 
154
154
  ListItems:
155
155
  /* nothing */ { result = [] }
156
- | Expression { result = [val[0]] }
157
- | ListItems ',' Expression { result = val[0] << val[2] }
156
+ | Expression { result = [val[0]] }
157
+ | ListItems ',' Expression { result = val[0] << val[2] }
158
158
  ;
159
159
 
160
160
  Dictionary:
161
- DictionaryLiteral { result = Riml::DictionaryNode.new(val[0]) }
161
+ DictionaryLiteral { result = make_node(val) { |v| Riml::DictionaryNode.new(v[0]) } }
162
162
  ;
163
163
 
164
164
  # {'key': 'value', 'key': 'value'}
@@ -180,19 +180,19 @@ rule
180
180
  ;
181
181
 
182
182
  DictGet:
183
- AllVariableRetrieval DictGetWithDot { result = Riml::DictGetDotNode.new(val[0], val[1]) }
184
- | ListOrDictGet DictGetWithDot { result = Riml::DictGetDotNode.new(val[0], val[1]) }
185
- | Call DictGetWithDot { result = Riml::DictGetDotNode.new(val[0], val[1]) }
186
- | '(' Expression ')' DictGetWithDot { result = Riml::DictGetDotNode.new(Riml::WrapInParensNode.new(val[1]), val[3]) }
183
+ AllVariableRetrieval DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } }
184
+ | ListOrDictGet DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } }
185
+ | Call DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(v[0], v[1]) } }
186
+ | '(' Expression ')' DictGetWithDot { result = make_node(val) { |v| Riml::DictGetDotNode.new(Riml::WrapInParensNode.new(v[1]), v[3]) } }
187
187
  ;
188
188
 
189
189
  ListOrDictGet:
190
- ExpressionWithoutDictLiteral ListOrDictGetWithBrackets { result = Riml::ListOrDictGetNode.new(val[0], val[1]) }
191
- | '(' Expression ')' ListOrDictGetWithBrackets { result = Riml::ListOrDictGetNode.new(Riml::WrapInParensNode.new(val[1]), val[3]) }
190
+ ExpressionWithoutDictLiteral ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::ListOrDictGetNode.new(v[0], v[1]) } }
191
+ | '(' Expression ')' ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::ListOrDictGetNode.new(Riml::WrapInParensNode.new(v[1]), v[3]) } }
192
192
  ;
193
193
 
194
194
  ListOrDictGetAssign:
195
- ExpressionWithoutDictLiteral ListOrDictGetWithBrackets { result = Riml::ListOrDictGetNode.new(val[0], val[1]) }
195
+ ExpressionWithoutDictLiteral ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::ListOrDictGetNode.new(v[0], v[1]) } }
196
196
  ;
197
197
 
198
198
  ListOrDictGetWithBrackets:
@@ -203,10 +203,10 @@ rule
203
203
  ;
204
204
 
205
205
  SubList:
206
- Expression ':' Expression { result = Riml::SublistNode.new([val[0], Riml::LiteralNode.new(' : '), val[2]]) }
207
- | Expression ':' { result = Riml::SublistNode.new([val[0], Riml::LiteralNode.new(' :')]) }
208
- | ':' Expression { result = Riml::SublistNode.new([Riml::LiteralNode.new(': '), val[1]]) }
209
- | ':' { result = Riml::SublistNode.new([Riml::LiteralNode.new(':')]) }
206
+ Expression ':' Expression { result = make_node(val) { |v| Riml::SublistNode.new([v[0], Riml::LiteralNode.new(' : '), v[2]]) } }
207
+ | Expression ':' { result = make_node(val) { |v| Riml::SublistNode.new([v[0], Riml::LiteralNode.new(' :')]) } }
208
+ | ':' Expression { result = make_node(val) { |v| Riml::SublistNode.new([Riml::LiteralNode.new(': '), v[1]]) } }
209
+ | ':' { result = make_node(val) { |_| Riml::SublistNode.new([Riml::LiteralNode.new(':')]) } }
210
210
  ;
211
211
 
212
212
  DictGetWithDot:
@@ -220,27 +220,27 @@ rule
220
220
  ;
221
221
 
222
222
  Call:
223
- Scope DefCallIdentifier '(' ArgList ')' { result = Riml::CallNode.new(val[0], val[1], val[3]) }
224
- | DictGet '(' ArgList ')' { result = Riml::CallNode.new(nil, val[0], val[2]) }
225
- | BUILTIN_COMMAND '(' ArgList ')' { result = Riml::CallNode.new(nil, val[0], val[2]) }
226
- | BUILTIN_COMMAND ArgListWithoutNothing { result = Riml::CallNode.new(nil, val[0], val[1]) }
227
- | BUILTIN_COMMAND NEWLINE { result = Riml::CallNode.new(nil, val[0], []) }
228
- | CALL '(' ArgList ')' { result = Riml::ExplicitCallNode.new(nil, nil, val[2]) }
223
+ Scope DefCallIdentifier '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], v[3]) } }
224
+ | DictGet '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[2]) } }
225
+ | BUILTIN_COMMAND '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[2]) } }
226
+ | BUILTIN_COMMAND ArgListWithoutNothing { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], v[1]) } }
227
+ | BUILTIN_COMMAND NEWLINE { result = make_node(val) { |v| Riml::CallNode.new(nil, v[0], []) } }
228
+ | CALL '(' ArgList ')' { result = make_node(val) { |v| Riml::ExplicitCallNode.new(nil, nil, v[2]) } }
229
229
  ;
230
230
 
231
231
  ObjectInstantiationCall:
232
- Scope DefCallIdentifier '(' ArgList ')' { result = Riml::CallNode.new(val[0], val[1], val[3]) }
233
- | Scope DefCallIdentifier { result = Riml::CallNode.new(val[0], val[1], []) }
232
+ Scope DefCallIdentifier '(' ArgList ')' { result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], v[3]) } }
233
+ | Scope DefCallIdentifier { result = make_node(val) { |v| Riml::CallNode.new(v[0], v[1], []) } }
234
234
  ;
235
235
 
236
236
  RimlCommand:
237
- RIML_COMMAND '(' ArgList ')' { result = Riml::RimlCommandNode.new(nil, val[0], val[2]) }
238
- | RIML_COMMAND ArgList { result = Riml::RimlCommandNode.new(nil, val[0], val[1]) }
237
+ RIML_COMMAND '(' ArgList ')' { result = make_node(val) { |v| Riml::RimlCommandNode.new(nil, v[0], v[2]) } }
238
+ | RIML_COMMAND ArgList { result = make_node(val) { |v| Riml::RimlCommandNode.new(nil, v[0], v[1]) } }
239
239
  ;
240
240
 
241
241
  ExplicitCall:
242
- CALL Scope DefCallIdentifier '(' ArgList ')' { result = Riml::ExplicitCallNode.new(val[1], val[2], val[4]) }
243
- | CALL DictGet '(' ArgList ')' { result = Riml::ExplicitCallNode.new(nil, val[1], val[3]) }
242
+ CALL Scope DefCallIdentifier '(' ArgList ')' { result = make_node(val) { |v| Riml::ExplicitCallNode.new(v[1], v[2], v[4]) } }
243
+ | CALL DictGet '(' ArgList ')' { result = make_node(val) { |v| Riml::ExplicitCallNode.new(nil, v[1], v[3]) } }
244
244
  ;
245
245
 
246
246
  Scope:
@@ -251,7 +251,7 @@ rule
251
251
  # [SID, scope_modifier]
252
252
  SIDAndScope:
253
253
  Scope { result = [ nil, val[0] ] }
254
- | '<' IDENTIFIER '>' Scope { result = [ Riml::SIDNode.new(val[1]), val[3] ] }
254
+ | '<' IDENTIFIER '>' Scope { result = [ make_node(val) { |v| Riml::SIDNode.new(v[1]) }, val[3] ] }
255
255
  ;
256
256
 
257
257
  ArgList:
@@ -265,70 +265,70 @@ rule
265
265
  ;
266
266
 
267
267
  BinaryOperator:
268
- Expression '||' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
269
- | Expression '&&' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
268
+ Expression '||' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
269
+ | Expression '&&' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
270
270
 
271
- | Expression '==' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
272
- | Expression '==#' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
273
- | Expression '==?' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
271
+ | Expression '==' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
272
+ | Expression '==#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
273
+ | Expression '==?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
274
274
 
275
275
  # added by riml
276
- | Expression '===' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
276
+ | Expression '===' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
277
277
 
278
- | Expression '!=' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
279
- | Expression '!=#' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
280
- | Expression '!=?' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
278
+ | Expression '!=' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
279
+ | Expression '!=#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
280
+ | Expression '!=?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
281
281
 
282
- | Expression '=~' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
283
- | Expression '=~#' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
284
- | Expression '=~?' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
282
+ | Expression '=~' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
283
+ | Expression '=~#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
284
+ | Expression '=~?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
285
285
 
286
- | Expression '!~' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
287
- | Expression '!~#' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
288
- | Expression '!~?' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
286
+ | Expression '!~' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
287
+ | Expression '!~#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
288
+ | Expression '!~?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
289
289
 
290
- | Expression '>' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
291
- | Expression '>#' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
292
- | Expression '>?' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
290
+ | Expression '>' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
291
+ | Expression '>#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
292
+ | Expression '>?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
293
293
 
294
- | Expression '>=' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
295
- | Expression '>=#' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
296
- | Expression '>=?' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
294
+ | Expression '>=' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
295
+ | Expression '>=#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
296
+ | Expression '>=?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
297
297
 
298
- | Expression '<' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
299
- | Expression '<#' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
300
- | Expression '<?' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
298
+ | Expression '<' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
299
+ | Expression '<#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
300
+ | Expression '<?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
301
301
 
302
- | Expression '<=' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
303
- | Expression '<=#' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
304
- | Expression '<=?' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
302
+ | Expression '<=' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
303
+ | Expression '<=#' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
304
+ | Expression '<=?' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
305
305
 
306
- | Expression '+' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
307
- | Expression '-' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
308
- | Expression '*' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
309
- | Expression '/' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
310
- | Expression '.' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
311
- | Expression '%' Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
306
+ | Expression '+' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
307
+ | Expression '-' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
308
+ | Expression '*' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
309
+ | Expression '/' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
310
+ | Expression '.' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
311
+ | Expression '%' Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
312
312
 
313
- | Expression IS Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
314
- | Expression ISNOT Expression { result = Riml::BinaryOperatorNode.new(val[1], [val[0], val[2]]) }
313
+ | Expression IS Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
314
+ | Expression ISNOT Expression { result = make_node(val) { |v| Riml::BinaryOperatorNode.new(v[1], [v[0], v[2]]) } }
315
315
  ;
316
316
 
317
317
  UnaryOperator:
318
- '!' Expression { result = Riml::UnaryOperatorNode.new(val[0], [val[1]]) }
319
- | '+' Expression { result = Riml::UnaryOperatorNode.new(val[0], [val[1]]) }
320
- | '-' Expression { result = Riml::UnaryOperatorNode.new(val[0], [val[1]]) }
318
+ '!' Expression { result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) } }
319
+ | '+' Expression { result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) } }
320
+ | '-' Expression { result = make_node(val) { |v| Riml::UnaryOperatorNode.new(val[0], [val[1]]) } }
321
321
  ;
322
322
 
323
323
  # ['=', LHS, RHS]
324
324
  Assign:
325
- LET AssignExpression { result = Riml::AssignNode.new(val[1][0], val[1][1], val[1][2]) }
326
- | AssignExpression { result = Riml::AssignNode.new(val[0][0], val[0][1], val[0][2]) }
325
+ LET AssignExpression { result = make_node(val) { |v| Riml::AssignNode.new(v[1][0], v[1][1], v[1][2]) } }
326
+ | AssignExpression { result = make_node(val) { |v| Riml::AssignNode.new(v[0][0], v[0][1], v[0][2]) } }
327
327
  ;
328
328
 
329
329
  MultiAssign:
330
- Assign ',' Assign { result = Riml::MultiAssignNode.new([val[0], val[2]]) }
331
- | MultiAssign ',' Assign { val[0].assigns << val[2]; result = val[0] }
330
+ Assign ',' Assign { result = make_node(val) { |v| Riml::MultiAssignNode.new([v[0], v[2]]) } }
331
+ | MultiAssign ',' Assign { val[0].assigns << val[2]; result = val[0] }
332
332
  ;
333
333
 
334
334
  # ['=', AssignLHS, Expression]
@@ -340,51 +340,51 @@ rule
340
340
  ;
341
341
 
342
342
  AssignLHS:
343
- AllVariableRetrieval { result = val[0] }
344
- | List { result = val[0] }
345
- | ListUnpack { result = val[0] }
346
- | DictGet { result = val[0] }
347
- | ListOrDictGetAssign { result = val[0] }
343
+ AllVariableRetrieval { result = val[0] }
344
+ | List { result = val[0] }
345
+ | ListUnpack { result = val[0] }
346
+ | DictGet { result = val[0] }
347
+ | ListOrDictGetAssign { result = val[0] }
348
348
  ;
349
349
 
350
350
  # retrieving the value of a variable
351
351
  VariableRetrieval:
352
- Scope IDENTIFIER { result = Riml::GetVariableNode.new(val[0], val[1]) }
353
- | SPECIAL_VAR_PREFIX IDENTIFIER { result = Riml::GetSpecialVariableNode.new(val[0], val[1]) }
354
- | ScopeModifierLiteral ListOrDictGetWithBrackets { result = Riml::GetVariableByScopeAndDictNameNode.new(val[0], val[1]) }
352
+ Scope IDENTIFIER { result = make_node(val) { |v| Riml::GetVariableNode.new(v[0], v[1]) } }
353
+ | SPECIAL_VAR_PREFIX IDENTIFIER { result = make_node(val) { |v| Riml::GetSpecialVariableNode.new(v[0], v[1]) } }
354
+ | ScopeModifierLiteral ListOrDictGetWithBrackets { result = make_node(val) { |v| Riml::GetVariableByScopeAndDictNameNode.new(v[0], v[1]) } }
355
355
  ;
356
356
 
357
357
  AllVariableRetrieval:
358
358
  VariableRetrieval { result = val[0] }
359
- | Scope CurlyBraceName { result = Riml::GetCurlyBraceNameNode.new(val[0], val[1]) }
359
+ | Scope CurlyBraceName { result = make_node(val) { |v| Riml::GetCurlyBraceNameNode.new(v[0], v[1]) } }
360
360
  ;
361
361
 
362
362
  UnletVariable:
363
- UNLET VariableRetrieval { result = Riml::UnletVariableNode.new('!', [ val[1] ]) }
364
- | UNLET_BANG VariableRetrieval { result = Riml::UnletVariableNode.new('!', [ val[1] ]) }
363
+ UNLET VariableRetrieval { result = make_node(val) { |v| Riml::UnletVariableNode.new('!', [ v[1] ]) } }
364
+ | UNLET_BANG VariableRetrieval { result = make_node(val) { |v| Riml::UnletVariableNode.new('!', [ v[1] ]) } }
365
365
  | UnletVariable VariableRetrieval { result = val[0] << val[1] }
366
366
  ;
367
367
 
368
368
  CurlyBraceName:
369
- CurlyBraceVarPart { result = Riml::CurlyBraceVariable.new([ val[0] ]) }
370
- | IDENTIFIER CurlyBraceName { result = Riml::CurlyBraceVariable.new([ Riml::CurlyBracePart.new(val[0]), val[1] ]) }
371
- | CurlyBraceName IDENTIFIER { result = val[0] << Riml::CurlyBracePart.new(val[1]) }
369
+ CurlyBraceVarPart { result = make_node(val) { |v| Riml::CurlyBraceVariable.new([ v[0] ]) } }
370
+ | IDENTIFIER CurlyBraceName { result = make_node(val) { |v| Riml::CurlyBraceVariable.new([ Riml::CurlyBracePart.new(v[0]), v[1] ]) } }
371
+ | CurlyBraceName IDENTIFIER { result = val[0] << make_node(val) { |v| Riml::CurlyBracePart.new(v[1]) } }
372
372
  | CurlyBraceName CurlyBraceVarPart { result = val[0] << val[1] }
373
373
  ;
374
374
 
375
375
  CurlyBraceVarPart:
376
- '{' PossibleStringValue '}' { result = Riml::CurlyBracePart.new(val[1]) }
377
- | '{' PossibleStringValue CurlyBraceVarPart '}' { result = Riml::CurlyBracePart.new([val[1], val[2]]) }
378
- | '{' CurlyBraceVarPart PossibleStringValue '}' { result = Riml::CurlyBracePart.new([val[1], val[2]]) }
376
+ '{' PossibleStringValue '}' { result = make_node(val) { |v| Riml::CurlyBracePart.new(v[1]) } }
377
+ | '{' PossibleStringValue CurlyBraceVarPart '}' { result = make_node(val) { |v| Riml::CurlyBracePart.new([v[1], v[2]]) } }
378
+ | '{' CurlyBraceVarPart PossibleStringValue '}' { result = make_node(val) { |v| Riml::CurlyBracePart.new([v[1], v[2]]) } }
379
379
  ;
380
380
 
381
381
  # Method definition
382
382
  # [SID, scope_modifier, name, parameters, keyword, expressions]
383
383
  Def:
384
- FunctionType SIDAndScope DefCallIdentifier DefKeywords Block END { result = Riml.const_get(val[0]).new('!', val[1][0], val[1][1], val[2], [], val[3], val[4]) }
385
- | FunctionType SIDAndScope DefCallIdentifier '(' ParamList ')' DefKeywords Block END { result = Riml.const_get(val[0]).new('!', val[1][0], val[1][1], val[2], val[4], val[6], val[7]) }
386
- | FunctionType SIDAndScope DefCallIdentifier '(' SPLAT ')' DefKeywords Block END { result = Riml.const_get(val[0]).new('!', val[1][0], val[1][1], val[2], [val[4]], val[6], val[7]) }
387
- | FunctionType SIDAndScope DefCallIdentifier '(' ParamList ',' SPLAT ')' DefKeywords Block END { result = Riml.const_get(val[0]).new('!', val[1][0], val[1][1], val[2], val[4] << val[6], val[8], val[9]) }
384
+ FunctionType SIDAndScope DefCallIdentifier DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], [], v[3], v[4]) } }
385
+ | FunctionType SIDAndScope DefCallIdentifier '(' ParamList ')' DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], v[4], v[6], v[7]) } }
386
+ | FunctionType SIDAndScope DefCallIdentifier '(' SPLAT ')' DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], [v[4]], v[6], v[7]) } }
387
+ | FunctionType SIDAndScope DefCallIdentifier '(' ParamList ',' SPLAT ')' DefKeywords Block END { result = make_node(val) { |v| Riml.const_get(val[0]).new('!', v[1][0], v[1][1], v[2], v[4] << v[6], v[8], v[9]) } }
388
388
  ;
389
389
 
390
390
  FunctionType:
@@ -395,7 +395,7 @@ rule
395
395
 
396
396
  DefCallIdentifier:
397
397
  # use '' for first argument instead of nil in order to avoid a double scope-modifier
398
- CurlyBraceName { result = Riml::GetCurlyBraceNameNode.new('', val[0]) }
398
+ CurlyBraceName { result = make_node(val) { |v| Riml::GetCurlyBraceNameNode.new('', v[0]) } }
399
399
  | IDENTIFIER { result = val[0] }
400
400
  ;
401
401
 
@@ -415,13 +415,13 @@ rule
415
415
  ;
416
416
 
417
417
  DefaultParam:
418
- IDENTIFIER '=' Expression { result = Riml::DefaultParamNode.new(val[0], val[2]) }
418
+ IDENTIFIER '=' Expression { result = make_node(val) { |v| Riml::DefaultParamNode.new(v[0], v[2]) } }
419
419
  ;
420
420
 
421
421
  Return:
422
- RETURN Returnable { result = Riml::ReturnNode.new(val[1]) }
423
- | RETURN Returnable IF Expression { result = Riml::IfNode.new(val[3], Nodes.new([ReturnNode.new(val[1])])) }
424
- | RETURN Returnable UNLESS Expression { result = Riml::UnlessNode.new(val[3], Nodes.new([ReturnNode.new(val[1])])) }
422
+ RETURN Returnable { result = make_node(val) { |v| Riml::ReturnNode.new(v[1]) } }
423
+ | RETURN Returnable IF Expression { result = make_node(val) { |v| Riml::IfNode.new(v[3], Nodes.new([ReturnNode.new(v[1])])) } }
424
+ | RETURN Returnable UNLESS Expression { result = make_node(val) { |v| Riml::UnlessNode.new(v[3], Nodes.new([ReturnNode.new(v[1])])) } }
425
425
  ;
426
426
 
427
427
  Returnable:
@@ -430,57 +430,57 @@ rule
430
430
  ;
431
431
 
432
432
  EndScript:
433
- FINISH { result = Riml::FinishNode.new }
433
+ FINISH { result = make_node(val) { |_| Riml::FinishNode.new } }
434
434
  ;
435
435
 
436
436
  # [expression, expressions]
437
437
  If:
438
- IF Expression IfBlock END { result = Riml::IfNode.new(val[1], val[2]) }
439
- | IF Expression THEN Expression END { result = Riml::IfNode.new(val[1], Riml::Nodes.new([val[3]])) }
440
- | Expression IF Expression { result = Riml::IfNode.new(val[2], Riml::Nodes.new([val[0]])) }
438
+ IF Expression IfBlock END { result = make_node(val) { |v| Riml::IfNode.new(v[1], v[2]) } }
439
+ | IF Expression THEN Expression END { result = make_node(val) { |v| Riml::IfNode.new(v[1], Riml::Nodes.new([v[3]])) } }
440
+ | Expression IF Expression { result = make_node(val) { |v| Riml::IfNode.new(v[2], Riml::Nodes.new([v[0]])) } }
441
441
  ;
442
442
 
443
443
  Unless:
444
- UNLESS Expression IfBlock END { result = Riml::UnlessNode.new(val[1], val[2]) }
445
- | UNLESS Expression THEN Expression END { result = Riml::UnlessNode.new(val[1], Riml::Nodes.new([val[3]])) }
446
- | Expression UNLESS Expression { result = Riml::UnlessNode.new(val[2], Riml::Nodes.new([val[0]])) }
444
+ UNLESS Expression IfBlock END { result = make_node(val) { |v| Riml::UnlessNode.new(v[1], v[2]) } }
445
+ | UNLESS Expression THEN Expression END { result = make_node(val) { |v| Riml::UnlessNode.new(v[1], Riml::Nodes.new([v[3]])) } }
446
+ | Expression UNLESS Expression { result = make_node(val) { |v| Riml::UnlessNode.new(v[2], Riml::Nodes.new([v[0]])) } }
447
447
  ;
448
448
 
449
449
  Ternary:
450
- Expression '?' Expression ':' Expression { result = Riml::TernaryOperatorNode.new([val[0], val[2], val[4]]) }
450
+ Expression '?' Expression ':' Expression { result = make_node(val) { |v| Riml::TernaryOperatorNode.new([v[0], v[2], v[4]]) } }
451
451
  ;
452
452
 
453
453
  While:
454
- WHILE Expression Block END { result = Riml::WhileNode.new(val[1], val[2]) }
454
+ WHILE Expression Block END { result = make_node(val) { |v| Riml::WhileNode.new(v[1], v[2]) } }
455
455
  ;
456
456
 
457
457
  LoopKeyword:
458
- BREAK { result = Riml::BreakNode.new }
459
- | CONTINUE { result = Riml::ContinueNode.new }
458
+ BREAK { result = make_node(val) { |_| Riml::BreakNode.new } }
459
+ | CONTINUE { result = make_node(val) { |_| Riml::ContinueNode.new } }
460
460
  ;
461
461
 
462
462
  Until:
463
- UNTIL Expression Block END { result = Riml::UntilNode.new(val[1], val[2]) }
463
+ UNTIL Expression Block END { result = make_node(val) { |v| Riml::UntilNode.new(v[1], v[2]) } }
464
464
  ;
465
465
 
466
466
  For:
467
- FOR IDENTIFIER IN Expression Block END { result = Riml::ForNode.new(val[1], val[3], val[4]) }
468
- | FOR List IN Expression Block END { result = Riml::ForNode.new(val[1], val[3], val[4]) }
469
- | FOR ListUnpack IN Expression Block END { result = Riml::ForNode.new(val[1], val[3], val[4]) }
467
+ FOR IDENTIFIER IN Expression Block END { result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) } }
468
+ | FOR List IN Expression Block END { result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) } }
469
+ | FOR ListUnpack IN Expression Block END { result = make_node(val) { |v| Riml::ForNode.new(v[1], v[3], v[4]) } }
470
470
  ;
471
471
 
472
472
  Try:
473
- TRY Block END { result = Riml::TryNode.new(val[1], nil, nil) }
474
- | TRY Block Catch END { result = Riml::TryNode.new(val[1], val[2], nil) }
475
- | TRY Block Catch FINALLY Block END { result = Riml::TryNode.new(val[1], val[2], val[4]) }
473
+ TRY Block END { result = make_node(val) { |v| Riml::TryNode.new(v[1], nil, nil) } }
474
+ | TRY Block Catch END { result = make_node(val) { |v| Riml::TryNode.new(v[1], v[2], nil) } }
475
+ | TRY Block Catch FINALLY Block END { result = make_node(val) { |v| Riml::TryNode.new(v[1], v[2], v[4]) } }
476
476
  ;
477
477
 
478
478
  Catch:
479
479
  /* nothing */ { result = nil }
480
- | CATCH Block { result = [ Riml::CatchNode.new(nil, val[1]) ] }
481
- | CATCH Regexp Block { result = [ Riml::CatchNode.new(val[1], val[2]) ] }
482
- | Catch CATCH Block { result = val[0] << Riml::CatchNode.new(nil, val[2]) }
483
- | Catch CATCH Regexp Block { result = val[0] << Riml::CatchNode.new(val[2], val[3]) }
480
+ | CATCH Block { result = [ make_node(val) { |v| Riml::CatchNode.new(nil, v[1]) } ] }
481
+ | CATCH Regexp Block { result = [ make_node(val) { |v| Riml::CatchNode.new(v[1], v[2]) } ] }
482
+ | Catch CATCH Block { result = val[0] << make_node(val) { |v| Riml::CatchNode.new(nil, v[2]) } }
483
+ | Catch CATCH Regexp Block { result = val[0] << make_node(val) { |v| Riml::CatchNode.new(v[2], v[3]) } }
484
484
  ;
485
485
 
486
486
  # [expressions]
@@ -488,7 +488,7 @@ rule
488
488
  # itself
489
489
  Block:
490
490
  NEWLINE Statements { result = val[1] }
491
- | NEWLINE { result = Riml::Nodes.new([]) }
491
+ | NEWLINE { result = make_node(val) { |_| Riml::Nodes.new([]) } }
492
492
  ;
493
493
 
494
494
  IfBlock:
@@ -499,30 +499,30 @@ rule
499
499
  ;
500
500
 
501
501
  ElseBlock:
502
- ELSE NEWLINE Statements { result = Riml::ElseNode.new(val[2]) }
502
+ ELSE NEWLINE Statements { result = make_node(val) { |v| Riml::ElseNode.new(v[2]) } }
503
503
  ;
504
504
 
505
505
  ElseifBlock:
506
- ELSEIF Expression NEWLINE Statements { result = Riml::Nodes.new([Riml::ElseifNode.new(val[1], val[3])]) }
507
- | ElseifBlock ELSEIF Expression NEWLINE Statements { result = val[0] << Riml::ElseifNode.new(val[2], val[4]) }
506
+ ELSEIF Expression NEWLINE Statements { result = make_node(val) { |v| Riml::Nodes.new([Riml::ElseifNode.new(v[1], v[3])]) } }
507
+ | ElseifBlock ELSEIF Expression NEWLINE Statements { result = val[0] << make_node(val) { |v| Riml::ElseifNode.new(v[2], v[4]) } }
508
508
  ;
509
509
 
510
510
  ClassDefinition:
511
- CLASS Scope IDENTIFIER Block END { result = Riml::ClassDefinitionNode.new(val[1], val[2], nil, val[3]) }
512
- | CLASS Scope IDENTIFIER '<' Scope IDENTIFIER Block END { result = Riml::ClassDefinitionNode.new(val[1], val[2], (val[4] || ClassDefinitionNode::DEFAULT_SCOPE_MODIFIER) + val[5], val[6]) }
511
+ CLASS Scope IDENTIFIER Block END { result = make_node(val) { |v| Riml::ClassDefinitionNode.new(v[1], v[2], nil, v[3]) } }
512
+ | CLASS Scope IDENTIFIER '<' Scope IDENTIFIER Block END { result = make_node(val) { |v| Riml::ClassDefinitionNode.new(v[1], v[2], (v[4] || ClassDefinitionNode::DEFAULT_SCOPE_MODIFIER) + v[5], v[6]) } }
513
513
  ;
514
514
 
515
515
  ObjectInstantiation:
516
- NEW ObjectInstantiationCall { result = Riml::ObjectInstantiationNode.new(val[1]) }
516
+ NEW ObjectInstantiationCall { result = make_node(val) { |v| Riml::ObjectInstantiationNode.new(v[1]) } }
517
517
  ;
518
518
 
519
519
  Super:
520
- SUPER '(' ArgList ')' { result = Riml::SuperNode.new(val[2], true) }
521
- | SUPER { result = Riml::SuperNode.new([], false) }
520
+ SUPER '(' ArgList ')' { result = make_node(val) { |v| Riml::SuperNode.new(v[2], true) } }
521
+ | SUPER { result = make_node(val) { |_| Riml::SuperNode.new([], false) } }
522
522
  ;
523
523
 
524
524
  ExLiteral:
525
- EX_LITERAL { result = Riml::ExLiteralNode.new(val[0])}
525
+ EX_LITERAL { result = make_node(val) { |v| Riml::ExLiteralNode.new(v[0]) } }
526
526
  ;
527
527
  end
528
528
 
@@ -541,7 +541,7 @@ end
541
541
  if tokens?(object)
542
542
  @tokens = object
543
543
  elsif code?(object)
544
- @lexer = Riml::Lexer.new(object)
544
+ @lexer = Riml::Lexer.new(object, filename, true)
545
545
  end
546
546
 
547
547
  begin
@@ -552,7 +552,7 @@ end
552
552
  warning = "#{@lexer.invalid_keyword.inspect} is a keyword, and cannot " \
553
553
  "be used as a variable name"
554
554
  end
555
- error_msg = "on line #{@lexer.lineno}: #{e.message}"
555
+ error_msg = "#{e.message} at #{@lexer.filename}:#{@lexer.lineno}"
556
556
  error_msg << "\n\n#{warning}" if warning
557
557
  raise Riml::ParseError, error_msg
558
558
  end
@@ -567,10 +567,13 @@ end
567
567
  # the lexer getting the next token
568
568
  def next_token
569
569
  return @tokens.shift unless @lexer
570
- @lexer.next_token
570
+ token = @lexer.next_token
571
+ @current_parser_info = token.pop if token
572
+ token
571
573
  end
572
574
 
573
575
  private
576
+
574
577
  def tokens?(object)
575
578
  Array === object
576
579
  end
@@ -578,3 +581,9 @@ end
578
581
  def code?(object)
579
582
  String === object
580
583
  end
584
+
585
+ def make_node(racc_val)
586
+ node = yield racc_val
587
+ node.parser_info = @current_parser_info
588
+ node
589
+ end