From e96fd4e652b0661d6edf7c727436bd82ddf6a848 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Mon, 8 Jul 2024 16:12:43 +0200 Subject: [PATCH] WIP --- src/libexpr/lexer.l | 11 +++++++++++ src/libexpr/nixexpr.hh | 9 +++++++++ src/libexpr/parser-state.hh | 4 ++-- src/libexpr/parser.y | 16 +++++++++++++++- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/libexpr/lexer.l b/src/libexpr/lexer.l index 8c0f9d1f2f77..bd0babf8aeee 100644 --- a/src/libexpr/lexer.l +++ b/src/libexpr/lexer.l @@ -29,6 +29,8 @@ namespace nix { #define CUR_POS state->at(*yylloc) +static std::string currentDocCommentText; + static void initLoc(YYLTYPE * loc) { loc->first_line = loc->last_line = 0; @@ -279,6 +281,15 @@ or { return OR_KW; } {SPATH} { yylval->path = {yytext, (size_t) yyleng}; return SPATH; } {URI} { yylval->uri = {yytext, (size_t) yyleng}; return URI; } +\/\*\*([^*]|\*+[^*/])*\*+\/ /* long comments */ { + // TODO: alternate, scalable approach: + // // save doc comment + // currentDocCommentText = std::string(yytext, yyleng); + // return DOC_COMMENT; + return new DocComment(std::string(yytext, yyleng)); +} + + [ \t\r\n]+ /* eat up whitespace */ \#[^\r\n]* /* single-line comments */ \/\*([^*]|\*+[^*/])*\*+\/ /* long comments */ diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index e37e3bdd1534..3ad37c7303c6 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -22,6 +22,10 @@ struct ExprWith; struct StaticEnv; +struct DocComment { + std::string innerText; +}; + /** * An attribute path is a sequence of attribute names. */ @@ -54,6 +58,7 @@ struct Expr virtual ~Expr() { }; virtual void show(const SymbolTable & symbols, std::ostream & str) const; virtual void bindVars(EvalState & es, const std::shared_ptr & env); + virtual void pushDocComment(const DocComment & docComment) { }; virtual void eval(EvalState & state, Env & env, Value & v); virtual Value * maybeThunk(EvalState & state, Env & env); virtual void setName(Symbol name); @@ -188,6 +193,10 @@ struct ExprAttrs : Expr Kind kind; Expr * e; PosIdx pos; + /** + * noPos pretty often + */ + PosIdx docStartPos; Displacement displ; // displacement AttrDef(Expr * e, const PosIdx & pos, Kind kind = Kind::Plain) : kind(kind), e(e), pos(pos) { }; diff --git a/src/libexpr/parser-state.hh b/src/libexpr/parser-state.hh index cff6282faa0a..83f60c2a9047 100644 --- a/src/libexpr/parser-state.hh +++ b/src/libexpr/parser-state.hh @@ -50,7 +50,7 @@ struct ParserState void dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos); void dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos); - void addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * e, const PosIdx pos); + void addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * e, const PosIdx pos, const DocComment & docComment); Formals * validateFormals(Formals * formals, PosIdx pos = noPos, Symbol arg = {}); Expr * stripIndentation(const PosIdx pos, std::vector>> && es); @@ -74,7 +74,7 @@ inline void ParserState::dupAttr(Symbol attr, const PosIdx pos, const PosIdx pre }); } -inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * e, const PosIdx pos) +inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * e, const PosIdx pos, const DocComment & docComment) { AttrPath::iterator i; // All attrpaths have at least one attr diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 709a4532a856..b5b581bf3429 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -94,6 +94,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParserState * state, const char * std::vector> * inheritAttrs; std::vector> * string_parts; std::vector>> * ind_string_parts; + nix::DocComment * docComment; } %type start expr expr_function expr_if expr_op @@ -118,6 +119,9 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParserState * state, const char * %token DOLLAR_CURLY /* == ${ */ %token IND_STRING_OPEN IND_STRING_CLOSE %token ELLIPSIS +%token DOC_COMMENT +%type doc_comment_maybe +//%type docComment %right IMPL %left OR @@ -311,8 +315,18 @@ ind_string_parts | { $$ = new std::vector>>; } ; +doc_comment_maybe + : DOC_COMMENT { return $1; } + | { return nullptr; } + ; + binds - : binds attrpath '=' expr ';' { $$ = $1; state->addAttr($$, std::move(*$2), $4, state->at(@2)); delete $2; } + : binds doc_comment_maybe attrpath '=' expr ';' { + $$ = $1; + $5->pushDocComment($2); + state->addAttr($$, std::move(*$3), $5, state->at(@3)); + delete $3; + } | binds INHERIT attrs ';' { $$ = $1; for (auto & [i, iPos] : *$3) {