diff options
author | eldritch horrors <pennae@lix.systems> | 2024-06-16 23:10:09 +0200 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-06-17 19:46:44 +0000 |
commit | dad8bc679e9f7bd97442249293138c7a2af311e4 (patch) | |
tree | 0fd0a1bc720f851e40b8683abaf6733fc20dd34e /src/libexpr/parser-state.hh | |
parent | 9592a9fd5740ffa0cdbbba7409b0e0aaee369d96 (diff) |
libexpr: don't immediately throw parser errors
now that destructors are hooked up we want to give the C skeleton every
real chance to actually run them. since bison does not call destructors
on values that have been passed to semantic actions even when an action
causes an abort we will also have to delete some things manually still.
Change-Id: Ia22bdaa9e969b74e17a6c496e35e6c2d86b7d750
Diffstat (limited to 'src/libexpr/parser-state.hh')
-rw-r--r-- | src/libexpr/parser-state.hh | 37 |
1 files changed, 20 insertions, 17 deletions
diff --git a/src/libexpr/parser-state.hh b/src/libexpr/parser-state.hh index 3305e05b6..94f10064f 100644 --- a/src/libexpr/parser-state.hh +++ b/src/libexpr/parser-state.hh @@ -45,34 +45,35 @@ struct ParserState SourcePath basePath; PosTable::Origin origin; const Expr::AstSymbols & s; + std::unique_ptr<Error> error; - 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); - Formals * validateFormals(Formals * formals, PosIdx pos = noPos, Symbol arg = {}); + [[nodiscard]] ParseError dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos); + [[nodiscard]] ParseError dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos); + [[nodiscard]] std::optional<ParseError> addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * e, const PosIdx pos); + [[nodiscard]] std::optional<ParseError> validateFormals(Formals * formals, PosIdx pos = noPos, Symbol arg = {}); Expr * stripIndentation(const PosIdx pos, std::vector<std::pair<PosIdx, std::variant<Expr *, StringToken>>> && es); PosIdx at(const ParserLocation & loc); }; -inline void ParserState::dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos) +inline ParseError ParserState::dupAttr(const AttrPath & attrPath, const PosIdx pos, const PosIdx prevPos) { - throw ParseError({ + return ParseError({ .msg = HintFmt("attribute '%1%' already defined at %2%", showAttrPath(symbols, attrPath), positions[prevPos]), .pos = positions[pos] }); } -inline void ParserState::dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos) +inline ParseError ParserState::dupAttr(Symbol attr, const PosIdx pos, const PosIdx prevPos) { - throw ParseError({ + return ParseError({ .msg = HintFmt("attribute '%1%' already defined at %2%", symbols[attr], positions[prevPos]), .pos = positions[pos] }); } -inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * e, const PosIdx pos) +inline std::optional<ParseError> ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * e, const PosIdx pos) { AttrPath::iterator i; // All attrpaths have at least one attr @@ -85,10 +86,10 @@ inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * if (j != attrs->attrs.end()) { if (j->second.kind != ExprAttrs::AttrDef::Kind::Inherited) { ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(j->second.e); - if (!attrs2) dupAttr({attrPath.begin(), i + 1}, pos, j->second.pos); + if (!attrs2) return dupAttr({attrPath.begin(), i + 1}, pos, j->second.pos); attrs = attrs2; } else - dupAttr({attrPath.begin(), i + 1}, pos, j->second.pos); + return dupAttr({attrPath.begin(), i + 1}, pos, j->second.pos); } else { ExprAttrs * nested = new ExprAttrs; attrs->attrs[i->symbol] = ExprAttrs::AttrDef(nested, pos); @@ -117,7 +118,7 @@ inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * for (auto & ad : ae->attrs) { auto j2 = jAttrs->attrs.find(ad.first); if (j2 != jAttrs->attrs.end()) // Attr already defined in iAttrs, error. - dupAttr(ad.first, j2->second.pos, ad.second.pos); + return dupAttr(ad.first, j2->second.pos, ad.second.pos); jAttrs->attrs.emplace(ad.first, ad.second); if (ad.second.kind == ExprAttrs::AttrDef::Kind::InheritedFrom) { auto & sel = dynamic_cast<ExprSelect &>(*ad.second.e); @@ -131,7 +132,7 @@ inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * ae->inheritFromExprs->begin(), ae->inheritFromExprs->end()); } } else { - dupAttr(attrPath, pos, j->second.pos); + return dupAttr(attrPath, pos, j->second.pos); } } else { // This attr path is not defined. Let's create it. @@ -141,9 +142,11 @@ inline void ParserState::addAttr(ExprAttrs * attrs, AttrPath && attrPath, Expr * } else { attrs->dynamicAttrs.push_back(ExprAttrs::DynamicAttrDef(i->expr, e, pos)); } + + return {}; } -inline Formals * ParserState::validateFormals(Formals * formals, PosIdx pos, Symbol arg) +inline std::optional<ParseError> ParserState::validateFormals(Formals * formals, PosIdx pos, Symbol arg) { std::sort(formals->formals.begin(), formals->formals.end(), [] (const auto & a, const auto & b) { @@ -158,18 +161,18 @@ inline Formals * ParserState::validateFormals(Formals * formals, PosIdx pos, Sym duplicate = std::min(thisDup, duplicate.value_or(thisDup)); } if (duplicate) - throw ParseError({ + return ParseError({ .msg = HintFmt("duplicate formal function argument '%1%'", symbols[duplicate->first]), .pos = positions[duplicate->second] }); if (arg && formals->has(arg)) - throw ParseError({ + return ParseError({ .msg = HintFmt("duplicate formal function argument '%1%'", symbols[arg]), .pos = positions[pos] }); - return formals; + return {}; } inline Expr * ParserState::stripIndentation(const PosIdx pos, |