Permalink
Browse files

[Hitomi::Interpolation] first cut at var interp

  • Loading branch information...
1 parent 1f57029 commit 3469b804f80341da190f76e86d6f5665bb123cc7 @masak committed Jul 25, 2009
Showing with 56 additions and 3 deletions.
  1. +39 −0 lib/Hitomi/Interpolation.pm
  2. +9 −1 lib/Hitomi/Markup.pm
  3. +6 −0 lib/Hitomi/Stream.pm
  4. +1 −1 lib/Hitomi/StreamEventKind.pm
  5. +1 −1 lib/Hitomi/XMLParser.pm
@@ -0,0 +1,39 @@
+use Hitomi::StreamEventKind;
+
+grammar Hitomi::Interpolation::Grammar {
+ regex TOP { ^ <chunk>* $ }
+ regex chunk { <plain> || <expr> }
+
+ regex plain { [<!after '$'> .]+ }
+ regex expr { '$' [ <identifier> | <block> ] }
+
+ regex ident { <.alpha> \w* }
+ regex identifier { <.ident> [ <.apostrophe> <.ident> ]* }
+ token apostrophe { <[ ' \- ]> }
+
+ regex block { '{' <-[{}]>+ '}' }
+}
+
+# Note: It _is_ possible for the above grammar to fail, even though it's
+# probably not very desirable that it can. An example of a failing
+# input is '$'. The way to fix this would likely be (1) see what
+# Genshi does about broken input, (2) write Hitomi tests to do the
+# same, (3) improve the grammar.
+
+sub interpolate($text, $filepath, $lineno = -1, $offset = 0,
+ $lookup = 'strict') {
+
+ # TODO: Make it impossible to fail here. See the above note.
+ return $text
+ unless Hitomi::Interpolation::Grammar.parse($text);
+
+ return gather for @($<chunk> // []) -> $chunk {
+ my $pos = [$filepath, $lineno, $offset];
+ if $chunk<plain> -> $plain {
+ take [Hitomi::StreamEventKind::text, ~$plain, $pos];
+ }
+ elsif $chunk<expr> -> $expr {
+ take [Hitomi::StreamEventKind::expr, ~$expr, $pos];
+ }
+ }
+}
View
@@ -1,4 +1,5 @@
use Hitomi::XMLParser;
+use Hitomi::Interpolation;
class Hitomi::Template {
has $!source;
@@ -57,9 +58,16 @@ class Hitomi::MarkupTemplate is Hitomi::Template {
for $source.llist -> @event {
my ($kind, $data, $pos) = @event;
- @stream.push( [$kind, $data, $pos] );
+ if $kind ~~ Hitomi::StreamEventKind::text {
+ @stream.push:
+ interpolate($data, $!filepath, $pos[1], $pos[2], $!lookup);
+ }
+ else {
+ @stream.push( [$kind, $data, $pos] );
+ }
}
+ warn .perl for @stream;
return Hitomi::Stream.new(@stream);
}
}
View
@@ -20,6 +20,12 @@ class Hitomi::Stream {
}
method Str() {
+ # RAKUDO: A complex set of circumstances may cause the
+ # array to have been nested one level too deeply at
+ # this point. Compensating.
+ if @!events.elems == 1 && @!events[0] ~~ Array {
+ @!events = @(@!events[0]);
+ }
return $serializer.serialize(self);
}
@@ -1,3 +1,3 @@
enum Hitomi::StreamEventKind <start end text xml-decl doctype start-ns end-ns
- start-cdata end-cdata pi comment empty>;
+ start-cdata end-cdata pi comment empty expr>;
View
@@ -52,7 +52,7 @@ class Hitomi::XMLParser {
];
push @events, [Hitomi::StreamEventKind::start, $data, *],
self.make-events($e, $text),
- [Hitomi::StreamEventKind::end, $data, *];
+ [Hitomi::StreamEventKind::end, ~$e<name>, *];
}
elsif $part<textnode> -> $t {
my $line-num = +$text.substr(0, $t.from).comb(/\n/) + 1;

0 comments on commit 3469b80

Please sign in to comment.