summaryrefslogtreecommitdiffstats
path: root/lib/Text/Xslate/Syntax/Handlebars.pm
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2012-09-28 17:32:46 -0500
committerJesse Luehrs <doy@tozt.net>2012-09-28 17:32:46 -0500
commitc964148db9790676e892265327f567939619c349 (patch)
tree8823cc12b17e18d1c17cd2f472a6933f0c89e607 /lib/Text/Xslate/Syntax/Handlebars.pm
parent5d1c22c9436077c5e3dede4abe55dbc8713a1e4c (diff)
downloadtext-handlebars-c964148db9790676e892265327f567939619c349.tar.gz
text-handlebars-c964148db9790676e892265327f567939619c349.zip
get blocks working
Diffstat (limited to 'lib/Text/Xslate/Syntax/Handlebars.pm')
-rw-r--r--lib/Text/Xslate/Syntax/Handlebars.pm87
1 files changed, 87 insertions, 0 deletions
diff --git a/lib/Text/Xslate/Syntax/Handlebars.pm b/lib/Text/Xslate/Syntax/Handlebars.pm
index 3f63f68..0cfc1e0 100644
--- a/lib/Text/Xslate/Syntax/Handlebars.pm
+++ b/lib/Text/Xslate/Syntax/Handlebars.pm
@@ -127,8 +127,17 @@ sub init_symbols {
$name->set_led($self->can('led_name'));
$name->lbp(1);
+ my $for = $self->symbol('(for)');
+ $for->arity('for');
+
+ my $iterator = $self->symbol('(iterator)');
+ $iterator->arity('iterator');
+
$self->infix('.', 256, $self->can('led_dot'));
$self->infix('/', 256, $self->can('led_dot'));
+
+ $self->symbol('#')->set_std($self->can('std_block'));
+ $self->prefix('/', 0)->is_block_end(1);
}
sub nud_name {
@@ -166,6 +175,73 @@ sub led_dot {
return $dot;
}
+sub std_block {
+ my $self = shift;
+ my ($symbol) = @_;
+
+ if ($self->token->arity ne 'name') {
+ $self->_unexpected("block name", $self->token);
+ }
+ my $name = $self->token->nud($self);
+ $self->advance;
+ $self->advance(';');
+
+ my $body = $self->statements;
+
+ $self->advance('/');
+
+ if ($self->token->arity ne 'name') {
+ $self->_unexpected("block name", $self->token);
+ }
+ if ($self->token->id ne $name->id) {
+ $self->_unexpected('/' . $name->id, $self->token);
+ }
+
+ $self->advance;
+
+ my $iterations = $self->make_ternary(
+ $self->call('(is_array)', $name->clone),
+ $name->clone,
+ $self->make_ternary(
+ $name->clone,
+ $self->call(
+ '(make_array)',
+ $self->symbol('(literal)')->clone(id => 1),
+ ),
+ $self->call(
+ '(make_array)',
+ $self->symbol('(literal)')->clone(id => 0),
+ ),
+ ),
+ );
+
+ my $loop_var = $self->symbol('(variable)')->clone(id => '(block)');
+
+ my $body_block = [
+ $symbol->clone(
+ arity => 'block',
+ first => [
+ $self->call(
+ '(new_vars_for)',
+ $self->symbol('(vars)')->clone(arity => 'vars'),
+ $name->clone,
+ $self->symbol('(iterator)')->clone(
+ id => '$~(block)',
+ first => $loop_var,
+ ),
+ ),
+ ],
+ second => $body,
+ ),
+ ];
+
+ return $self->symbol('(for)')->clone(
+ first => $iterations,
+ second => [$loop_var],
+ third => $body_block,
+ );
+}
+
sub make_field_lookup {
my $self = shift;
my ($var, $field, $dot) = @_;
@@ -183,6 +259,17 @@ sub make_field_lookup {
);
}
+sub make_ternary {
+ my $self = shift;
+ my ($if, $then, $else) = @_;
+ return $self->symbol('?:')->clone(
+ arity => 'if',
+ first => $if,
+ second => $then,
+ third => $else,
+ );
+}
+
if (0) {
require Devel::STDERR::Indent;
my @stack;