hotcell 0.0.1 → 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +4 -1
- data/.rspec +1 -0
- data/.rvmrc +1 -1
- data/.travis.yml +7 -0
- data/Gemfile +4 -1
- data/README.md +361 -2
- data/Rakefile +28 -6
- data/ext/lexerc/extconf.rb +3 -0
- data/ext/lexerc/lexerc.c +618 -0
- data/ext/lexerc/lexerc.h +20 -0
- data/ext/lexerc/lexerc.rl +167 -0
- data/hotcell.gemspec +8 -7
- data/lib/hotcell/commands/case.rb +59 -0
- data/lib/hotcell/commands/cycle.rb +38 -0
- data/lib/hotcell/commands/for.rb +70 -0
- data/lib/hotcell/commands/if.rb +51 -0
- data/lib/hotcell/commands/include.rb +21 -0
- data/lib/hotcell/commands/scope.rb +13 -0
- data/lib/hotcell/commands/unless.rb +23 -0
- data/lib/hotcell/commands.rb +13 -0
- data/lib/hotcell/config.rb +33 -6
- data/lib/hotcell/context.rb +40 -7
- data/lib/hotcell/errors.rb +37 -28
- data/lib/hotcell/extensions.rb +4 -0
- data/lib/hotcell/lexer.rb +19 -635
- data/lib/hotcell/lexerr.rb +572 -0
- data/lib/hotcell/lexerr.rl +137 -0
- data/lib/hotcell/node/assigner.rb +1 -5
- data/lib/hotcell/node/block.rb +17 -40
- data/lib/hotcell/node/command.rb +29 -22
- data/lib/hotcell/node/hasher.rb +1 -1
- data/lib/hotcell/node/summoner.rb +2 -6
- data/lib/hotcell/node/tag.rb +10 -7
- data/lib/hotcell/node.rb +12 -1
- data/lib/hotcell/parser.rb +474 -408
- data/lib/hotcell/parser.y +175 -117
- data/lib/hotcell/resolver.rb +44 -0
- data/lib/hotcell/source.rb +35 -0
- data/lib/hotcell/template.rb +15 -6
- data/lib/hotcell/version.rb +1 -1
- data/lib/hotcell.rb +15 -10
- data/spec/data/templates/simple.hc +1 -0
- data/spec/lib/hotcell/commands/case_spec.rb +39 -0
- data/spec/lib/hotcell/commands/cycle_spec.rb +29 -0
- data/spec/lib/hotcell/commands/for_spec.rb +65 -0
- data/spec/lib/hotcell/commands/if_spec.rb +35 -0
- data/spec/lib/hotcell/commands/include_spec.rb +39 -0
- data/spec/lib/hotcell/commands/scope_spec.rb +16 -0
- data/spec/lib/hotcell/commands/unless_spec.rb +23 -0
- data/spec/lib/hotcell/config_spec.rb +35 -10
- data/spec/lib/hotcell/context_spec.rb +58 -18
- data/spec/lib/hotcell/lexer_spec.rb +37 -28
- data/spec/lib/hotcell/node/block_spec.rb +28 -56
- data/spec/lib/hotcell/node/command_spec.rb +7 -31
- data/spec/lib/hotcell/node/tag_spec.rb +16 -0
- data/spec/lib/hotcell/parser_spec.rb +152 -123
- data/spec/lib/hotcell/resolver_spec.rb +28 -0
- data/spec/lib/hotcell/source_spec.rb +41 -0
- data/spec/lib/hotcell/template_spec.rb +47 -4
- data/spec/lib/hotcell_spec.rb +2 -1
- data/spec/spec_helper.rb +6 -2
- metadata +54 -24
- data/lib/hotcell/.DS_Store +0 -0
- data/lib/hotcell/lexer.rl +0 -299
- data/misc/rage.rl +0 -1999
- data/misc/unicode2ragel.rb +0 -305
data/lib/hotcell/node/block.rb
CHANGED
@@ -1,22 +1,27 @@
|
|
1
1
|
module Hotcell
|
2
2
|
class Block < Hotcell::Command
|
3
|
-
class_attribute :
|
4
|
-
self.
|
3
|
+
class_attribute :subcommands, instance_writter: false, instance_reader: false
|
4
|
+
self.subcommands = {}
|
5
5
|
|
6
|
-
def self.
|
7
|
-
if
|
8
|
-
self.
|
6
|
+
def self.subcommand name_or_hash, &block
|
7
|
+
if name_or_hash.is_a? Hash
|
8
|
+
self.subcommands = subcommands.merge(name_or_hash.stringify_keys)
|
9
9
|
else
|
10
|
-
|
10
|
+
subcommand name_or_hash => Class.new(Hotcell::Command, &block)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
14
|
+
def validate!
|
15
|
+
subcommands.each do |subcommand|
|
16
|
+
raise Hotcell::BlockError.new(
|
17
|
+
"Unexpected subcommand `#{subcommand.name}` for `#{name}` command",
|
18
|
+
*subcommand.position_info
|
19
|
+
) unless self.class.subcommands.key?(subcommand.name)
|
19
20
|
end
|
21
|
+
|
22
|
+
super
|
23
|
+
|
24
|
+
subcommands.each(&:validate!)
|
20
25
|
end
|
21
26
|
|
22
27
|
def subnodes
|
@@ -24,35 +29,7 @@ module Hotcell
|
|
24
29
|
end
|
25
30
|
|
26
31
|
def subcommands
|
27
|
-
subnodes.select { |node| node.is_a?(
|
28
|
-
end
|
29
|
-
|
30
|
-
def validate!
|
31
|
-
valid = subcommands.map { |subcommand| subcommand[:name] } - _subcommands == []
|
32
|
-
raise Hotcell::Errors::BlockError.new 'Invalid block syntax' unless valid
|
33
|
-
end
|
34
|
-
|
35
|
-
def process context, subnodes, *args
|
36
|
-
end
|
37
|
-
|
38
|
-
def render context
|
39
|
-
context.safe do
|
40
|
-
subnodes = render_subnodes(context)
|
41
|
-
values = render_nodes(context, children)
|
42
|
-
concat context, process(context, subnodes, *values)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def render_subnodes context
|
47
|
-
subnodes.map do |node|
|
48
|
-
if node.is_a?(Hash)
|
49
|
-
subcommand = { name: node[:name] }
|
50
|
-
subcommand.merge!(args: node[:args].render(context)) if node[:args]
|
51
|
-
subcommand
|
52
|
-
else
|
53
|
-
node.render(context)
|
54
|
-
end
|
55
|
-
end
|
32
|
+
subnodes.select { |node| node.is_a?(Hotcell::Command) }
|
56
33
|
end
|
57
34
|
end
|
58
35
|
end
|
data/lib/hotcell/node/command.rb
CHANGED
@@ -1,22 +1,39 @@
|
|
1
1
|
module Hotcell
|
2
2
|
class Command < Hotcell::Node
|
3
|
-
|
3
|
+
class_attribute :_validations
|
4
|
+
self._validations = {}
|
4
5
|
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
if klass = Hotcell.commands[name]
|
13
|
-
klass.new name, *children, options
|
6
|
+
def self.validate_arguments_count options
|
7
|
+
arguments_count = case options
|
8
|
+
when Hash
|
9
|
+
Range.new(options[:min].to_i,
|
10
|
+
options[:max].present? ? options[:max].to_i : Float::INFINITY)
|
11
|
+
when Range
|
12
|
+
options
|
14
13
|
else
|
15
|
-
|
14
|
+
options.to_i
|
16
15
|
end
|
16
|
+
|
17
|
+
self._validations = _validations.merge(arguments_count: arguments_count)
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate_arguments_count!
|
21
|
+
return unless _validations.key?(:arguments_count)
|
22
|
+
|
23
|
+
args_count = children.count
|
24
|
+
valid_args_count = _validations[:arguments_count]
|
25
|
+
|
26
|
+
valid = valid_args_count.is_a?(Integer) ?
|
27
|
+
args_count == valid_args_count : valid_args_count.include?(args_count)
|
28
|
+
|
29
|
+
raise Hotcell::ArgumentError.new(
|
30
|
+
"Wrond number of arguments for `#{name}` (#{args_count} for #{valid_args_count})",
|
31
|
+
*position_info
|
32
|
+
) unless valid
|
17
33
|
end
|
18
34
|
|
19
35
|
def validate!
|
36
|
+
validate_arguments_count!
|
20
37
|
end
|
21
38
|
|
22
39
|
def process context, *args
|
@@ -24,17 +41,7 @@ module Hotcell
|
|
24
41
|
|
25
42
|
def render context
|
26
43
|
context.safe do
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def concat context, result
|
32
|
-
context[assign] = result if assign
|
33
|
-
case mode
|
34
|
-
when :normal
|
35
|
-
result
|
36
|
-
else
|
37
|
-
''
|
44
|
+
process(context, *render_children(context))
|
38
45
|
end
|
39
46
|
end
|
40
47
|
end
|
data/lib/hotcell/node/hasher.rb
CHANGED
@@ -1,11 +1,7 @@
|
|
1
1
|
module Hotcell
|
2
2
|
class Summoner < Hotcell::Node
|
3
|
-
def
|
4
|
-
|
5
|
-
end
|
6
|
-
|
7
|
-
def process context, object, method, *arguments
|
8
|
-
(object.to_manipulator || context).manipulator_invoke(method, *arguments)
|
3
|
+
def process context, target = nil, *arguments
|
4
|
+
(target ? target.to_manipulator : context).manipulator_invoke(name, *arguments)
|
9
5
|
end
|
10
6
|
end
|
11
7
|
end
|
data/lib/hotcell/node/tag.rb
CHANGED
@@ -13,13 +13,16 @@ module Hotcell
|
|
13
13
|
|
14
14
|
def render context
|
15
15
|
context.safe do
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
concat context, process(context, *render_children(context))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def concat context, result
|
21
|
+
case mode
|
22
|
+
when :normal
|
23
|
+
result
|
24
|
+
else
|
25
|
+
''
|
23
26
|
end
|
24
27
|
end
|
25
28
|
end
|
data/lib/hotcell/node.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Hotcell
|
2
2
|
class Node
|
3
3
|
attr_accessor :name, :children, :options
|
4
|
+
attr_reader :position, :source
|
4
5
|
|
5
6
|
def self.build *args
|
6
7
|
new(*args).optimize
|
@@ -9,9 +10,15 @@ module Hotcell
|
|
9
10
|
def initialize name, *args
|
10
11
|
@name = name
|
11
12
|
@options = args.extract_options!
|
13
|
+
@source = @options.delete(:source)
|
14
|
+
@position = @options.delete(:position)
|
12
15
|
@children = args
|
13
16
|
end
|
14
17
|
|
18
|
+
def position_info
|
19
|
+
source.info(position).values_at(:line, :column)
|
20
|
+
end
|
21
|
+
|
15
22
|
def optimize
|
16
23
|
self
|
17
24
|
end
|
@@ -21,7 +28,7 @@ module Hotcell
|
|
21
28
|
end
|
22
29
|
|
23
30
|
def render context
|
24
|
-
process context, *
|
31
|
+
process context, *render_children(context)
|
25
32
|
end
|
26
33
|
|
27
34
|
def process context, *values
|
@@ -34,6 +41,10 @@ module Hotcell
|
|
34
41
|
end
|
35
42
|
end
|
36
43
|
|
44
|
+
def render_children context
|
45
|
+
render_nodes context, children
|
46
|
+
end
|
47
|
+
|
37
48
|
def == other
|
38
49
|
other.is_a?(self.class) &&
|
39
50
|
name == other.name &&
|