* Added a list concatenation operator:

[1 2 3] ++ [4 5 6] => [1 2 3 4 5 6]
This commit is contained in:
Eelco Dolstra 2005-07-25 15:05:34 +00:00
parent e6899794ae
commit 991a130b1e
8 changed files with 29 additions and 12 deletions

View file

@ -140,6 +140,15 @@ bool evalBool(EvalState & state, Expr e)
} }
ATermList evalList(EvalState & state, Expr e)
{
e = evalExpr(state, e);
ATermList list;
if (!matchList(e, list)) throw Error("list expected");
return list;
}
Expr evalExpr2(EvalState & state, Expr e) Expr evalExpr2(EvalState & state, Expr e)
{ {
Expr e1, e2, e3, e4; Expr e1, e2, e3, e4;
@ -336,6 +345,13 @@ Expr evalExpr2(EvalState & state, Expr e)
else throw Error("wrong argument types in `+' operator"); else throw Error("wrong argument types in `+' operator");
} }
/* List concatenation. */
if (matchOpConcat(e, e1, e2)) {
ATermList l1 = evalList(state, e1);
ATermList l2 = evalList(state, e2);
return makeList(ATconcat(l1, l2));
}
/* Barf. */ /* Barf. */
throw badTerm("invalid expression", e); throw badTerm("invalid expression", e);
} }

View file

@ -46,6 +46,7 @@ Expr evalFile(EvalState & state, const Path & path);
/* Specific results. */ /* Specific results. */
string evalString(EvalState & state, Expr e); string evalString(EvalState & state, Expr e);
Path evalPath(EvalState & state, Expr e); Path evalPath(EvalState & state, Expr e);
ATermList evalList(EvalState & state, Expr e);
/* Print statistics. */ /* Print statistics. */
void printEvalStats(EvalState & state); void printEvalStats(EvalState & state);

View file

@ -59,6 +59,7 @@ inherit { return INHERIT; }
\|\| { return OR; } \|\| { return OR; }
\-\> { return IMPL; } \-\> { return IMPL; }
\/\/ { return UPDATE; } \/\/ { return UPDATE; }
\+\+ { return CONCAT; }
{ID} { yylval->t = ATmake("<str>", yytext); return ID; /* !!! alloc */ } {ID} { yylval->t = ATmake("<str>", yytext); return ID; /* !!! alloc */ }
{INT} { int n = atoi(yytext); /* !!! overflow */ {INT} { int n = atoi(yytext); /* !!! overflow */

View file

@ -18,6 +18,7 @@ OpUpdate | Expr Expr | Expr |
SubPath | Expr Expr | Expr | SubPath | Expr Expr | Expr |
OpHasAttr | Expr string | Expr | OpHasAttr | Expr string | Expr |
OpPlus | Expr Expr | Expr | OpPlus | Expr Expr | Expr |
OpConcat | Expr Expr | Expr |
Call | Expr Expr | Expr | Call | Expr Expr | Expr |
Select | Expr string | Expr | Select | Expr string | Expr |
Var | string | Expr | Var | string | Expr |

View file

@ -64,6 +64,7 @@ static Pos makeCurPos(YYLTYPE * loc, void * data)
%right UPDATE %right UPDATE
%left NEG %left NEG
%left '+' %left '+'
%left CONCAT
%nonassoc '?' %nonassoc '?'
%nonassoc '~' %nonassoc '~'
@ -102,6 +103,7 @@ expr_op
| expr_op '~' expr_op { $$ = makeSubPath($1, $3); } | expr_op '~' expr_op { $$ = makeSubPath($1, $3); }
| expr_op '?' ID { $$ = makeOpHasAttr($1, $3); } | expr_op '?' ID { $$ = makeOpHasAttr($1, $3); }
| expr_op '+' expr_op { $$ = makeOpPlus($1, $3); } | expr_op '+' expr_op { $$ = makeOpPlus($1, $3); }
| expr_op CONCAT expr_op { $$ = makeOpConcat($1, $3); }
| expr_app | expr_app
; ;

View file

@ -414,17 +414,13 @@ static Expr primIsNull(EvalState & state, const ATermVector & args)
static Expr primMap(EvalState & state, const ATermVector & args) static Expr primMap(EvalState & state, const ATermVector & args)
{ {
Expr fun = evalExpr(state, args[0]); Expr fun = evalExpr(state, args[0]);
Expr list = evalExpr(state, args[1]); ATermList list = evalList(state, args[1]);
ATermList list2; ATermList res = ATempty;
if (!matchList(list, list2)) for (ATermIterator i(list); i; ++i)
throw Error("`map' expects a list as its second argument"); res = ATinsert(res, makeCall(fun, *i));
ATermList list3 = ATempty; return makeList(ATreverse(res));
for (ATermIterator i(list2); i; ++i)
list3 = ATinsert(list3, makeCall(fun, *i));
return makeList(ATreverse(list3));
} }
@ -449,9 +445,7 @@ static Expr primRemoveAttrs(EvalState & state, const ATermVector & args)
ATermMap attrs; ATermMap attrs;
queryAllAttrs(evalExpr(state, args[0]), attrs, true); queryAllAttrs(evalExpr(state, args[0]), attrs, true);
ATermList list; ATermList list = evalList(state, args[1]);
if (!matchList(evalExpr(state, args[1]), list))
throw Error("`removeAttrs' expects a list as its second argument");
for (ATermIterator i(list); i; ++i) for (ATermIterator i(list); i; ++i)
/* It's not an error for *i not to exist. */ /* It's not an error for *i not to exist. */

View file

@ -0,0 +1 @@
List([Int(1),Int(2),Int(3),Int(4),Int(5),Int(6),Int(7),Int(8),Int(9)])

View file

@ -0,0 +1 @@
[1 2 3] ++ [4 5 6] ++ [7 8 9]