4 # Copyright (C) 2002-2005, The Perl Foundation.
5 # This program is free software. It is subject to the same license
6 # as the Parrot interpreter.
14 package Jako
::Construct
::Expression
::Value
::Literal
;
18 use base
qw(Jako::Construct::Expression::Value);
22 my ( $block, $token ) = @_;
28 TYPE
=> Jako
::Construct
::Type
->new( $token->type ),
29 VALUE
=> $token->text,
40 # By default, compiling a literal does nothing, returning you
41 # the literal for you to use in other compilations. But, string
42 # literals are subject to interpolation, and so they go through
43 # compilation in such a way that a string register value results
44 # for use by further compilations. This register value is
45 # returned to the caller.
47 # Converts a single string argument:
51 # to multiple arguments:
53 # "Foo ", a, " ", b, "ar ", b, "\n"
55 # to effect string interpolation.
62 confess
"No Compiler!" unless defined $compiler;
64 my $type = $self->type;
66 # $self->DEBUG(0, "Compiling literal of type: '%s'...", ref $type);
68 if ( UNIVERSAL
::isa
( $type, 'Jako::Construct::Type::String' ) ) {
69 my $string = $self->value;
71 # $self->DEBUG(0, "Compiling string literal: '%s'...", $self->value);
73 return $string unless $string =~ m/(^"|^".*?[^\\])\$/; # Double-quote with an unescaped '$'.
75 $string = substr( $string, 1, -1 ); # Without the surrounding double quotes.
77 my $temp = $compiler->temp_str(); # Allocate and clear a temporary string register
79 $compiler->emit(" $temp = \"\"");
83 unless defined $string
85 m/(^|^.*?[^\\])\$((([A-Za-z][A-Za-z0-9_]*)\b)|({[A-Za-z][A-Za-z0-9_]*}))(.*)$/;
87 $compiler->emit(" concat $temp, \"$1\"")
88 if defined $1 and $1 ne '';
91 $ident =~ s/^{(.*)}$/$1/; # Strip '{' and '}'.
93 my $sym = $self->block->find_symbol($ident);
96 Jako
::Construct
::Expression
::Value
::Identifier
->compile2( $compiler, $self->block,
97 $ident, $sym->kind, $sym->scope, $sym->type );
99 $self->SYNTAX_ERROR( "Cannot interpolate '%s': symbol not found!", $ident )
102 if ( not UNIVERSAL
::isa
( $sym->type, 'Jako::Construct::Type::String' ) ) {
103 my $temp2 = $compiler->temp_str();
104 $compiler->emit(" $temp2 = $ident");
108 $compiler->emit(" concat $temp, $ident");
113 $compiler->emit(" concat $temp, \"$string\"")
114 if defined $string and $string ne '';
120 # $self->DEBUG(0, "Compiling non-string literal: '%s'...", $self->value);
129 # TODO: Convert escapes. For example, "\n" should be an actual newline.
136 my $type = $self->type;
138 if ( UNIVERSAL
::isa
( $type, 'Jako::Construct::Type::String' ) ) {
139 my $string = $self->value;
141 if ( $string =~ m/(^"|^".*?[^\\])\$/ ) { # Double-quote with an unescaped '$'.
142 $string = substr( $string, 1, -1 ); # Without the surrounding double quotes.
144 $handler->start_element( { Name
=> 'concat' } );
148 unless defined $string
150 m/(^|^.*?[^\\])\$((([A-Za-z][A-Za-z0-9_]*)\b)|({[A-Za-z][A-Za-z0-9_]*}))(.*)$/;
152 if ( defined $1 and $1 ne '' ) {
153 $handler->start_element(
154 { Name
=> 'literal', Attributes
=> { type
=> $type->name } } );
155 $handler->characters( { Data
=> $1 } );
156 $handler->end_element( { Name
=> 'literal' } );
160 $ident =~ s/^{(.*)}$/$1/; # Strip '{' and '}'.
162 $handler->start_element( { Name
=> 'ident', Attributes
=> { name
=> $ident } } );
163 $handler->end_element( { Name
=> 'ident' } );
168 if ( defined $string and $string ne '' ) {
169 $handler->start_element(
170 { Name
=> 'literal', Attributes
=> { type
=> $type->name } } );
171 $handler->characters( { Data
=> $string } );
172 $handler->end_element( { Name
=> 'literal' } );
175 $handler->end_element( { Name
=> 'concat' } );
178 $string = substr( $string, 1, -1 ); # Without the surrounding quotes.
180 $handler->start_element( { Name
=> 'literal', Attributes
=> { type
=> $type->name } } );
181 $handler->characters( { Data
=> $string } );
182 $handler->end_element( { Name
=> 'literal' } );
186 $handler->start_element( { Name
=> 'literal', Attributes
=> { type
=> $type->name } } );
187 $handler->characters( { Data
=> $self->value } );
188 $handler->end_element( { Name
=> 'literal' } );
197 # cperl-indent-level: 4
200 # vim: expandtab shiftwidth=4: