* Strings.

This commit is contained in:
Eelco Dolstra 2010-03-28 18:27:07 +00:00
parent d96cdcea6b
commit 392811eb8f
1 changed files with 45 additions and 0 deletions

View File

@ -5,6 +5,7 @@
#include "nixexpr-ast.hh"
#include <cstdlib>
#include <cstring>
using namespace nix;
@ -27,6 +28,7 @@ struct Env
typedef enum {
tInt = 1,
tBool,
tString,
tAttrs,
tList,
tThunk,
@ -48,6 +50,10 @@ struct Value
{
int integer;
bool boolean;
struct {
const char * s;
const char * * context;
} string;
Bindings * attrs;
struct {
unsigned int length;
@ -97,6 +103,14 @@ static void mkBool(Value & v, bool b)
}
static void mkString(Value & v, const char * s)
{
v.type = tString;
v.string.s = s;
v.string.context = 0;
}
std::ostream & operator << (std::ostream & str, Value & v)
{
switch (v.type) {
@ -106,6 +120,9 @@ std::ostream & operator << (std::ostream & str, Value & v)
case tBool:
str << (v.boolean ? "true" : "false");
break;
case tString:
str << "\"" << v.string.s << "\""; // !!! escaping
break;
case tAttrs:
str << "{ ";
foreach (Bindings::iterator, i, *v.attrs)
@ -269,6 +286,13 @@ static void eval(Env & env, Expr e, Value & v)
return;
}
ATerm s; ATermList context;
if (matchStr(e, s, context)) {
assert(context == ATempty);
mkString(v, ATgetName(ATgetAFun(s)));
return;
}
ATermList es;
if (matchAttrs(e, es)) {
v.type = tAttrs;
@ -481,6 +505,25 @@ static void eval(Env & env, Expr e, Value & v)
return;
}
if (matchConcatStrings(e, es)) {
unsigned int n = ATgetLength(es), j = 0;
Value vs[n];
unsigned int len = 0;
for (ATermIterator i(es); i; ++i, ++j) {
eval(env, *i, vs[j]);
if (vs[j].type != tString) throw TypeError("string expected");
len += strlen(vs[j].string.s);
}
char * s = new char[len + 1], * t = s;
for (unsigned int i = 0; i < j; ++i) {
strcpy(t, vs[i].string.s);
t += strlen(vs[i].string.s);
}
*t = 0;
mkString(v, s);
return;
}
throw Error("unsupported term");
}
@ -601,6 +644,8 @@ void run(Strings args)
doTest("true == false");
doTest("__head [ 1 2 3 ]");
doTest("__add 1 2");
doTest("\"foo\"");
doTest("let s = \"bar\"; in \"foo${s}\"");
printMsg(lvlError, format("alloced %1% values") % nrValues);
printMsg(lvlError, format("alloced %1% environments") % nrEnvs);