about summary refs log tree commit diff
path: root/src/libexpr/parser.y
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2006-05-01T14·01+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2006-05-01T14·01+0000
commit0064599a27ec44880e4ff6fa19f453e610b5ef07 (patch)
tree50289edc19dc99d5423ce8f57b99c5b8eb5597c1 /src/libexpr/parser.y
parent6cecad2be0f7ced82658ec2a86bcf61583487959 (diff)
* String interpolation. Expressions like
    "--with-freetype2-library=" + freetype + "/lib"

  can now be written as

    "--with-freetype2-library=${freetype}/lib"

  An arbitrary expression can be enclosed within ${...}, not just
  identifiers.

* Escaping in string literals: \n, \r, \t interpreted as in C, any
  other character following \ is interpreted as-is.
  
* Newlines are now allowed in string literals.

Diffstat (limited to 'src/libexpr/parser.y')
-rw-r--r--src/libexpr/parser.y17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index ec07a0191971..cba390d8dad8 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -25,6 +25,7 @@ void parseError(void * data, char * error, int line, int column);
 ATerm absParsedPath(void * data, ATerm t);
 ATerm fixAttrs(int recursive, ATermList as);
 const char * getPath(void * data);
+void backToString(yyscan_t scanner);
 
 void yyerror(YYLTYPE * loc, yyscan_t scanner, void * data, char * s)
 {
@@ -73,9 +74,10 @@ static void freeAndUnprotect(void * p)
 
 %type <t> start expr expr_function expr_if expr_op
 %type <t> expr_app expr_select expr_simple bind inheritsrc formal
-%type <ts> binds ids expr_list formals
+%type <ts> binds ids expr_list formals string_parts
 %token <t> ID INT STR PATH URI
 %token IF THEN ELSE ASSERT WITH LET REC INHERIT EQ NEQ AND OR IMPL
+%token DOLLAR_CURLY /* == ${ */
 
 %nonassoc IMPL
 %left OR
@@ -142,7 +144,12 @@ expr_select
 expr_simple
   : ID { $$ = makeVar($1); }
   | INT { $$ = makeInt(ATgetInt((ATermInt) $1)); }
-  | STR { $$ = makeStr($1); }
+  | '"' string_parts '"' {
+      /* For efficiency, and to simplify parse trees a bit. */
+      if ($2 == ATempty) $$ = makeStr(toATerm(""));
+      else if (ATgetNext($2) == ATempty) $$ = ATgetFirst($2);
+      else $$ = makeConcatStrings(ATreverse($2));
+  }
   | PATH { $$ = makePath(absParsedPath(data, $1)); }
   | URI { $$ = makeUri($1); }
   | '(' expr ')' { $$ = $2; }
@@ -157,6 +164,12 @@ expr_simple
   | '[' expr_list ']' { $$ = makeList($2); }
   ;
 
+string_parts
+  : string_parts STR { $$ = ATinsert($1, $2); }
+  | string_parts DOLLAR_CURLY expr '}' { backToString(scanner); $$ = ATinsert($1, $3); }
+  | { $$ = ATempty; }
+  ;
+
 binds
   : binds bind { $$ = ATinsert($1, $2); }
   | { $$ = ATempty; }