diff --git a/nixd/include/nixd/Syntax/Nodes.h b/nixd/include/nixd/Syntax/Nodes.h index 9ea74a2a5..202693d5e 100644 --- a/nixd/include/nixd/Syntax/Nodes.h +++ b/nixd/include/nixd/Syntax/Nodes.h @@ -71,9 +71,17 @@ struct Int : Node {}; struct Float : Node {}; -struct StringParts : Node {}; +struct InterpExpr : Node { + Node *Body; +}; -struct StringPartsInterpolated : Node {}; +struct String : Node { + std::string S; +}; + +struct ConcatStrings : Node { + std::vector SubStrings; +}; struct List : Node { std::vector Elems; diff --git a/nixd/lib/Syntax/Parser/Parser.y b/nixd/lib/Syntax/Parser/Parser.y index 93d629643..23ba52357 100644 --- a/nixd/lib/Syntax/Parser/Parser.y +++ b/nixd/lib/Syntax/Parser/Parser.y @@ -25,6 +25,9 @@ nixd::syntax::Binds *Binds; nixd::syntax::AttrPath *AttrPath; nixd::syntax::Call *Call; + nixd::syntax::ConcatStrings *ConcatStrings; + nixd::syntax::String *String; + nixd::syntax::InterpExpr *InterpExpr; // Tokens nixd::syntax::StringToken STR; @@ -37,6 +40,10 @@ %type start expr expr_function expr_if expr_op expr_select expr_simple +%type string_parts +%type string; +%type string_parts_interpolated +%type string_parts_interp_expr %type identifier %type formals %type binds @@ -213,18 +220,34 @@ expr_simple | '{' binds '}' | '[' expr_list ']' - string_parts - : STR - | string_parts_interpolated - | + : string { + $$ = $1; + } + | string_parts_interpolated { + $$ = $1; + } string_parts_interpolated - : string_parts_interpolated STR - | string_parts_interpolated DOLLAR_CURLY expr '}' - | DOLLAR_CURLY expr '}' - | STR DOLLAR_CURLY expr '}' + : string_parts_interpolated string { + $$->SubStrings.emplace_back($2); + $$->Range = mkRange(yylloc, *Data); + } + | string_parts_interpolated string_parts_interp_expr { + $$->SubStrings.emplace_back($2); + $$->Range = mkRange(yylloc, *Data); + } + | string_parts_interp_expr { + $$ = decorateNode(new ConcatStrings{ + .SubStrings = {$1} + }, yylloc, *Data); + } + | string string_parts_interp_expr { + $$ = decorateNode(new ConcatStrings{ + .SubStrings = {$1, $2} + }, yylloc, *Data); + } path_start @@ -234,9 +257,25 @@ path_start ind_string_parts : ind_string_parts IND_STR - | ind_string_parts DOLLAR_CURLY expr '}' + | ind_string_parts string_parts_interp_expr | +// Nixd extension, nix uses the token directly +string + : STR { + $$ = decorateNode(new String{ + .S = std::string($1) + }, yylloc, *Data); + } + +// Nixd extension +// nix: DOLLAR_CURLY expr '}' +string_parts_interp_expr + : DOLLAR_CURLY expr '}' { + $$ = decorateNode(new InterpExpr{ + .Body = $2 + }, yylloc, *Data); + } identifier : ID { @@ -275,7 +314,7 @@ attr string_attr : '"' string_parts '"' - | DOLLAR_CURLY expr '}' + | string_parts_interp_expr expr_list