scanner/string-escape-x-digit-length.test \
scanner/string-escape-x-empty.test \
scanner/string-escape-x.vala \
+ scanner/string-template.vala \
+ scanner/string-verbatim-template.vala \
parser/argument-list-incomplete.test \
parser/array-creation-invalid.test \
parser/array-length.vala \
parser/using-invalid-namespace.test \
parser/var-type-dynamic.vala \
parser/var-type-nullable.vala \
+ parser/verbatim-template.vala \
parser/with-embedded.vala \
parser/with-empty.vala \
parser/with-invalid-declaration.test \
genie/struct-after-class.gs \
genie/try-except-finally.gs \
genie/typeof.gs \
+ genie/verbatim-template.gs \
genie/while.gs \
glib/conditional-glib-api.vala \
bindings/gio/memoryoutputstream.vala \
#include <string.h>
#include <glib.h>
+#if !defined(VALA_EXTERN)
+#if defined(_MSC_VER)
+#define VALA_EXTERN __declspec(dllexport) extern
+#elif __GNUC__ >= 4
+#define VALA_EXTERN __attribute__((visibility("default"))) extern
+#else
+#define VALA_EXTERN extern
+#endif
+#endif
+
#define _g_free0(var) (var = (g_free (var), NULL))
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+VALA_EXTERN gchar* m (void);
static void _vala_main (gchar** args,
gint args_length1);
+gchar*
+m (void)
+{
+ gchar* _tmp0_;
+ gchar* result;
+ _tmp0_ = g_strdup ("foo");
+ result = _tmp0_;
+ return result;
+}
+
static const gchar*
string_to_string (const gchar* self)
{
_vala_main (gchar** args,
gint args_length1)
{
- gchar* a = NULL;
+ gchar* _result_ = NULL;
gchar* _tmp0_;
- gint b = 0;
- gchar* c = NULL;
const gchar* _tmp1_;
+ gint i = 0;
gchar* _tmp2_;
gchar* _tmp3_;
gchar* _tmp4_;
gchar* _tmp5_;
- _tmp0_ = g_strdup ("test");
- a = _tmp0_;
- b = 100;
- _tmp1_ = string_to_string (a);
- _tmp2_ = g_strdup_printf ("%i", b);
+ const gchar* _tmp6_;
+ gchar* _tmp7_;
+ const gchar* _tmp8_;
+ _tmp0_ = g_strdup ("");
+ _result_ = _tmp0_;
+ _tmp1_ = _result_;
+ _vala_assert (g_strcmp0 (_tmp1_, "") == 0, "result == \"\"");
+ i = 42;
+ _tmp2_ = g_strdup_printf ("%i", i);
_tmp3_ = _tmp2_;
- _tmp4_ = g_strconcat (_tmp1_, _tmp3_, NULL);
+ _tmp4_ = m ();
_tmp5_ = _tmp4_;
+ _tmp6_ = string_to_string (_tmp5_);
+ _tmp7_ = g_strconcat ("i=", _tmp3_, " m=", _tmp6_, " ", "$", NULL);
+ _g_free0 (_result_);
+ _result_ = _tmp7_;
+ _g_free0 (_tmp5_);
_g_free0 (_tmp3_);
- c = _tmp5_;
- _vala_assert (g_strcmp0 (c, "test100") == 0, "c == \"test100\"");
- _g_free0 (c);
- _g_free0 (a);
+ _tmp8_ = _result_;
+ _vala_assert (g_strcmp0 (_tmp8_, "i=42 m=foo $") == 0, "result == \"i=42 m=foo $\"");
+ _g_free0 (_result_);
}
int
+def m():string
+ return "foo"
+
init
- var a = "test"
- var b = 100
- var c = @"$( a )$b"
- assert( c == "test100" )
+ result:string = @""
+ assert( result == "" )
+
+ i:int = 42
+ result = @"i=$i m=$( m() ) $$"
+ assert( result == "i=42 m=foo $" )
--- /dev/null
+/* genie_verbatim_template.c generated by valac, the Vala compiler
+ * generated from genie_verbatim_template.gs, do not modify */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#if !defined(VALA_EXTERN)
+#if defined(_MSC_VER)
+#define VALA_EXTERN __declspec(dllexport) extern
+#elif __GNUC__ >= 4
+#define VALA_EXTERN __attribute__((visibility("default"))) extern
+#else
+#define VALA_EXTERN extern
+#endif
+#endif
+
+#define _g_free0(var) (var = (g_free (var), NULL))
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+VALA_EXTERN gchar* m (void);
+static void _vala_main (gchar** args,
+ gint args_length1);
+
+gchar*
+m (void)
+{
+ gchar* _tmp0_;
+ gchar* result;
+ _tmp0_ = g_strdup ("foo");
+ result = _tmp0_;
+ return result;
+}
+
+static const gchar*
+string_to_string (const gchar* self)
+{
+ const gchar* result;
+ g_return_val_if_fail (self != NULL, NULL);
+ result = self;
+ return result;
+}
+
+static void
+_vala_main (gchar** args,
+ gint args_length1)
+{
+ gchar* _result_ = NULL;
+ gchar* _tmp0_;
+ const gchar* _tmp1_;
+ gint i = 0;
+ gchar* _tmp2_;
+ gchar* _tmp3_;
+ gchar* _tmp4_;
+ gchar* _tmp5_;
+ const gchar* _tmp6_;
+ gchar* _tmp7_;
+ const gchar* _tmp8_;
+ gint a = 0;
+ gchar* _tmp9_;
+ gchar* _tmp10_;
+ gchar* _tmp11_;
+ const gchar* _tmp12_;
+ _tmp0_ = g_strdup ("");
+ _result_ = _tmp0_;
+ _tmp1_ = _result_;
+ _vala_assert (g_strcmp0 (_tmp1_, "") == 0, "result == \"\"");
+ i = 42;
+ _tmp2_ = g_strdup_printf ("%i", i);
+ _tmp3_ = _tmp2_;
+ _tmp4_ = m ();
+ _tmp5_ = _tmp4_;
+ _tmp6_ = string_to_string (_tmp5_);
+ _tmp7_ = g_strconcat ("i=", _tmp3_, " \nm=", _tmp6_, " \n", "$", NULL);
+ _g_free0 (_result_);
+ _result_ = _tmp7_;
+ _g_free0 (_tmp5_);
+ _g_free0 (_tmp3_);
+ _tmp8_ = _result_;
+ _vala_assert (g_strcmp0 (_tmp8_, "i=42 \nm=foo \n$") == 0, "result == \"i=42 \\nm=foo \\n$\"");
+ a = 4711;
+ _tmp9_ = g_strdup_printf ("%i", a);
+ _tmp10_ = _tmp9_;
+ _tmp11_ = g_strconcat ("\"", _tmp10_, "\"", "\"", NULL);
+ _g_free0 (_result_);
+ _result_ = _tmp11_;
+ _g_free0 (_tmp10_);
+ _tmp12_ = _result_;
+ _vala_assert (g_strcmp0 (_tmp12_, "\"4711\"\"") == 0, "result == \"\\\"4711\\\"\\\"\"");
+ _g_free0 (_result_);
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main (argv, argc);
+ return 0;
+}
+
--- /dev/null
+def m():string
+ return "foo"
+
+init
+ result:string = @""""""
+ assert( result == "" )
+
+ i:int = 42
+ result = @"""i=$i
+m=$( m() )
+$$"""
+ assert( result == "i=42 \nm=foo \n$" )
+
+ a:int = 4711
+ result = @""""$a"""""
+ assert( result == "\"4711\"\"" )
{
gchar* _result_ = NULL;
gchar* _tmp0_;
+ const gchar* _tmp1_;
gint i = 0;
- gchar* _tmp1_;
gchar* _tmp2_;
- const gchar* _tmp3_;
+ gchar* _tmp3_;
const gchar* _tmp4_;
- gchar* _tmp5_;
- const gchar* _tmp6_;
+ const gchar* _tmp5_;
+ gchar* _tmp6_;
+ const gchar* _tmp7_;
_tmp0_ = g_strdup ("");
_g_free0 (_result_);
_result_ = _tmp0_;
+ _tmp1_ = _result_;
+ _vala_assert (g_strcmp0 (_tmp1_, "") == 0, "result == \"\"");
i = 42;
- _tmp1_ = g_strdup_printf ("%i", i);
- _tmp2_ = _tmp1_;
- _tmp3_ = m ();
- _tmp4_ = string_to_string (_tmp3_);
- _tmp5_ = g_strconcat ("i=", _tmp2_, " m=", _tmp4_, " ", "$", NULL);
+ _tmp2_ = g_strdup_printf ("%i", i);
+ _tmp3_ = _tmp2_;
+ _tmp4_ = m ();
+ _tmp5_ = string_to_string (_tmp4_);
+ _tmp6_ = g_strconcat ("i=", _tmp3_, " m=", _tmp5_, " ", "$", NULL);
_g_free0 (_result_);
- _result_ = _tmp5_;
- _g_free0 (_tmp2_);
- _tmp6_ = _result_;
- _vala_assert (g_strcmp0 (_tmp6_, "i=42 m=foo $") == 0, "result == \"i=42 m=foo $\"");
+ _result_ = _tmp6_;
+ _g_free0 (_tmp3_);
+ _tmp7_ = _result_;
+ _vala_assert (g_strcmp0 (_tmp7_, "i=42 m=foo $") == 0, "result == \"i=42 m=foo $\"");
_g_free0 (_result_);
}
void main () {
string result;
result = @"";
+ assert (result == "");
int i = 42;
result = @"i=$i m=$(m ()) $$";
--- /dev/null
+/* parser_verbatim_template.c generated by valac, the Vala compiler
+ * generated from parser_verbatim_template.vala, do not modify */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#if !defined(VALA_EXTERN)
+#if defined(_MSC_VER)
+#define VALA_EXTERN __declspec(dllexport) extern
+#elif __GNUC__ >= 4
+#define VALA_EXTERN __attribute__((visibility("default"))) extern
+#else
+#define VALA_EXTERN extern
+#endif
+#endif
+
+#define _g_free0(var) (var = (g_free (var), NULL))
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+VALA_EXTERN const gchar* m (void);
+static void _vala_main (void);
+
+const gchar*
+m (void)
+{
+ const gchar* result;
+ result = "foo";
+ return result;
+}
+
+static const gchar*
+string_to_string (const gchar* self)
+{
+ const gchar* result;
+ g_return_val_if_fail (self != NULL, NULL);
+ result = self;
+ return result;
+}
+
+static void
+_vala_main (void)
+{
+ gchar* _result_ = NULL;
+ gchar* _tmp0_;
+ const gchar* _tmp1_;
+ gint i = 0;
+ gchar* _tmp2_;
+ gchar* _tmp3_;
+ const gchar* _tmp4_;
+ const gchar* _tmp5_;
+ gchar* _tmp6_;
+ const gchar* _tmp7_;
+ _tmp0_ = g_strdup ("");
+ _g_free0 (_result_);
+ _result_ = _tmp0_;
+ _tmp1_ = _result_;
+ _vala_assert (g_strcmp0 (_tmp1_, "") == 0, "result == \"\"");
+ i = 42;
+ _tmp2_ = g_strdup_printf ("%i", i);
+ _tmp3_ = _tmp2_;
+ _tmp4_ = m ();
+ _tmp5_ = string_to_string (_tmp4_);
+ _tmp6_ = g_strconcat ("i=", _tmp3_, " \nm=", _tmp5_, " \n", "$", NULL);
+ _g_free0 (_result_);
+ _result_ = _tmp6_;
+ _g_free0 (_tmp3_);
+ _tmp7_ = _result_;
+ _vala_assert (g_strcmp0 (_tmp7_, "i=42 \nm=foo \n$") == 0, "result == \"i=42 \\nm=foo \\n$\"");
+ _g_free0 (_result_);
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
--- /dev/null
+unowned string m () {
+ return "foo";
+}
+
+void main () {
+ string result;
+ result = @"""""";
+ assert (result == "");
+
+ int i = 42;
+ result = @"""i=$i
+m=$(m ())
+$$""";
+ assert (result == "i=42 \nm=foo \n$");
+}
--- /dev/null
+/* scanner_string_template.c generated by valac, the Vala compiler
+ * generated from scanner_string_template.vala, do not modify */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#define _g_free0(var) (var = (g_free (var), NULL))
+
+static void _vala_main (void);
+
+static const gchar*
+string_to_string (const gchar* self)
+{
+ const gchar* result;
+ g_return_val_if_fail (self != NULL, NULL);
+ result = self;
+ return result;
+}
+
+static void
+_vala_main (void)
+{
+ gchar* foo = NULL;
+ gchar* _tmp0_;
+ gchar* bar = NULL;
+ gchar* _tmp1_;
+ gchar* manam = NULL;
+ const gchar* _tmp2_;
+ const gchar* _tmp3_;
+ gchar* _tmp4_;
+ gchar* minim = NULL;
+ gchar* _tmp5_;
+ _tmp0_ = g_strdup ("Hello");
+ foo = _tmp0_;
+ _tmp1_ = g_strdup ("world");
+ bar = _tmp1_;
+ _tmp2_ = string_to_string (foo);
+ _tmp3_ = string_to_string (bar);
+ _tmp4_ = g_strconcat (_tmp2_, " ", _tmp3_, "!", NULL);
+ manam = _tmp4_;
+ _tmp5_ = g_strdup ("");
+ minim = _tmp5_;
+ _g_free0 (minim);
+ _g_free0 (manam);
+ _g_free0 (bar);
+ _g_free0 (foo);
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
--- /dev/null
+void main () {
+ var foo = "Hello";
+ var bar = "world";
+
+ var manam = @"$foo $bar!";
+ var minim = @"";
+}
+
--- /dev/null
+/* scanner_string_verbatim_template.c generated by valac, the Vala compiler
+ * generated from scanner_string_verbatim_template.vala, do not modify */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#define _g_free0(var) (var = (g_free (var), NULL))
+
+static void _vala_main (void);
+
+static const gchar*
+string_to_string (const gchar* self)
+{
+ const gchar* result;
+ g_return_val_if_fail (self != NULL, NULL);
+ result = self;
+ return result;
+}
+
+static void
+_vala_main (void)
+{
+ gchar* foo = NULL;
+ gchar* _tmp0_;
+ gchar* bar = NULL;
+ gchar* _tmp1_;
+ gchar* manam = NULL;
+ const gchar* _tmp2_;
+ const gchar* _tmp3_;
+ gchar* _tmp4_;
+ gchar* minim = NULL;
+ gchar* _tmp5_;
+ _tmp0_ = g_strdup ("Hello");
+ foo = _tmp0_;
+ _tmp1_ = g_strdup ("world");
+ bar = _tmp1_;
+ _tmp2_ = string_to_string (foo);
+ _tmp3_ = string_to_string (bar);
+ _tmp4_ = g_strconcat (_tmp2_, " \n", _tmp3_, "!", NULL);
+ manam = _tmp4_;
+ _tmp5_ = g_strdup ("");
+ minim = _tmp5_;
+ _g_free0 (minim);
+ _g_free0 (manam);
+ _g_free0 (bar);
+ _g_free0 (foo);
+}
+
+int
+main (int argc,
+ char ** argv)
+{
+ _vala_main ();
+ return 0;
+}
+
--- /dev/null
+void main () {
+ var foo = "Hello";
+ var bar = "world";
+
+ var manam = @"""$foo
+$bar!""";
+ var minim = @"""""";
+}
string raw_string = get_last_string ();
string escaped_string = raw_string.substring (3, raw_string.length - 6).escape ("");
return new StringLiteral ("\"%s\"".printf (escaped_string), get_src (begin));
+ case TokenType.VERBATIM_TEMPLATE_STRING_LITERAL:
+ next ();
+ string raw_string = get_last_string ();
+ string escaped_string = raw_string.escape ("");
+ return new StringLiteral ("\"%s\"".printf (escaped_string), get_src (begin));
case TokenType.NULL:
next ();
return new NullLiteral (get_src (begin));
case TokenType.STRING_LITERAL:
case TokenType.TEMPLATE_STRING_LITERAL:
case TokenType.VERBATIM_STRING_LITERAL:
+ case TokenType.VERBATIM_TEMPLATE_STRING_LITERAL:
case TokenType.NULL:
expr = parse_literal ();
break;
case TokenType.STRING_LITERAL:
case TokenType.TEMPLATE_STRING_LITERAL:
case TokenType.VERBATIM_STRING_LITERAL:
+ case TokenType.VERBATIM_TEMPLATE_STRING_LITERAL:
case TokenType.NULL:
case TokenType.SELF:
case TokenType.SUPER:
BRACKET,
REGEX_LITERAL,
TEMPLATE,
- TEMPLATE_PART
+ TEMPLATE_PART,
+ VERBATIM_TEMPLATE
}
public Scanner (SourceFile source_file) {
return (state_stack.length > 0 && state_stack[state_stack.length - 1] == State.TEMPLATE);
}
+ bool in_verbatim_template () {
+ return (state_stack.length > 0 && state_stack[state_stack.length - 1] == State.VERBATIM_TEMPLATE);
+ }
+
bool in_template_part () {
return (state_stack.length > 0 && state_stack[state_stack.length - 1] == State.TEMPLATE_PART);
}
public TokenType read_template_token (out SourceLocation token_begin, out SourceLocation token_end) {
+ bool is_verbatim = in_verbatim_template ();
TokenType type;
char* begin = current;
token_begin = SourceLocation (begin, line, column);
} else {
switch (current[0]) {
case '"':
- type = TokenType.CLOSE_TEMPLATE;
- current++;
- state_stack.length--;
+ if (is_verbatim) {
+ if (current < end -2 && current[1] == '"' && current[2] == '"' && current[3] != '"') {
+ type = TokenType.CLOSE_TEMPLATE;
+ current += 3;
+ state_stack.length--;
+ } else {
+ type = TokenType.VERBATIM_TEMPLATE_STRING_LITERAL;
+ current++;
+ token_length_in_chars++;
+ state_stack += State.TEMPLATE_PART;
+ }
+ } else {
+ type = TokenType.CLOSE_TEMPLATE;
+ current++;
+ state_stack.length--;
+ }
break;
case '$':
token_begin.pos++; // $ is not part of following token
state_stack += State.PARENS;
return read_token (out token_begin, out token_end);
} else if (current[0] == '$') {
- type = TokenType.TEMPLATE_STRING_LITERAL;
+ type = is_verbatim ? TokenType.VERBATIM_TEMPLATE_STRING_LITERAL : TokenType.TEMPLATE_STRING_LITERAL;
current++;
state_stack += State.TEMPLATE_PART;
} else {
}
break;
default:
- type = TokenType.TEMPLATE_STRING_LITERAL;
+ type = is_verbatim ? TokenType.VERBATIM_TEMPLATE_STRING_LITERAL : TokenType.TEMPLATE_STRING_LITERAL;
token_length_in_chars = 0;
while (current < end && current[0] != '"' && current[0] != '$') {
- if (current[0] == '\\') {
+ if (current[0] == '\\' && !is_verbatim) {
current++;
token_length_in_chars++;
if (current >= end) {
return TokenType.EOF;
}
- if (in_template ()) {
+ if (in_template () || in_verbatim_template ()) {
return read_template_token (out token_begin, out token_end);
} else if (in_template_part ()) {
state_stack.length--;
type = get_identifier_or_keyword (begin, len);
} else if (current[0] == '@') {
if (current < end - 1 && current[1] == '"') {
+ current += 1;
+ if (current < end - 5 && current[1] == '"' && current[2] == '"') {
+ current += 3;
+ state_stack += State.VERBATIM_TEMPLATE;
+ } else {
+ current += 1;
+ state_stack += State.TEMPLATE;
+ }
type = TokenType.OPEN_TEMPLATE;
- current += 2;
- state_stack += State.TEMPLATE;
} else {
token_begin.pos++; // @ is not part of the identifier
current++;
if (state_stack.length > 0) {
state_stack.length--;
}
- if (in_template ()) {
+ if (in_template () || in_verbatim_template ()) {
type = TokenType.COMMA;
}
break;
USES,
VAR,
VERBATIM_STRING_LITERAL,
+ VERBATIM_TEMPLATE_STRING_LITERAL,
VIRTUAL,
VOID,
VOLATILE,
case USES: return "`uses'";
case VAR: return "`var'";
case VERBATIM_STRING_LITERAL: return "verbatim string literal";
+ case VERBATIM_TEMPLATE_STRING_LITERAL: return "verbatim template string literal";
case VIRTUAL: return "`virtual'";
case VOID: return "`void'";
case VOLATILE: return "`volatile'";
string raw_string = get_last_string ();
string escaped_string = raw_string.substring (3, raw_string.length - 6).escape ("");
return new StringLiteral ("\"%s\"".printf (escaped_string), get_src (begin));
+ case TokenType.VERBATIM_TEMPLATE_STRING_LITERAL:
+ next ();
+ string raw_string = get_last_string ();
+ string escaped_string = raw_string.escape ("");
+ return new StringLiteral ("\"%s\"".printf (escaped_string), get_src (begin));
case TokenType.NULL:
next ();
return new NullLiteral (get_src (begin));
case TokenType.REGEX_LITERAL:
case TokenType.TEMPLATE_STRING_LITERAL:
case TokenType.VERBATIM_STRING_LITERAL:
+ case TokenType.VERBATIM_TEMPLATE_STRING_LITERAL:
case TokenType.NULL:
expr = parse_literal ();
break;
case TokenType.STRING_LITERAL:
case TokenType.TEMPLATE_STRING_LITERAL:
case TokenType.VERBATIM_STRING_LITERAL:
+ case TokenType.VERBATIM_TEMPLATE_STRING_LITERAL:
case TokenType.REGEX_LITERAL:
case TokenType.NULL:
case TokenType.THIS:
BRACKET,
TEMPLATE,
TEMPLATE_PART,
- REGEX_LITERAL
+ REGEX_LITERAL,
+ VERBATIM_TEMPLATE
}
public Scanner (SourceFile source_file) {
return (state_stack.length > 0 && state_stack[state_stack.length - 1] == State.TEMPLATE);
}
+ bool in_verbatim_template () {
+ return (state_stack.length > 0 && state_stack[state_stack.length - 1] == State.VERBATIM_TEMPLATE);
+ }
+
bool in_template_part () {
return (state_stack.length > 0 && state_stack[state_stack.length - 1] == State.TEMPLATE_PART);
}
}
public TokenType read_template_token (out SourceLocation token_begin, out SourceLocation token_end) {
+ bool is_verbatim = in_verbatim_template ();
TokenType type;
char* begin = current;
token_begin = SourceLocation (begin, line, column);
} else {
switch (current[0]) {
case '"':
- type = TokenType.CLOSE_TEMPLATE;
- current++;
- state_stack.length--;
+ if (is_verbatim) {
+ if (current < end -2 && current[1] == '"' && current[2] == '"' && current[3] != '"') {
+ type = TokenType.CLOSE_TEMPLATE;
+ current += 3;
+ state_stack.length--;
+ } else {
+ type = TokenType.VERBATIM_TEMPLATE_STRING_LITERAL;
+ current++;
+ token_length_in_chars++;
+ state_stack += State.TEMPLATE_PART;
+ }
+ } else {
+ type = TokenType.CLOSE_TEMPLATE;
+ current++;
+ state_stack.length--;
+ }
break;
case '$':
token_begin.pos++; // $ is not part of following token
state_stack += State.PARENS;
return read_token (out token_begin, out token_end);
} else if (current[0] == '$') {
- type = TokenType.TEMPLATE_STRING_LITERAL;
+ type = is_verbatim ? TokenType.VERBATIM_TEMPLATE_STRING_LITERAL : TokenType.TEMPLATE_STRING_LITERAL;
current++;
state_stack += State.TEMPLATE_PART;
} else {
}
break;
default:
- type = TokenType.TEMPLATE_STRING_LITERAL;
+ type = is_verbatim ? TokenType.VERBATIM_TEMPLATE_STRING_LITERAL : TokenType.TEMPLATE_STRING_LITERAL;
token_length_in_chars = 0;
while (current < end && current[0] != '"' && current[0] != '$') {
- if (current[0] == '\\') {
+ if (current[0] == '\\' && !is_verbatim) {
current++;
token_length_in_chars++;
if (current >= end) {
}
public TokenType read_token (out SourceLocation token_begin, out SourceLocation token_end) {
- if (in_template ()) {
+ if (in_template () || in_verbatim_template ()) {
return read_template_token (out token_begin, out token_end);
} else if (in_template_part ()) {
state_stack.length--;
type = get_identifier_or_keyword (begin, len);
} else if (current[0] == '@') {
if (current < end - 1 && current[1] == '"') {
+ current += 1;
+ if (current < end - 5 && current[1] == '"' && current[2] == '"') {
+ current += 3;
+ state_stack += State.VERBATIM_TEMPLATE;
+ } else {
+ current += 1;
+ state_stack += State.TEMPLATE;
+ }
type = TokenType.OPEN_TEMPLATE;
- current += 2;
- state_stack += State.TEMPLATE;
} else {
token_begin.pos++; // @ is not part of the identifier
current++;
if (state_stack.length > 0) {
state_stack.length--;
}
- if (in_template ()) {
+ if (in_template () || in_verbatim_template ()) {
type = TokenType.COMMA;
}
break;
USING,
VAR,
VERBATIM_STRING_LITERAL,
+ VERBATIM_TEMPLATE_STRING_LITERAL,
VIRTUAL,
VOID,
VOLATILE,
case USING: return "`using'";
case VAR: return "`var'";
case VERBATIM_STRING_LITERAL: return "verbatim string literal";
+ case VERBATIM_TEMPLATE_STRING_LITERAL: return "verbatim template string literal";
case VIRTUAL: return "`virtual'";
case VOID: return "`void'";
case VOLATILE: return "`volatile'";