ltdtemplate 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.
- data/HISTORY.txt +15 -0
- data/TEMPLATE_MANUAL.html +838 -0
- data/lib/ltdtemplate/code/call.rb +46 -0
- data/lib/ltdtemplate/code/code_block.rb +30 -0
- data/lib/ltdtemplate/code/parameters.rb +40 -0
- data/lib/ltdtemplate/code/subscript.rb +81 -0
- data/lib/ltdtemplate/code/variable.rb +77 -0
- data/lib/ltdtemplate/code.rb +102 -0
- data/lib/ltdtemplate/value/array.rb +168 -0
- data/lib/ltdtemplate/value/boolean.rb +79 -0
- data/lib/ltdtemplate/value/code_block.rb +40 -0
- data/lib/ltdtemplate/value/namespace.rb +135 -0
- data/lib/ltdtemplate/value/nil.rb +27 -0
- data/lib/ltdtemplate/value/number.rb +93 -0
- data/lib/ltdtemplate/value/string.rb +121 -0
- data/lib/ltdtemplate.rb +451 -0
- data/ltdtemplate.gemspec +16 -0
- data/test/00class.rb +20 -0
- data/test/01instance.rb +30 -0
- data/test/02tpl_literal.rb +61 -0
- data/test/03tpl_singletons.rb +48 -0
- data/test/04number.rb +36 -0
- data/test/05string.rb +30 -0
- data/test/06array.rb +34 -0
- metadata +94 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
# LtdTemplate::Code::Call - Represents a method call in an LtdTemplate
|
2
|
+
#
|
3
|
+
# Author:: Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
|
4
|
+
# Copyright:: 2013 Brian Katzung and Kappa Computer Solutions, LLC
|
5
|
+
# License:: MIT License
|
6
|
+
|
7
|
+
require 'ltdtemplate/code'
|
8
|
+
|
9
|
+
class LtdTemplate::Code::Call < LtdTemplate::Code
|
10
|
+
|
11
|
+
# Initialize a method call object.
|
12
|
+
#
|
13
|
+
# @param template [LtdTemplate] The template object
|
14
|
+
# @param target [LtdTemplate::Code] The target object
|
15
|
+
# @param method [String] The method to call
|
16
|
+
# @param parameters [LtdTemplate::Code::Parameters] The call parameters
|
17
|
+
def initialize (template, target, method, parameters)
|
18
|
+
super template
|
19
|
+
@target, @method, @parameters = target, method, parameters
|
20
|
+
end
|
21
|
+
|
22
|
+
# Return the result of executing the call.
|
23
|
+
#
|
24
|
+
# @param opts [Hash] Option hash
|
25
|
+
# @option opts [String] :method A method to call on the return value
|
26
|
+
def get_value (opts = {})
|
27
|
+
# Increase the call count and call depth.
|
28
|
+
@template.use :calls
|
29
|
+
@template.use :call_depth
|
30
|
+
|
31
|
+
result = @target.get_value({ :method => @method,
|
32
|
+
:parameters => @parameters.get_value })
|
33
|
+
|
34
|
+
# Decrease the call depth.
|
35
|
+
@template.use :call_depth, -1
|
36
|
+
|
37
|
+
opts[:method] ? result.get_value(opts) : result
|
38
|
+
end
|
39
|
+
|
40
|
+
# Pass has/get/set_item calls through to result of call;
|
41
|
+
# in some cases it might be the same value each time.
|
42
|
+
def has_item? (key); get_value.has_item? key; end
|
43
|
+
def get_item (key); get_value.get_item key; end
|
44
|
+
def set_item (key, value); get_value.set_item key, value; end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# LtdTemplate::Code::Code_Block - Represents a code block (a list of
|
2
|
+
# code steps) in an LtdTemplate
|
3
|
+
#
|
4
|
+
# Implied code blocks do not accept parameters or generate new namespaces.
|
5
|
+
# They are used for things like call parameters and subscript expressions.
|
6
|
+
# See also: LtdTemplate::Value::Code_Block.
|
7
|
+
#
|
8
|
+
# Author:: Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
|
9
|
+
# Copyright:: 2013 Brian Katzung and Kappa Computer Solutions, LLC
|
10
|
+
# License:: MIT License
|
11
|
+
|
12
|
+
require 'ltdtemplate/code'
|
13
|
+
|
14
|
+
class LtdTemplate::Code::Code_Block < LtdTemplate::Code
|
15
|
+
|
16
|
+
def initialize (template, code)
|
17
|
+
super template
|
18
|
+
@code = code
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_value (opts = {})
|
22
|
+
values = @code.map { |part| part.get_value }.flatten
|
23
|
+
case values.size
|
24
|
+
when 0 then @template.factory :nil
|
25
|
+
when 1 then values[0]
|
26
|
+
else @template.factory(:array).set_value(values)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# LtdTemplate::Code::Parameters - Represents call parameters in an LtdTemplate
|
2
|
+
#
|
3
|
+
# Author:: Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
|
4
|
+
# Copyright:: 2013 Brian Katzung and Kappa Computer Solutions, LLC
|
5
|
+
# License:: MIT License
|
6
|
+
|
7
|
+
require 'ltdtemplate/code'
|
8
|
+
|
9
|
+
class LtdTemplate::Code::Parameters < LtdTemplate::Code
|
10
|
+
|
11
|
+
#
|
12
|
+
# Create a parameter list builder with code to generate positional
|
13
|
+
# values and possibly code to generate named values.
|
14
|
+
#
|
15
|
+
def initialize (template, positional = [], named = nil)
|
16
|
+
super template
|
17
|
+
|
18
|
+
# Save the code blocks for positional and named parameters.
|
19
|
+
@positional, @named = positional, named
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Evaluate the code provided for the positional and named parameters
|
24
|
+
# and return a corresponding array t-value.
|
25
|
+
#
|
26
|
+
def get_value (opts = {})
|
27
|
+
positional = @positional.map { |val| val.get_value }
|
28
|
+
named = {}
|
29
|
+
if @named
|
30
|
+
@named.each_slice(2) do |key, val|
|
31
|
+
named[key.get_value.to_native] = val.get_value
|
32
|
+
end
|
33
|
+
scalar = false
|
34
|
+
else
|
35
|
+
scalar = positional.size == 1
|
36
|
+
end
|
37
|
+
@template.factory(:array).set_value(positional, named, scalar)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# LtdTemplate::Code::Subscript - Represents an array subscript in
|
2
|
+
# an LtdTemplate
|
3
|
+
#
|
4
|
+
# Author:: Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
|
5
|
+
# Copyright:: 2013 Brian Katzung and Kappa Computer Solutions, LLC
|
6
|
+
# License:: MIT License
|
7
|
+
|
8
|
+
require 'ltdtemplate/code'
|
9
|
+
|
10
|
+
class LtdTemplate::Code::Subscript < LtdTemplate::Code
|
11
|
+
|
12
|
+
def initialize (template, base, subscripts)
|
13
|
+
super template
|
14
|
+
@base, @subscripts = base, subscripts
|
15
|
+
end
|
16
|
+
|
17
|
+
#
|
18
|
+
# Return native subscripts calculated from the supplied code blocks.
|
19
|
+
#
|
20
|
+
def native_subs (usage = false)
|
21
|
+
nsubs = @subscripts ?
|
22
|
+
@subscripts.map { |sub| sub.get_value.to_native }.flatten : []
|
23
|
+
num_subs = nsubs.size
|
24
|
+
if usage and num_subs > 0
|
25
|
+
@template.using :subscript_depth, num_subs
|
26
|
+
@template.use :subscripts, num_subs
|
27
|
+
end
|
28
|
+
nsubs
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# Return the target value, variable[sub1, ..., subN]
|
33
|
+
#
|
34
|
+
def target (usage = false)
|
35
|
+
current = @base.get_value
|
36
|
+
native_subs(usage).each { |subs| current = current.get_item subs }
|
37
|
+
current
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Implement the subscript interface for the target.
|
42
|
+
#
|
43
|
+
def has_item? (key); target.has_item? key; end
|
44
|
+
def get_item (key); target.get_item key; end
|
45
|
+
def set_item (key, value); target(true).set_item key, value; end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Set the target's value.
|
49
|
+
#
|
50
|
+
def set_value (value)
|
51
|
+
subs = native_subs true
|
52
|
+
if subs.size == 0
|
53
|
+
# If there are no subscripts, just use the base.
|
54
|
+
@base.set_value value
|
55
|
+
else
|
56
|
+
#
|
57
|
+
# Traverse all but the last subscript, trying to autovivicate
|
58
|
+
# new arrays as we go. This will silently fail if there is an
|
59
|
+
# existing non-array value somewhere.
|
60
|
+
#
|
61
|
+
current = @base
|
62
|
+
current.set_value @template.factory :array unless current.is_set?
|
63
|
+
subs[0..-2].each do |sub|
|
64
|
+
if !current.has_item? sub
|
65
|
+
current.set_item sub, @template.factory(:array)
|
66
|
+
end
|
67
|
+
current = current.get_item sub
|
68
|
+
end
|
69
|
+
current.set_item subs[-1], value
|
70
|
+
end
|
71
|
+
self
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_value (opts = {})
|
75
|
+
case opts[:method]
|
76
|
+
when '=' then do_set opts # see LtdTemplate::Code
|
77
|
+
else target.get_value opts
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# LtdTemplate::Code::Variable - Represents a variable in an LtdTemplate
|
2
|
+
#
|
3
|
+
# Author:: Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
|
4
|
+
# Copyright:: 2013 Brian Katzung and Kappa Computer Solutions, LLC
|
5
|
+
# License:: MIT License
|
6
|
+
|
7
|
+
require 'ltdtemplate/code'
|
8
|
+
|
9
|
+
class LtdTemplate::Code::Variable < LtdTemplate::Code
|
10
|
+
|
11
|
+
def initialize (template, name)
|
12
|
+
super template
|
13
|
+
case name[0]
|
14
|
+
when '@', '^'
|
15
|
+
# @var is in the root namespace
|
16
|
+
# ^var is in the parent namespace
|
17
|
+
@modifier = name[0]
|
18
|
+
@name = name[1..-1]
|
19
|
+
@name = @name.to_i if @name =~ /^(?:0|[1-9]\d*)$/
|
20
|
+
else
|
21
|
+
# Standard bottom-to-top namespace search variable
|
22
|
+
@modifier = nil
|
23
|
+
@name = name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# Return the namespace in which this variable currently resides
|
29
|
+
# (or would reside, if it doesn't currently exist).
|
30
|
+
#
|
31
|
+
def namespace
|
32
|
+
case @modifier
|
33
|
+
when '@' then base = @template.namespace.root
|
34
|
+
when '^' then base = @template.namespace.parent || @template.namespace
|
35
|
+
else base = @template.namespace
|
36
|
+
end
|
37
|
+
base.find_item(@name) || base
|
38
|
+
end
|
39
|
+
|
40
|
+
#
|
41
|
+
# Return the namespace item for this variable.
|
42
|
+
#
|
43
|
+
def target; namespace.get_item(@name); end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Implement the subscripting interface.
|
47
|
+
#
|
48
|
+
def has_item? (key); target.has_item? key; end
|
49
|
+
def get_item (key); target.get_item key; end
|
50
|
+
def set_item (key, value); target.set_item key, value; end
|
51
|
+
|
52
|
+
#
|
53
|
+
# Try to set the value.
|
54
|
+
#
|
55
|
+
def set_value (value)
|
56
|
+
namespace.set_item(@name, value)
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Is this variable set?
|
61
|
+
# Among other possible uses, this is needed for determining when to
|
62
|
+
# auto-vivicate array subscripts.
|
63
|
+
#
|
64
|
+
def is_set?; namespace.has_item? @name; end
|
65
|
+
|
66
|
+
def get_value (opts = {})
|
67
|
+
case opts[:method]
|
68
|
+
when '=' then do_set opts # see LtdTemplate::Code
|
69
|
+
when '?='
|
70
|
+
if is_set? then @template.factory :nil
|
71
|
+
else do_set opts
|
72
|
+
end
|
73
|
+
else target.get_value opts
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
class LtdTemplate; end
|
2
|
+
|
3
|
+
# LtdTemplate::Code - Base class for LtdTemplate code/value objects
|
4
|
+
#
|
5
|
+
# @author Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
|
6
|
+
# @copyright 2013 Brian Katzung and Kappa Computer Solutions, LLC
|
7
|
+
# @license MIT License
|
8
|
+
|
9
|
+
class LtdTemplate::Code
|
10
|
+
|
11
|
+
# @!attribute [r] tpl_methods
|
12
|
+
# @return [Array<LtdTemplate::Value::Code_Block>]
|
13
|
+
# The code blocks bound to non-array values.
|
14
|
+
attr_reader :tpl_methods
|
15
|
+
|
16
|
+
# Return a new factory object instance (or a singleton in some
|
17
|
+
# subclasses, e.g. nil).
|
18
|
+
#
|
19
|
+
# @param args [Array] Class-specific initializer parameters.
|
20
|
+
def self.instance (*args); self.new(*args); end
|
21
|
+
|
22
|
+
# Initialize the object with a link to the associated template.
|
23
|
+
#
|
24
|
+
# @param template [LtdTemplate] The associated template object.
|
25
|
+
def initialize (template)
|
26
|
+
@template = template
|
27
|
+
@tpl_methods = {}
|
28
|
+
end
|
29
|
+
|
30
|
+
# Does a non-array value have a particular template method?
|
31
|
+
#
|
32
|
+
# @param key [String] The (native) string for the method.
|
33
|
+
# @return [Boolean]
|
34
|
+
def has_item? (key); @tpl_methods.has_key? key; end
|
35
|
+
|
36
|
+
# Return a non-array value's method code block (if set).
|
37
|
+
#
|
38
|
+
# @param key [String] The (native) string for the method.
|
39
|
+
# @return [LtdTemplate::Value::Code_Block]
|
40
|
+
def get_item (key)
|
41
|
+
(@tpl_methods.has_key? key) ? @tpl_methods[key] :
|
42
|
+
@template.factory(:nil)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Set a non-array value's method code block.
|
46
|
+
#
|
47
|
+
# @param key [String] The (native) string for the method.
|
48
|
+
# @param value [LtdTemplate::Value::Code_Block] The code block
|
49
|
+
# for the method.
|
50
|
+
def set_item (key, value); @tpl_methods[key] = value; end
|
51
|
+
|
52
|
+
# No-op setting a value. (Typically only variables can change their
|
53
|
+
# primary values.)
|
54
|
+
#
|
55
|
+
# @param value The value to set. (Ignored.)
|
56
|
+
# @return [LtdTemplate::Code]
|
57
|
+
def set_value (value); self; end
|
58
|
+
|
59
|
+
# Is this value set? Always true except for unset variables.
|
60
|
+
#
|
61
|
+
# @return [true]
|
62
|
+
def is_set?; true; end
|
63
|
+
|
64
|
+
# Implement "=" (assignment). Note that set_value is a no-op except
|
65
|
+
# for variables and array subscripts.
|
66
|
+
#
|
67
|
+
# @param opts [Hash] A hash of method options.
|
68
|
+
# @option opts [LtdTemplate::Value::Parameters] :parameters The method
|
69
|
+
# parameters.
|
70
|
+
# @return [LtdTemplate::Value::Nil]
|
71
|
+
def do_set (opts)
|
72
|
+
if params = opts[:parameters]
|
73
|
+
set_value(params.scalar? ? params.positional[0] : params)
|
74
|
+
end
|
75
|
+
@template.factory :nil
|
76
|
+
end
|
77
|
+
|
78
|
+
# Try to execute code-block methods bound to the object or object
|
79
|
+
# class. Returns the return value from the code block or t-nil.
|
80
|
+
def do_method (opts, class_name = nil)
|
81
|
+
method = nil
|
82
|
+
if name = opts[:method]
|
83
|
+
if @tpl_methods.has_key? name
|
84
|
+
method = @tpl_methods[name]
|
85
|
+
elsif class_name
|
86
|
+
class_var = @template.factory :variable, class_name
|
87
|
+
method = class_var.target.tpl_methods[name] if
|
88
|
+
class_var.is_set?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
if method
|
92
|
+
opts[:target] = self
|
93
|
+
method.get_value opts
|
94
|
+
else
|
95
|
+
@template.factory :nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
# This is the parent namespace for value code classes.
|
102
|
+
class LtdTemplate::Value; end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# LtdTemplate::Value::Array - Represents a combination array/hash value
|
2
|
+
# in an LtdTemplate
|
3
|
+
#
|
4
|
+
# @author Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
|
5
|
+
# @copyright 2013 Brian Katzung and Kappa Computer Solutions, LLC
|
6
|
+
# @license MIT License
|
7
|
+
|
8
|
+
require 'ltdtemplate/code'
|
9
|
+
require 'sarah'
|
10
|
+
|
11
|
+
class LtdTemplate::Value::Array < LtdTemplate::Code
|
12
|
+
|
13
|
+
attr_reader :sarah
|
14
|
+
|
15
|
+
def initialize (template)
|
16
|
+
super template
|
17
|
+
@sarah = Sarah.new
|
18
|
+
@scalar = false
|
19
|
+
@template.use :arrays
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Access positional (sequential) or named (random-access)
|
24
|
+
# parts of the array
|
25
|
+
#
|
26
|
+
def positional; @sarah.seq; end
|
27
|
+
def named; @sarah.rnd; end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Implement the subscripting interface. Note that the most recent
|
31
|
+
# value is always used. (1 .. 0, 2, 0, 3)[0] is 3.
|
32
|
+
# Items set within (or at the end of) the positional range at the
|
33
|
+
# time will be positional. Otherwise, they will be named.
|
34
|
+
#
|
35
|
+
# Keys must be Ruby-native values; values must be template code
|
36
|
+
# or values.
|
37
|
+
#
|
38
|
+
def has_item? (key); @sarah.has_key? key; end
|
39
|
+
def get_item (key)
|
40
|
+
@sarah.has_key?(key) ? @sarah[key] : @template.factory(:nil)
|
41
|
+
end
|
42
|
+
def set_item (key, value)
|
43
|
+
@sarah[key] = value
|
44
|
+
@template.using :array_size, @sarah.size
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_boolean; true; end
|
48
|
+
def to_native; @sarah.seq.map { |val| val.to_native }; end
|
49
|
+
def to_text; @sarah.seq.map { |val| val.to_text }.join ''; end
|
50
|
+
|
51
|
+
def get_value (opts = {})
|
52
|
+
case opts[:method]
|
53
|
+
when nil, 'call' then self
|
54
|
+
when 'class' then @template.factory :string, 'Array'
|
55
|
+
when 'join' then do_join opts
|
56
|
+
when 'pop', '->' then do_pop opts
|
57
|
+
when 'push', '+>' then do_push opts
|
58
|
+
when 'rnd_size' then @template.factory :number, @sarah.rnd_size
|
59
|
+
when 'seq_size' then @template.factory :number, @sarah.seq_size
|
60
|
+
when 'shift', '<-' then do_shift opts
|
61
|
+
when 'size' then @template.factory :number, @sarah.size
|
62
|
+
when 'type' then @template.factory :string, 'array'
|
63
|
+
when 'unshift', '<+' then do_unshift opts
|
64
|
+
else do_method opts, 'Array'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Scalar assignment is used instead of array assignment if the
|
70
|
+
# parameter list contains exactly one positional parameter and
|
71
|
+
# the ".." operator was not used.
|
72
|
+
#
|
73
|
+
def scalar?; @scalar and @sarah.seq_size == 1; end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Clear all current positional and named values
|
77
|
+
#
|
78
|
+
def clear
|
79
|
+
@sarah.clear
|
80
|
+
@scalar = false
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Set positional and possibly named values. Keys must be ruby-native
|
86
|
+
# values; values must be template code or values.
|
87
|
+
#
|
88
|
+
def set_value (positional, named = {}, scalar = false)
|
89
|
+
clear
|
90
|
+
@sarah.merge! positional, named
|
91
|
+
@scalar = scalar
|
92
|
+
self
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Set (recursively) from a native array.
|
97
|
+
#
|
98
|
+
def set_from_array (data)
|
99
|
+
clear
|
100
|
+
data.each_index { |i| set_item i, map_native_value(data[i]) }
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
#
|
105
|
+
# Set (recursively) from a native hash.
|
106
|
+
#
|
107
|
+
def set_from_hash (data)
|
108
|
+
clear
|
109
|
+
data.each { |key, val| set_item key, map_native_value(val) }
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Combine array element values into a string
|
115
|
+
#
|
116
|
+
def do_join (opts)
|
117
|
+
two = first = middle = last = ''
|
118
|
+
if params = opts[:parameters]
|
119
|
+
params = params.positional
|
120
|
+
if params.size > 3
|
121
|
+
two, first, middle, last =
|
122
|
+
params[0..3].map { |val| val.get_value.to_text }
|
123
|
+
elsif params.size > 0
|
124
|
+
two = first = middle = last = params[0].get_value.to_text
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
text = @sarah.seq.map { |val| val.get_value.to_text }
|
129
|
+
@template.factory :string, case text.size
|
130
|
+
when 0 then ''
|
131
|
+
when 1 then text[0]
|
132
|
+
when 2 then "#{text[0]}#{two}#{text[1]}"
|
133
|
+
else "#{text[0]}#{first}" + text[1..-2].join(middle) +
|
134
|
+
"#{last}#{text[-1]}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def do_pop (opts)
|
139
|
+
@sarah.pop || @template.factory(:nil)
|
140
|
+
end
|
141
|
+
|
142
|
+
def do_push (opts)
|
143
|
+
if params = opts[:parameters] then @sarah.append! params.sarah end
|
144
|
+
@template.factory :nil
|
145
|
+
end
|
146
|
+
|
147
|
+
def do_shift (opts)
|
148
|
+
@sarah.shift || @template.factory(:nil)
|
149
|
+
end
|
150
|
+
|
151
|
+
def do_unshift (opts)
|
152
|
+
if params = opts[:parameters] then @sarah.insert! params.sarah end
|
153
|
+
@template.factory :nil
|
154
|
+
end
|
155
|
+
|
156
|
+
protected
|
157
|
+
|
158
|
+
def map_native_value (value)
|
159
|
+
return @template.factory :number, value if value.is_a? Numeric
|
160
|
+
return @template.factory :string, value if value.is_a? String
|
161
|
+
return @template.factory(:array).set_from_array value if
|
162
|
+
value.is_a? Array
|
163
|
+
return @template.factory(:array).set_from_hash value if
|
164
|
+
value.is_a? Hash
|
165
|
+
@template.factory :nil
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# LtdTemplate::Value::Boolean - Represents true/false in an LtdTemplate
|
2
|
+
#
|
3
|
+
# @author Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
|
4
|
+
# @copyright 2013 Brian Katzung and Kappa Computer Solutions, LLC
|
5
|
+
# @license MIT License
|
6
|
+
|
7
|
+
require 'ltdtemplate/code'
|
8
|
+
|
9
|
+
class LtdTemplate::Value::Boolean < LtdTemplate::Code
|
10
|
+
|
11
|
+
# Use one shared true value and one shared false value per template.
|
12
|
+
def self.instance (template, bool)
|
13
|
+
template.factory_singletons[bool ? :bool_true : :bool_false] ||=
|
14
|
+
self.new(template, bool)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize (template, bool)
|
18
|
+
super template
|
19
|
+
@bool = bool
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_boolean; @bool; end
|
23
|
+
def to_native; @bool; end
|
24
|
+
def to_text; ''; end
|
25
|
+
|
26
|
+
def get_value (opts = {})
|
27
|
+
case opts[:method]
|
28
|
+
when nil, 'call' then self
|
29
|
+
when 'class' then @template.factory :string, 'Boolean'
|
30
|
+
when 'str', 'string' then @template.factory :string,
|
31
|
+
(@bool ? 'true' : 'false')
|
32
|
+
when 'type' then @template.factory :string, 'boolean'
|
33
|
+
when '+', '|', 'or' then do_or opts
|
34
|
+
when '*', '&', 'and' then do_and opts
|
35
|
+
when '!', 'not' then do_not opts
|
36
|
+
else do_method opts, 'Boolean'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Implement +/| (or):
|
41
|
+
# bool|(bool1, ..., boolN)
|
42
|
+
# True if ANY boolean is true. Evaluates {} blocks until true.
|
43
|
+
def do_or (opts)
|
44
|
+
if not @bool and params = opts[:parameters]
|
45
|
+
params.positional.each do |tval|
|
46
|
+
return @template.factory :boolean, true if
|
47
|
+
tval.get_value(:method => 'call').to_boolean
|
48
|
+
end
|
49
|
+
end
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
# Implement */& (and):
|
54
|
+
# bool&(bool1, ..., boolN)
|
55
|
+
# True if ALL booleans are true. Evaluates {} blocks until false.
|
56
|
+
def do_and (opts)
|
57
|
+
if @bool and params = opts[:parameters]
|
58
|
+
params.positional.each do |tval|
|
59
|
+
return @template.factory :boolean, false unless
|
60
|
+
tval.get_value(:method => 'call').to_boolean
|
61
|
+
end
|
62
|
+
end
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
# Implement ! (not):
|
67
|
+
# bool!(bool1, ..., boolN)
|
68
|
+
# True if ALL booleans are false. Evaluates {} blocks until true.
|
69
|
+
def do_not (opts)
|
70
|
+
if !@bool and params = opts[:parameters]
|
71
|
+
params.positional.each do |tval|
|
72
|
+
return @template.factory :boolean, false if
|
73
|
+
tval.get_value(:method => 'call').to_boolean
|
74
|
+
end
|
75
|
+
end
|
76
|
+
@template.factory :boolean, !@bool
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# LtdTemplate::Value::Code_Block - Represents an explicit code block in an
|
2
|
+
# LtdTemplate
|
3
|
+
#
|
4
|
+
# Explicit code blocks are wrappers around implied code blocks. They are
|
5
|
+
# essentially anonymous functions; they accept optional parameters and
|
6
|
+
# create a new namespace for the duration of each execution.
|
7
|
+
#
|
8
|
+
# @author Brian Katzung <briank@kappacs.com>, Kappa Computer Solutions, LLC
|
9
|
+
# @copyright 2013 Brian Katzung and Kappa Computer Solutions, LLC
|
10
|
+
# @license MIT License
|
11
|
+
|
12
|
+
require 'ltdtemplate/code'
|
13
|
+
|
14
|
+
class LtdTemplate::Value::Code_Block < LtdTemplate::Code
|
15
|
+
|
16
|
+
attr_reader :code
|
17
|
+
|
18
|
+
def initialize (template, code)
|
19
|
+
super template
|
20
|
+
@code = code
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_boolean; true; end
|
24
|
+
def to_native; self; end
|
25
|
+
def to_text; ''; end
|
26
|
+
|
27
|
+
def get_value (opts = {})
|
28
|
+
case opts[:method]
|
29
|
+
when nil then self
|
30
|
+
when 'type' then @template.factory :string, 'code'
|
31
|
+
else
|
32
|
+
@template.push_namespace opts[:method], opts[:parameters],
|
33
|
+
:target => (opts[:target] || self)
|
34
|
+
result = @code.get_value
|
35
|
+
@template.pop_namespace
|
36
|
+
result
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|