forked from lix-project/lix
* Optimise string constants by putting them in the symbol table.
This commit is contained in:
parent
8ac06726b9
commit
b2ba62170c
|
@ -249,6 +249,14 @@ void mkString(Value & v, const string & s, const PathSet & context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mkString(Value & v, const Symbol & s)
|
||||||
|
{
|
||||||
|
v.type = tString;
|
||||||
|
v.string.s = ((string) s).c_str();
|
||||||
|
v.string.context = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void mkPath(Value & v, const char * s)
|
void mkPath(Value & v, const char * s)
|
||||||
{
|
{
|
||||||
clearValue(v);
|
clearValue(v);
|
||||||
|
@ -429,7 +437,7 @@ void ExprInt::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprString::eval(EvalState & state, Env & env, Value & v)
|
void ExprString::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
mkString(v, s.c_str());
|
mkString(v, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ static void adjustLoc(YYLTYPE * loc, const char * s, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr * unescapeStr(const char * s)
|
static Expr * unescapeStr(SymbolTable & symbols, const char * s)
|
||||||
{
|
{
|
||||||
string t;
|
string t;
|
||||||
char c;
|
char c;
|
||||||
|
@ -66,7 +66,7 @@ static Expr * unescapeStr(const char * s)
|
||||||
}
|
}
|
||||||
else t += c;
|
else t += c;
|
||||||
}
|
}
|
||||||
return new ExprString(t);
|
return new ExprString(symbols.create(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ inherit { return INHERIT; }
|
||||||
"$\"" will be consumed as part of a string, rather
|
"$\"" will be consumed as part of a string, rather
|
||||||
than a "$" followed by the string terminator.
|
than a "$" followed by the string terminator.
|
||||||
Disallow "$\"" for now. */
|
Disallow "$\"" for now. */
|
||||||
yylval->e = unescapeStr(yytext);
|
yylval->e = unescapeStr(data->symbols, yytext);
|
||||||
return STR;
|
return STR;
|
||||||
}
|
}
|
||||||
<STRING>\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; }
|
<STRING>\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; }
|
||||||
|
@ -140,7 +140,7 @@ inherit { return INHERIT; }
|
||||||
return IND_STR;
|
return IND_STR;
|
||||||
}
|
}
|
||||||
<IND_STRING>\'\'\\. {
|
<IND_STRING>\'\'\\. {
|
||||||
yylval->e = unescapeStr(yytext + 2);
|
yylval->e = unescapeStr(data->symbols, yytext + 2);
|
||||||
return IND_STR;
|
return IND_STR;
|
||||||
}
|
}
|
||||||
<IND_STRING>\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; }
|
<IND_STRING>\$\{ { BEGIN(INITIAL); return DOLLAR_CURLY; }
|
||||||
|
|
|
@ -65,8 +65,8 @@ struct ExprInt : Expr
|
||||||
|
|
||||||
struct ExprString : Expr
|
struct ExprString : Expr
|
||||||
{
|
{
|
||||||
string s;
|
Symbol s;
|
||||||
ExprString(const string & s) : s(s) { };
|
ExprString(const Symbol & s) : s(s) { };
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,36 +7,21 @@
|
||||||
%parse-param { yyscan_t scanner }
|
%parse-param { yyscan_t scanner }
|
||||||
%parse-param { ParseData * data }
|
%parse-param { ParseData * data }
|
||||||
%lex-param { yyscan_t scanner }
|
%lex-param { yyscan_t scanner }
|
||||||
|
%lex-param { ParseData * data }
|
||||||
|
|
||||||
|
%code requires {
|
||||||
|
|
||||||
%{
|
#ifndef BISON_HEADER
|
||||||
/* Newer versions of Bison copy the declarations below to
|
#define BISON_HEADER
|
||||||
parser-tab.hh, which sucks bigtime since lexer.l doesn't want that
|
|
||||||
stuff. So allow it to be excluded. */
|
|
||||||
#ifndef BISON_HEADER_HACK
|
|
||||||
#define BISON_HEADER_HACK
|
|
||||||
|
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
|
||||||
#include "nixexpr.hh"
|
#include "nixexpr.hh"
|
||||||
|
|
||||||
#include "parser-tab.hh"
|
|
||||||
#include "lexer-tab.hh"
|
|
||||||
#define YYSTYPE YYSTYPE // workaround a bug in Bison 2.4
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
using namespace nix;
|
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
struct ParseData
|
||||||
struct ParseData
|
{
|
||||||
{
|
|
||||||
SymbolTable & symbols;
|
SymbolTable & symbols;
|
||||||
Expr * result;
|
Expr * result;
|
||||||
Path basePath;
|
Path basePath;
|
||||||
|
@ -47,7 +32,33 @@ struct ParseData
|
||||||
: symbols(symbols)
|
: symbols(symbols)
|
||||||
, sLetBody(symbols.create("<let-body>"))
|
, sLetBody(symbols.create("<let-body>"))
|
||||||
{ };
|
{ };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#define YY_DECL int yylex \
|
||||||
|
(YYSTYPE * yylval_param, YYLTYPE * yylloc_param, yyscan_t yyscanner, nix::ParseData * data)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
%{
|
||||||
|
|
||||||
|
#include "parser-tab.hh"
|
||||||
|
#include "lexer-tab.hh"
|
||||||
|
#define YYSTYPE YYSTYPE // workaround a bug in Bison 2.4
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
YY_DECL;
|
||||||
|
|
||||||
|
using namespace nix;
|
||||||
|
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
static string showAttrPath(const vector<Symbol> & attrPath)
|
static string showAttrPath(const vector<Symbol> & attrPath)
|
||||||
|
@ -113,9 +124,9 @@ static void addFormal(const Pos & pos, Formals * formals, const Formal & formal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Expr * stripIndentation(vector<Expr *> & es)
|
static Expr * stripIndentation(SymbolTable & symbols, vector<Expr *> & es)
|
||||||
{
|
{
|
||||||
if (es.empty()) return new ExprString("");
|
if (es.empty()) return new ExprString(symbols.create(""));
|
||||||
|
|
||||||
/* Figure out the minimum indentation. Note that by design
|
/* Figure out the minimum indentation. Note that by design
|
||||||
whitespace-only final lines are not taken into account. (So
|
whitespace-only final lines are not taken into account. (So
|
||||||
|
@ -195,7 +206,7 @@ static Expr * stripIndentation(vector<Expr *> & es)
|
||||||
s2 = string(s2, 0, p + 1);
|
s2 = string(s2, 0, p + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
es2->push_back(new ExprString(s2));
|
es2->push_back(new ExprString(symbols.create(s2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ExprConcatStrings(es2);
|
return new ExprConcatStrings(es2);
|
||||||
|
@ -224,9 +235,6 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
|
@ -337,15 +345,15 @@ expr_simple
|
||||||
| INT { $$ = new ExprInt($1); }
|
| INT { $$ = new ExprInt($1); }
|
||||||
| '"' string_parts '"' {
|
| '"' string_parts '"' {
|
||||||
/* For efficiency, and to simplify parse trees a bit. */
|
/* For efficiency, and to simplify parse trees a bit. */
|
||||||
if ($2->empty()) $$ = new ExprString("");
|
if ($2->empty()) $$ = new ExprString(data->symbols.create(""));
|
||||||
else if ($2->size() == 1) $$ = $2->front();
|
else if ($2->size() == 1) $$ = $2->front();
|
||||||
else $$ = new ExprConcatStrings($2);
|
else $$ = new ExprConcatStrings($2);
|
||||||
}
|
}
|
||||||
| IND_STRING_OPEN ind_string_parts IND_STRING_CLOSE {
|
| IND_STRING_OPEN ind_string_parts IND_STRING_CLOSE {
|
||||||
$$ = stripIndentation(*$2);
|
$$ = stripIndentation(data->symbols, *$2);
|
||||||
}
|
}
|
||||||
| PATH { $$ = new ExprPath(absPath($1, data->basePath)); }
|
| PATH { $$ = new ExprPath(absPath($1, data->basePath)); }
|
||||||
| URI { $$ = new ExprString($1); }
|
| URI { $$ = new ExprString(data->symbols.create($1)); }
|
||||||
| '(' expr ')' { $$ = $2; }
|
| '(' expr ')' { $$ = $2; }
|
||||||
/* Let expressions `let {..., body = ...}' are just desugared
|
/* Let expressions `let {..., body = ...}' are just desugared
|
||||||
into `(rec {..., body = ...}).body'. */
|
into `(rec {..., body = ...}).body'. */
|
||||||
|
|
Loading…
Reference in a new issue