Eagerly evaluate interpolated expressions.

If we ever support custom string templates, we'll need to go back to
compiling them to functions. But, for now, they can be evaluated
eagerly, leading to simpler code.
This commit is contained in:
Bob Nystrom
2015-11-23 07:08:14 -08:00
parent fb72e0fff7
commit 5bde04db4c
3 changed files with 14 additions and 40 deletions

View File

@ -2208,12 +2208,18 @@ static void literal(Compiler* compiler, bool allowAssignment)
emitConstant(compiler, compiler->parser->previous.value);
}
// A string literal that contains interpolated expressions.
//
// Interpolation is syntactic sugar for calling ".join()" on a list. So the
// string:
//
// "a %(b + c) d"
//
// is compiled roughly like:
//
// ["a ", b + c, " d"].join()
static void stringInterpolation(Compiler* compiler, bool allowAssignment)
{
// TODO: Allow other expressions here so that user-defined classes can control
// interpolation processing like "tagged template strings" in ES6.
loadCoreVariable(compiler, "String");
// Instantiate a new list.
loadCoreVariable(compiler, "List");
callMethod(compiler, 0, "new()", 5);
@ -2224,15 +2230,9 @@ static void stringInterpolation(Compiler* compiler, bool allowAssignment)
literal(compiler, false);
callMethod(compiler, 1, "addCore_(_)", 11);
// The interpolated expression.
ignoreNewlines(compiler);
// Compile the interpolated expression part to a function.
Compiler fnCompiler;
initCompiler(&fnCompiler, compiler->parser, compiler, true);
expression(&fnCompiler);
emit(&fnCompiler, CODE_RETURN);
endCompiler(&fnCompiler, "interpolation", 9);
expression(compiler);
callMethod(compiler, 1, "addCore_(_)", 11);
ignoreNewlines(compiler);
@ -2243,8 +2243,8 @@ static void stringInterpolation(Compiler* compiler, bool allowAssignment)
literal(compiler, false);
callMethod(compiler, 1, "addCore_(_)", 11);
// Call .interpolate() with the list of interpolation parts.
callMethod(compiler, 1, "interpolate_(_)", 15);
// The list of interpolated parts.
callMethod(compiler, 0, "join()", 6);
}
static void super_(Compiler* compiler, bool allowAssignment)

View File

@ -131,19 +131,6 @@ class WhereSequence is Sequence {
class String is Sequence {
bytes { StringByteSequence.new(this) }
codePoints { StringCodePointSequence.new(this) }
static interpolate_(parts) {
var result = ""
for (part in parts) {
if (part is String) {
result = result + part
} else {
result = result + part.call().toString
}
}
return result
}
}
class StringByteSequence is Sequence {

View File

@ -133,19 +133,6 @@ static const char* coreModuleSource =
"class String is Sequence {\n"
" bytes { StringByteSequence.new(this) }\n"
" codePoints { StringCodePointSequence.new(this) }\n"
"\n"
" static interpolate_(parts) {\n"
" var result = \"\"\n"
" for (part in parts) {\n"
" if (part is String) {\n"
" result = result + part\n"
" } else {\n"
" result = result + part.call().toString\n"
" }\n"
" }\n"
"\n"
" return result\n"
" }\n"
"}\n"
"\n"
"class StringByteSequence is Sequence {\n"