walrus 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/walrus +19 -12
- data/lib/walrus.rb +27 -70
- data/lib/walrus/additions/string.rb +21 -35
- data/lib/walrus/compile_error.rb +19 -16
- data/lib/walrus/compiler.rb +66 -55
- data/lib/walrus/contrib/spec/walruscloth_spec.rb +21 -17
- data/lib/walrus/contrib/walruscloth.rb +19 -11
- data/lib/walrus/document.rb +41 -33
- data/lib/walrus/grammar.rb +474 -162
- data/lib/walrus/grammar/assignment_expression.rb +33 -0
- data/lib/walrus/grammar/block_directive.rb +37 -0
- data/lib/walrus/grammar/comment.rb +33 -0
- data/lib/walrus/grammar/def_directive.rb +80 -0
- data/lib/walrus/grammar/echo_directive.rb +56 -0
- data/lib/walrus/grammar/escape_sequence.rb +33 -0
- data/lib/walrus/grammar/import_directive.rb +54 -0
- data/lib/walrus/grammar/include_directive.rb +36 -0
- data/lib/walrus/grammar/instance_variable.rb +33 -0
- data/lib/walrus/grammar/literal.rb +33 -0
- data/lib/walrus/grammar/message_expression.rb +34 -0
- data/lib/walrus/grammar/multiline_comment.rb +70 -0
- data/lib/walrus/grammar/placeholder.rb +47 -0
- data/lib/walrus/grammar/raw_directive.rb +50 -0
- data/lib/walrus/grammar/raw_text.rb +56 -0
- data/lib/walrus/grammar/ruby_directive.rb +41 -0
- data/lib/walrus/grammar/ruby_expression.rb +42 -0
- data/lib/walrus/grammar/set_directive.rb +34 -0
- data/lib/walrus/grammar/silent_directive.rb +51 -0
- data/lib/walrus/grammar/slurp_directive.rb +36 -0
- data/lib/walrus/grammar/super_directive.rb +34 -0
- data/lib/walrus/parser.rb +26 -408
- data/lib/walrus/runner.rb +37 -20
- data/lib/walrus/template.rb +34 -25
- data/lib/walrus/version.rb +24 -1
- metadata +57 -71
- data/ext/extconf.rb +0 -16
- data/ext/jindex.c +0 -92
- data/lib/walrus/diff.rb +0 -95
- data/lib/walrus/grammar/additions/proc.rb +0 -26
- data/lib/walrus/grammar/additions/regexp.rb +0 -27
- data/lib/walrus/grammar/additions/string.rb +0 -58
- data/lib/walrus/grammar/additions/symbol.rb +0 -49
- data/lib/walrus/grammar/and_predicate.rb +0 -46
- data/lib/walrus/grammar/array_result.rb +0 -25
- data/lib/walrus/grammar/continuation_wrapper_exception.rb +0 -34
- data/lib/walrus/grammar/left_recursion_exception.rb +0 -33
- data/lib/walrus/grammar/location_tracking.rb +0 -115
- data/lib/walrus/grammar/match_data_wrapper.rb +0 -71
- data/lib/walrus/grammar/memoizing.rb +0 -47
- data/lib/walrus/grammar/memoizing_cache.rb +0 -103
- data/lib/walrus/grammar/node.rb +0 -66
- data/lib/walrus/grammar/not_predicate.rb +0 -46
- data/lib/walrus/grammar/parse_error.rb +0 -45
- data/lib/walrus/grammar/parser_state.rb +0 -187
- data/lib/walrus/grammar/parslet.rb +0 -34
- data/lib/walrus/grammar/parslet_choice.rb +0 -128
- data/lib/walrus/grammar/parslet_combination.rb +0 -32
- data/lib/walrus/grammar/parslet_combining.rb +0 -160
- data/lib/walrus/grammar/parslet_merge.rb +0 -94
- data/lib/walrus/grammar/parslet_omission.rb +0 -63
- data/lib/walrus/grammar/parslet_repetition.rb +0 -106
- data/lib/walrus/grammar/parslet_repetition_default.rb +0 -64
- data/lib/walrus/grammar/parslet_sequence.rb +0 -214
- data/lib/walrus/grammar/predicate.rb +0 -63
- data/lib/walrus/grammar/proc_parslet.rb +0 -58
- data/lib/walrus/grammar/regexp_parslet.rb +0 -79
- data/lib/walrus/grammar/skipped_substring_exception.rb +0 -42
- data/lib/walrus/grammar/string_enumerator.rb +0 -53
- data/lib/walrus/grammar/string_parslet.rb +0 -81
- data/lib/walrus/grammar/string_result.rb +0 -30
- data/lib/walrus/grammar/symbol_parslet.rb +0 -69
- data/lib/walrus/no_parameter_marker.rb +0 -25
- data/lib/walrus/walrus_grammar/assignment_expression.rb +0 -30
- data/lib/walrus/walrus_grammar/block_directive.rb +0 -34
- data/lib/walrus/walrus_grammar/comment.rb +0 -30
- data/lib/walrus/walrus_grammar/def_directive.rb +0 -72
- data/lib/walrus/walrus_grammar/echo_directive.rb +0 -50
- data/lib/walrus/walrus_grammar/escape_sequence.rb +0 -30
- data/lib/walrus/walrus_grammar/import_directive.rb +0 -50
- data/lib/walrus/walrus_grammar/include_directive.rb +0 -33
- data/lib/walrus/walrus_grammar/instance_variable.rb +0 -30
- data/lib/walrus/walrus_grammar/literal.rb +0 -30
- data/lib/walrus/walrus_grammar/message_expression.rb +0 -31
- data/lib/walrus/walrus_grammar/multiline_comment.rb +0 -60
- data/lib/walrus/walrus_grammar/placeholder.rb +0 -46
- data/lib/walrus/walrus_grammar/raw_directive.rb +0 -48
- data/lib/walrus/walrus_grammar/raw_text.rb +0 -51
- data/lib/walrus/walrus_grammar/ruby_directive.rb +0 -35
- data/lib/walrus/walrus_grammar/ruby_expression.rb +0 -37
- data/lib/walrus/walrus_grammar/set_directive.rb +0 -30
- data/lib/walrus/walrus_grammar/silent_directive.rb +0 -50
- data/lib/walrus/walrus_grammar/slurp_directive.rb +0 -31
- data/lib/walrus/walrus_grammar/super_directive.rb +0 -33
data/bin/walrus
CHANGED
@@ -1,17 +1,25 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
# Copyright 2007-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# the Free Software Foundation, either version 3 of the License, or
|
6
|
-
# (at your option) any later version.
|
2
|
+
# Copyright 2007-2010 Wincent Colaiuta. All rights reserved.
|
3
|
+
# Redistribution and use in source and binary forms, with or without
|
4
|
+
# modification, are permitted provided that the following conditions are met:
|
7
5
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
6
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
7
|
+
# this list of conditions and the following disclaimer.
|
8
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer in the documentation
|
10
|
+
# and/or other materials provided with the distribution.
|
12
11
|
#
|
13
|
-
#
|
14
|
-
#
|
12
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
13
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
14
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
15
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
16
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
17
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
18
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
19
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
20
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
21
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
22
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
15
23
|
|
16
24
|
module Walrus
|
17
25
|
|
@@ -55,5 +63,4 @@ substituting absolute paths for "lib" and "ext":
|
|
55
63
|
$stderr.puts ":: error: #{e.to_s}"
|
56
64
|
exit EXIT_UNKNOWN_ERROR
|
57
65
|
end
|
58
|
-
|
59
66
|
end # module Walrus
|
data/lib/walrus.rb
CHANGED
@@ -1,78 +1,35 @@
|
|
1
|
-
# Copyright 2007-2010 Wincent Colaiuta
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# the Free Software Foundation, either version 3 of the License, or
|
5
|
-
# (at your option) any later version.
|
1
|
+
# Copyright 2007-2010 Wincent Colaiuta. All rights reserved.
|
2
|
+
# Redistribution and use in source and binary forms, with or without
|
3
|
+
# modification, are permitted provided that the following conditions are met:
|
6
4
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
5
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
6
|
+
# this list of conditions and the following disclaimer.
|
7
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer in the documentation
|
9
|
+
# and/or other materials provided with the distribution.
|
11
10
|
#
|
12
|
-
#
|
13
|
-
#
|
11
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
12
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
13
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
14
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
15
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
16
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
17
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
18
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
19
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
20
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
21
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
14
22
|
|
15
|
-
|
16
|
-
require 'jcode' # jlength method
|
17
|
-
rescue LoadError
|
18
|
-
class String
|
19
|
-
def jlength
|
20
|
-
self.gsub(/[^\Wa-zA-Z_\d]/, ' ').length
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
require 'continuation' unless Kernel.respond_to?(:callcc)
|
23
|
+
require 'walrat'
|
26
24
|
|
27
25
|
module Walrus
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
autoload
|
34
|
-
autoload
|
35
|
-
autoload(:Grammar, 'walrus/grammar')
|
36
|
-
autoload(:Parser, 'walrus/parser')
|
37
|
-
autoload(:NoParameterMarker, 'walrus/no_parameter_marker')
|
38
|
-
autoload(:Template, 'walrus/template')
|
39
|
-
autoload :VERSION, 'walrus/version'
|
40
|
-
|
41
|
-
class Grammar
|
42
|
-
autoload(:AndPredicate, 'walrus/grammar/and_predicate')
|
43
|
-
autoload(:ArrayResult, 'walrus/grammar/array_result')
|
44
|
-
autoload(:ContinuationWrapperException, 'walrus/grammar/continuation_wrapper_exception')
|
45
|
-
autoload(:LeftRecursionException, 'walrus/grammar/left_recursion_exception')
|
46
|
-
autoload(:LocationTracking, 'walrus/grammar/location_tracking')
|
47
|
-
autoload(:MatchDataWrapper, 'walrus/grammar/match_data_wrapper')
|
48
|
-
autoload(:Memoizing, 'walrus/grammar/memoizing')
|
49
|
-
autoload(:MemoizingCache, 'walrus/grammar/memoizing_cache')
|
50
|
-
autoload(:NotPredicate, 'walrus/grammar/not_predicate')
|
51
|
-
autoload(:Node, 'walrus/grammar/node')
|
52
|
-
autoload(:ParseError, 'walrus/grammar/parse_error')
|
53
|
-
autoload(:ParserState, 'walrus/grammar/parser_state')
|
54
|
-
autoload(:Parslet, 'walrus/grammar/parslet')
|
55
|
-
autoload(:ParsletChoice, 'walrus/grammar/parslet_choice')
|
56
|
-
autoload(:ParsletCombination, 'walrus/grammar/parslet_combination')
|
57
|
-
autoload(:ParsletCombining, 'walrus/grammar/parslet_combining')
|
58
|
-
autoload(:ParsletMerge, 'walrus/grammar/parslet_merge')
|
59
|
-
autoload(:ParsletOmission, 'walrus/grammar/parslet_omission')
|
60
|
-
autoload(:ParsletRepetition, 'walrus/grammar/parslet_repetition')
|
61
|
-
autoload(:ParsletRepetitionDefault, 'walrus/grammar/parslet_repetition_default')
|
62
|
-
autoload(:ParsletSequence, 'walrus/grammar/parslet_sequence')
|
63
|
-
autoload(:Predicate, 'walrus/grammar/predicate')
|
64
|
-
autoload(:ProcParslet, 'walrus/grammar/proc_parslet')
|
65
|
-
autoload(:RegexpParslet, 'walrus/grammar/regexp_parslet')
|
66
|
-
autoload(:SkippedSubstringException, 'walrus/grammar/skipped_substring_exception')
|
67
|
-
autoload(:StringEnumerator, 'walrus/grammar/string_enumerator')
|
68
|
-
autoload(:StringParslet, 'walrus/grammar/string_parslet')
|
69
|
-
autoload(:StringResult, 'walrus/grammar/string_result')
|
70
|
-
autoload(:SymbolParslet, 'walrus/grammar/symbol_parslet')
|
71
|
-
end
|
26
|
+
autoload :CompileError, 'walrus/compile_error'
|
27
|
+
autoload :Compiler, 'walrus/compiler'
|
28
|
+
autoload :COPYRIGHT, 'walrus/version'
|
29
|
+
autoload :Grammar, 'walrus/grammar'
|
30
|
+
autoload :Parser, 'walrus/parser'
|
31
|
+
autoload :Template, 'walrus/template'
|
32
|
+
autoload :VERSION, 'walrus/version'
|
72
33
|
end # module Walrus
|
73
34
|
|
74
35
|
require 'walrus/additions/string'
|
75
|
-
require 'walrus/grammar/additions/proc'
|
76
|
-
require 'walrus/grammar/additions/regexp'
|
77
|
-
require 'walrus/grammar/additions/string'
|
78
|
-
require 'walrus/grammar/additions/symbol'
|
@@ -1,43 +1,29 @@
|
|
1
|
-
# Copyright 2007 Wincent Colaiuta
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# the Free Software Foundation, either version 3 of the License, or
|
5
|
-
# (at your option) any later version.
|
1
|
+
# Copyright 2007-2010 Wincent Colaiuta. All rights reserved.
|
2
|
+
# Redistribution and use in source and binary forms, with or without
|
3
|
+
# modification, are permitted provided that the following conditions are met:
|
6
4
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
5
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
6
|
+
# this list of conditions and the following disclaimer.
|
7
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer in the documentation
|
9
|
+
# and/or other materials provided with the distribution.
|
11
10
|
#
|
12
|
-
#
|
13
|
-
#
|
11
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
12
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
13
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
14
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
15
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
16
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
17
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
18
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
19
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
20
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
21
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
14
22
|
|
15
|
-
require 'walrus'
|
16
|
-
|
17
|
-
# Additions to String class for Unicode support.
|
18
23
|
class String
|
19
|
-
|
20
|
-
#
|
21
|
-
# Concretely, the receiver is split into words, each word lowercased, and the words are joined together using a lower-case separator. "Words" are considered to be runs of characters starting with an initial capital letter (note that words may begin with consecutive capital letters), and numbers may mark the start or the end of a word.
|
22
|
-
# Note that some information loss may be incurred; for example, "EOLToken" would be reduced to "eol_token".
|
23
|
-
def to_require_name
|
24
|
-
base = self.gsub(/([^A-Z_])([A-Z])/, '\1_\2') # insert an underscore before any initial capital letters
|
25
|
-
base.gsub!(/([A-Z])([A-Z])([^A-Z0-9_])/, '\1_\2\3') # consecutive capitals are words too, excluding any following capital that belongs to the next word
|
26
|
-
base.gsub!(/([^0-9_])(\d)/, '\1_\2') # numbers mark the start of a new word
|
27
|
-
base.gsub!(/(\d)([^0-9_])/, '\1_\2') # numbers also mark the end of a word
|
28
|
-
base.downcase # lowercase everything
|
29
|
-
end
|
30
|
-
|
31
|
-
# Converts the receiver of the form "foo_bar" to "FooBar".
|
32
|
-
# Specifically, the receiver is split into pieces delimited by underscores, each component is then converted to captial case (the first letter is capitalized and the remaining letters are lowercased) and finally the components are joined.
|
33
|
-
# Note that this method cannot recover information lost during a conversion using the require_name_from_classname method; for example, "EOL", when converted to "token", would be transformed back to "EolToken". Likewise, "Foo__bar" would be reduced to "foo__bar" and then in the reverse conversion would become "FooBar".
|
34
|
-
def to_class_name
|
35
|
-
self.split('_').collect { |component| component.capitalize}.join
|
36
|
-
end
|
37
|
-
|
38
|
-
# Returns a copy of the receiver with occurrences of \ replaced with \\, and occurrences of ' replaced with \'
|
24
|
+
# Returns a copy of the receiver with occurrences of \ replaced with \\, and
|
25
|
+
# occurrences of ' replaced with \'
|
39
26
|
def to_source_string
|
40
27
|
gsub(/[\\']/, '\\\\\&')
|
41
28
|
end
|
42
|
-
|
43
29
|
end # class String
|
data/lib/walrus/compile_error.rb
CHANGED
@@ -1,24 +1,30 @@
|
|
1
|
-
# Copyright 2007 Wincent Colaiuta
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# the Free Software Foundation, either version 3 of the License, or
|
5
|
-
# (at your option) any later version.
|
1
|
+
# Copyright 2007-2010 Wincent Colaiuta. All rights reserved.
|
2
|
+
# Redistribution and use in source and binary forms, with or without
|
3
|
+
# modification, are permitted provided that the following conditions are met:
|
6
4
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
5
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
6
|
+
# this list of conditions and the following disclaimer.
|
7
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer in the documentation
|
9
|
+
# and/or other materials provided with the distribution.
|
11
10
|
#
|
12
|
-
#
|
13
|
-
#
|
11
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
12
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
13
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
14
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
15
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
16
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
17
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
18
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
19
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
20
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
21
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
14
22
|
|
15
23
|
require 'walrus'
|
16
24
|
|
17
25
|
module Walrus
|
18
26
|
class Grammar
|
19
|
-
|
20
27
|
class CompileError < Exception
|
21
|
-
|
22
28
|
# take an optional hash (for packing extra info into exception?)
|
23
29
|
# position in AST/source file
|
24
30
|
# line number, column number
|
@@ -26,9 +32,6 @@ module Walrus
|
|
26
32
|
def initialize(message, info = {})
|
27
33
|
super message
|
28
34
|
end
|
29
|
-
|
30
35
|
end # class CompileError
|
31
|
-
|
32
36
|
end # class Grammar
|
33
37
|
end # module Walrus
|
34
|
-
|
data/lib/walrus/compiler.rb
CHANGED
@@ -1,78 +1,98 @@
|
|
1
|
-
# Copyright 2007 Wincent Colaiuta
|
2
|
-
#
|
3
|
-
#
|
4
|
-
# the Free Software Foundation, either version 3 of the License, or
|
5
|
-
# (at your option) any later version.
|
1
|
+
# Copyright 2007-2010 Wincent Colaiuta. All rights reserved.
|
2
|
+
# Redistribution and use in source and binary forms, with or without
|
3
|
+
# modification, are permitted provided that the following conditions are met:
|
6
4
|
#
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
5
|
+
# 1. Redistributions of source code must retain the above copyright notice,
|
6
|
+
# this list of conditions and the following disclaimer.
|
7
|
+
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer in the documentation
|
9
|
+
# and/or other materials provided with the distribution.
|
11
10
|
#
|
12
|
-
#
|
13
|
-
#
|
11
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
12
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
13
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
14
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
|
15
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
16
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
17
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
18
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
19
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
20
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
21
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
14
22
|
|
15
23
|
require 'walrus'
|
16
24
|
require 'pathname'
|
17
25
|
|
18
26
|
module Walrus
|
19
27
|
class Compiler
|
20
|
-
|
21
28
|
BODY_INDENT = ' ' * 8
|
22
29
|
OUTSIDE_INDENT = ' ' * 6
|
23
30
|
DEFAULT_CLASS = 'DocumentSubclass'
|
24
|
-
|
25
|
-
# The public compiler class serves as the interface with the outside world.
|
31
|
+
|
32
|
+
# The public compiler class serves as the interface with the outside world.
|
33
|
+
# For thread-safety and concurrency, an inner, private Instance class is
|
34
|
+
# spawned in order to perform the actual compilation.
|
26
35
|
class Instance
|
27
|
-
|
28
|
-
def initialize(options)
|
36
|
+
def initialize options
|
29
37
|
@class_name = (options[:class_name] || DEFAULT_CLASS).to_s
|
30
|
-
@template_body = [] #
|
31
|
-
@outside_body = [] #
|
38
|
+
@template_body = [] # accumulate body items, joined at end of process
|
39
|
+
@outside_body = [] # accumulate outside-of-body items, joined at end
|
32
40
|
end
|
33
|
-
|
41
|
+
|
34
42
|
def compile_subtree(subtree)
|
35
43
|
template_body = [] # local variable
|
36
44
|
outside_body = [] # local variable
|
37
45
|
subtree = [subtree] unless subtree.respond_to? :each
|
38
46
|
options = { :compiler_instance => self } # reset
|
39
|
-
subtree.each do |element|
|
40
|
-
|
41
|
-
|
47
|
+
subtree.each do |element|
|
48
|
+
if element.kind_of? Walrus::Grammar::DefDirective or
|
49
|
+
element.kind_of? Walrus::Grammar::IncludeDirective
|
50
|
+
# def/block and include directives may return two items
|
42
51
|
inner, outer = element.compile(options)
|
43
52
|
outer.each { |line| outside_body << OUTSIDE_INDENT + line } if outer
|
44
53
|
inner.each { |line| template_body << BODY_INDENT + line } if inner
|
45
|
-
elsif element.instance_of?
|
46
|
-
|
47
|
-
|
54
|
+
elsif element.instance_of? Walrus::Grammar::ExtendsDirective
|
55
|
+
# defines superclass and automatically invoke #super (super) at the
|
56
|
+
# head of the template_body
|
57
|
+
raise CompileError.new('#extends may be used only once per template') if @extends_directive
|
58
|
+
raise CompileError.new('illegal #extends (#import already used in this template)') if @import_directive
|
48
59
|
@extends_directive = element.compile(options)
|
49
|
-
elsif element.instance_of?
|
50
|
-
|
51
|
-
|
60
|
+
elsif element.instance_of? Walrus::Grammar::ImportDirective
|
61
|
+
# defines superclass with no automatic invocation of #super on the
|
62
|
+
# template_body
|
63
|
+
raise CompileError.new('#import may be used only once per template') if @import_directive
|
64
|
+
raise CompileError.new('illegal #import (#extends already used in this template)') if @extends_directive
|
52
65
|
@import_directive = element.compile(options)
|
53
|
-
elsif element.kind_of?
|
66
|
+
elsif element.kind_of? Walrus::Grammar::Comment and
|
67
|
+
element.column_start == 0
|
68
|
+
# special case if comment is only thing on input line
|
54
69
|
template_body << BODY_INDENT + element.compile(options)
|
55
70
|
options[:slurping] = true
|
56
71
|
next
|
57
|
-
else
|
58
|
-
element.compile(options).each
|
72
|
+
else # everything else gets added to the template_body
|
73
|
+
element.compile(options).each do |line|
|
74
|
+
template_body << BODY_INDENT + line # indent by 6 spaces
|
75
|
+
end
|
59
76
|
end
|
60
77
|
options = { :compiler_instance => self } # reset
|
61
78
|
end
|
62
79
|
[template_body, outside_body]
|
63
80
|
end
|
64
|
-
|
81
|
+
|
65
82
|
def compile(tree)
|
66
83
|
inner, outer = compile_subtree(tree)
|
67
84
|
@template_body.concat inner if inner
|
68
85
|
@outside_body.concat outer if outer
|
69
86
|
if @import_directive
|
70
87
|
superclass_name = @import_directive.class_name
|
71
|
-
require_line = "require 'walrus/document'\n" +
|
88
|
+
require_line = "require 'walrus/document'\n" +
|
89
|
+
@import_directive.require_line
|
72
90
|
elsif @extends_directive
|
73
91
|
superclass_name = @extends_directive.class_name
|
74
|
-
require_line = "require 'walrus/document'\n" +
|
75
|
-
|
92
|
+
require_line = "require 'walrus/document'\n" +
|
93
|
+
@extends_directive.require_line
|
94
|
+
@template_body.unshift BODY_INDENT +
|
95
|
+
"super # (invoked automatically due to Extends directive)\n"
|
76
96
|
else
|
77
97
|
superclass_name = 'Document'
|
78
98
|
require_line = "require 'walrus/document'"
|
@@ -92,39 +112,30 @@ end
|
|
92
112
|
#{require_line}
|
93
113
|
|
94
114
|
module Walrus
|
95
|
-
|
96
|
-
class WalrusGrammar
|
97
|
-
|
115
|
+
class Grammar
|
98
116
|
class #{@class_name} < #{superclass_name}
|
99
|
-
|
100
117
|
def template_body
|
101
|
-
|
102
118
|
#{@template_body.join}
|
103
119
|
end
|
104
120
|
|
105
|
-
#{@outside_body.join}
|
106
|
-
if __FILE__ == $0 #
|
107
|
-
new.run
|
121
|
+
#{@outside_body.join}
|
122
|
+
if __FILE__ == $0 # if run from the command line
|
123
|
+
new.run # same as "walrus run __FILE__"
|
108
124
|
end
|
109
|
-
|
110
125
|
end \# #{@class_name}
|
111
|
-
|
112
|
-
end \# WalrusGrammar
|
113
|
-
|
126
|
+
end \# Grammar
|
114
127
|
end \# Walrus
|
115
|
-
|
116
128
|
RETURN
|
117
|
-
|
118
129
|
end
|
119
|
-
|
120
130
|
end
|
121
|
-
|
122
|
-
# Walks the Abstract Syntax Tree, tree, that represents a parsed Walrus
|
123
|
-
#
|
131
|
+
|
132
|
+
# Walks the Abstract Syntax Tree, tree, that represents a parsed Walrus
|
133
|
+
# template.
|
134
|
+
#
|
135
|
+
# Returns a String that defines a Document subclass corresponding to the
|
136
|
+
# compiled version of the tree.
|
124
137
|
def compile(tree, options = {})
|
125
138
|
Instance.new(options).compile(tree)
|
126
139
|
end
|
127
|
-
|
128
140
|
end # class Compiler
|
129
141
|
end # module Walrus
|
130
|
-
|