wlang 0.8.4 → 0.8.5
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.
- data/lib/wlang.rb +1 -1
- data/lib/wlang/errors.rb +6 -27
- data/lib/wlang/parser.rb +11 -3
- data/lib/wlang/parser_context.rb +0 -7
- data/lib/wlang/ruby_extensions.rb +14 -0
- data/lib/wlang/rulesets/buffering_ruleset.rb +38 -19
- data/lib/wlang/template.rb +26 -4
- data/test/wlang/parser_test.rb +6 -6
- metadata +2 -2
data/lib/wlang.rb
CHANGED
data/lib/wlang/errors.rb
CHANGED
@@ -3,35 +3,14 @@ module WLang
|
|
3
3
|
# Main error of all WLang errors.
|
4
4
|
class Error < StandardError; end
|
5
5
|
|
6
|
+
# Raise when something fails when evaluting through the parser context
|
7
|
+
class EvalError < StandardError; end
|
8
|
+
|
6
9
|
# Error raised by a WLang parser instanciation when an error occurs.
|
7
|
-
class ParseError < StandardError;
|
8
|
-
|
9
|
-
attr_reader :line, :column
|
10
|
-
|
11
|
-
# Creates an error with offset information
|
12
|
-
def initialize(message, offset=nil, template=nil)
|
13
|
-
@offset = offset
|
14
|
-
@line, @column = parse(template) if template
|
15
|
-
unless template and offset
|
16
|
-
super(message)
|
17
|
-
else
|
18
|
-
super("ParseError at #{@line}:#{@column} : #{message}")
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
10
|
+
class ParseError < StandardError;
|
22
11
|
|
23
|
-
|
24
|
-
def parse(template)
|
25
|
-
template = template[0,@offset]
|
26
|
-
if template =~ /\n/ then
|
27
|
-
lines = template[0,@offset].split(/\n/)
|
28
|
-
else
|
29
|
-
lines = [template]
|
30
|
-
end
|
31
|
-
line, column = lines.length, lines.last.length
|
32
|
-
return [line, column]
|
33
|
-
end
|
12
|
+
attr_accessor :line, :column
|
34
13
|
|
35
|
-
end
|
14
|
+
end
|
36
15
|
|
37
16
|
end # module WLang
|
data/lib/wlang/parser.rb
CHANGED
@@ -136,6 +136,8 @@ module WLang
|
|
136
136
|
#
|
137
137
|
def evaluate(expression)
|
138
138
|
@context.evaluate(expression)
|
139
|
+
rescue Exception => ex
|
140
|
+
raise ::WLang::EvalError, "#{template.where(@offset)} evaluation of '#{expression}' failed", ex.backtrace
|
139
141
|
end
|
140
142
|
|
141
143
|
#
|
@@ -199,19 +201,25 @@ module WLang
|
|
199
201
|
encoder.encode(src, options)
|
200
202
|
end
|
201
203
|
|
204
|
+
# Raises an exception with a friendly message
|
205
|
+
def error(offset, message)
|
206
|
+
template.error(offset, message)
|
207
|
+
end
|
208
|
+
|
202
209
|
#
|
203
210
|
# Raises a ParseError at a given offset.
|
204
211
|
#
|
205
212
|
def syntax_error(offset, msg=nil)
|
206
213
|
text = self.parse(offset, "wlang/dummy", "")
|
207
|
-
|
214
|
+
msg = msg.nil? ? '' : ": #{msg}"
|
215
|
+
template.parse_error(offset, "parse error on '#{text}'#{msg}")
|
208
216
|
end
|
209
217
|
|
210
218
|
#
|
211
219
|
# Raises a ParseError at a given offset for a missing block
|
212
220
|
#
|
213
221
|
def block_missing_error(offset)
|
214
|
-
|
222
|
+
template.parse_error(offset, "parse error, block was expected")
|
215
223
|
end
|
216
224
|
|
217
225
|
#
|
@@ -219,7 +227,7 @@ module WLang
|
|
219
227
|
# specif. the expected character when EOF found
|
220
228
|
#
|
221
229
|
def unexpected_eof(offset, expected)
|
222
|
-
|
230
|
+
template.parse_error(offset, "#{expected} expected, EOF found")
|
223
231
|
end
|
224
232
|
|
225
233
|
#
|
data/lib/wlang/parser_context.rb
CHANGED
@@ -104,13 +104,6 @@ module WLang
|
|
104
104
|
else
|
105
105
|
@current_scope.__evaluate(expression)
|
106
106
|
end
|
107
|
-
rescue Exception => ex
|
108
|
-
puts "Warning, some wlang exception when evaluating the expression\n#{expression}"
|
109
|
-
puts "Message was: #{ex.message}"
|
110
|
-
puts ex.backtrace.join("\n")
|
111
|
-
puts "Current scope was:\n"
|
112
|
-
puts @current_scope.__underlying.inspect
|
113
|
-
return nil
|
114
107
|
end
|
115
108
|
|
116
109
|
# Pushes a new scope instance.
|
@@ -17,5 +17,19 @@ class String
|
|
17
17
|
end
|
18
18
|
alias :wlang :wlang_instantiate
|
19
19
|
|
20
|
+
def __wlang_column_of(index)
|
21
|
+
return 1 if index == 0
|
22
|
+
newline_index = rindex("\n", index - 1)
|
23
|
+
if newline_index
|
24
|
+
index - newline_index
|
25
|
+
else
|
26
|
+
index + 1
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def __wlang_line_of(index)
|
31
|
+
self[0...index].count("\n") + 1
|
32
|
+
end
|
33
|
+
|
20
34
|
end
|
21
35
|
|
@@ -20,8 +20,13 @@ module WLang
|
|
20
20
|
# Rule implementation of <tt><<{wlang/uri}</tt>
|
21
21
|
def self.input(parser, offset)
|
22
22
|
uri, reached = parser.parse(offset, "wlang/uri")
|
23
|
-
file = parser.template.file_resolve(uri,
|
24
|
-
|
23
|
+
file = parser.template.file_resolve(uri, false)
|
24
|
+
if File.file?(file) and File.readable?(file)
|
25
|
+
[File.read(file), reached]
|
26
|
+
else
|
27
|
+
text = parser.parse(offset, "wlang/dummy")[0]
|
28
|
+
parser.error(offset, "unable to apply input rule <<{#{text}}, not a file or not readable (#{file})")
|
29
|
+
end
|
25
30
|
end
|
26
31
|
|
27
32
|
# Rule implementation of <tt>>>{wlang/uri}</tt>
|
@@ -29,11 +34,15 @@ module WLang
|
|
29
34
|
uri, reached = parser.parse(offset, "wlang/uri")
|
30
35
|
file = parser.template.file_resolve(uri, false)
|
31
36
|
dir = File.dirname(file)
|
32
|
-
|
33
|
-
|
34
|
-
|
37
|
+
if File.writable?(dir) or not(File.exists?(dir))
|
38
|
+
FileUtils.mkdir_p(dir) unless File.exists?(dir)
|
39
|
+
File.open(file, "w") do |file|
|
40
|
+
text, reached = parser.parse_block(reached, nil, file)
|
41
|
+
end
|
42
|
+
["", reached]
|
43
|
+
else
|
44
|
+
parser.error(offset, "unable to apply output rule >>{#{text}}, not a writable directory (#{file})")
|
35
45
|
end
|
36
|
-
["", reached]
|
37
46
|
end
|
38
47
|
|
39
48
|
# Rule implementation of <<={wlang/uri as x}{...}
|
@@ -44,18 +53,23 @@ module WLang
|
|
44
53
|
decoded = U.decode_uri_as(uri)
|
45
54
|
parser.syntax_error(offset) if decoded.nil?
|
46
55
|
|
47
|
-
file = parser.template.file_resolve(decoded[:uri],
|
48
|
-
|
56
|
+
file = parser.template.file_resolve(decoded[:uri], false)
|
57
|
+
if File.file?(file) and File.readable?(file)
|
58
|
+
data = WLang::load_data(file)
|
49
59
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
60
|
+
# handle two different cases
|
61
|
+
if parser.has_block?(reached)
|
62
|
+
parser.context_push(decoded[:variable] => data)
|
63
|
+
text, reached = parser.parse_block(reached)
|
64
|
+
parser.context_pop
|
65
|
+
[text, reached]
|
66
|
+
else
|
67
|
+
parser.context_define(decoded[:variable], data)
|
68
|
+
["", reached]
|
69
|
+
end
|
56
70
|
else
|
57
|
-
parser.
|
58
|
-
|
71
|
+
text = parser.parse(offset, "wlang/dummy")[0]
|
72
|
+
parser.error(offset, "unable to apply data-assignment rule <<={#{text}} (#{file}), not a file or not readable (#{file})")
|
59
73
|
end
|
60
74
|
end
|
61
75
|
|
@@ -91,9 +105,14 @@ module WLang
|
|
91
105
|
end
|
92
106
|
end
|
93
107
|
|
94
|
-
file = parser.template.file_resolve(decoded[:uri],
|
95
|
-
|
96
|
-
|
108
|
+
file = parser.template.file_resolve(decoded[:uri], false)
|
109
|
+
if File.file?(file) and File.readable?(file)
|
110
|
+
instantiated = WLang::file_instantiate(file, context)
|
111
|
+
[instantiated, reached]
|
112
|
+
else
|
113
|
+
text = parser.parse(offset, "wlang/dummy")[0]
|
114
|
+
parser.error(offset, "unable to apply input-inclusion rule <<+{#{text}}, not a file or not readable (#{file})")
|
115
|
+
end
|
97
116
|
end
|
98
117
|
|
99
118
|
|
data/lib/wlang/template.rb
CHANGED
@@ -52,10 +52,10 @@ module WLang
|
|
52
52
|
# Returns template's source text
|
53
53
|
def source_text
|
54
54
|
case @source
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
when String
|
56
|
+
@source
|
57
|
+
else
|
58
|
+
@source.to_s
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -73,6 +73,28 @@ module WLang
|
|
73
73
|
end
|
74
74
|
instantiated[0]
|
75
75
|
end
|
76
|
+
|
77
|
+
# Returns a friendly position of an offset in the source text
|
78
|
+
def where(offset)
|
79
|
+
src = source_text
|
80
|
+
"#{@source_file}:#{src.__wlang_line_of(offset)}:#{src.__wlang_column_of(offset)-1}"
|
81
|
+
end
|
82
|
+
|
83
|
+
# Raises a WLang::Error for the given offset
|
84
|
+
def error(offset, msg = "")
|
85
|
+
src = source_text
|
86
|
+
line, column = src.__wlang_line_of(offset), src.__wlang_column_of(offset)-1
|
87
|
+
raise WLang::Error, "#{@source_file}:#{line}:#{column} #{msg}"
|
88
|
+
end
|
89
|
+
|
90
|
+
# Raises a friendly ParseError, with positions and so on
|
91
|
+
def parse_error(offset, msg = "")
|
92
|
+
src = source_text
|
93
|
+
line, column = src.__wlang_line_of(offset), src.__wlang_column_of(offset)-1
|
94
|
+
ex = ParseError.new("#{@source_file}:#{line}:#{column} #{msg}")
|
95
|
+
ex.line, ex.column = line, column
|
96
|
+
raise ex
|
97
|
+
end
|
76
98
|
|
77
99
|
end # class Template
|
78
100
|
|
data/test/wlang/parser_test.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'test/unit
|
1
|
+
require 'test/unit'
|
2
2
|
require 'wlang'
|
3
3
|
module WLang
|
4
4
|
|
@@ -77,11 +77,11 @@ class ParserTest < Test::Unit::TestCase
|
|
77
77
|
def test_parser_error_find_line_and_column
|
78
78
|
assert_error_at_line_column("-{tag", 1, 5)
|
79
79
|
assert_error_at_line_column("-{tag with spaces ", 1, 20)
|
80
|
-
assert_error_at_line_column("-{tag as i}{\n",
|
81
|
-
assert_error_at_line_column("-{tag as i}{\n\n",
|
82
|
-
assert_error_at_line_column("-{tag as i}{\ntext\n",
|
83
|
-
assert_error_at_line_column("-{tag as i}{\n\ntext\n",
|
84
|
-
assert_error_at_line_column("-{tag as i}{\n\n\ntext\n",
|
80
|
+
assert_error_at_line_column("-{tag as i}{\n", 2, 0)
|
81
|
+
assert_error_at_line_column("-{tag as i}{\n\n", 3, 0)
|
82
|
+
assert_error_at_line_column("-{tag as i}{\ntext\n", 3, 0)
|
83
|
+
assert_error_at_line_column("-{tag as i}{\n\ntext\n", 4, 0)
|
84
|
+
assert_error_at_line_column("-{tag as i}{\n\n\ntext\n", 5, 0)
|
85
85
|
end
|
86
86
|
|
87
87
|
end # ParserTest
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wlang
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bernard Lambeau
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-21 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|