feat(furc/parser): add pre- and post- conditions

This commit is contained in:
2026-08-09 17:17:47 +02:00
parent 7ebc27cab9
commit 47e8b1bf51
5 changed files with 38 additions and 6 deletions
+10 -4
View File
@@ -116,10 +116,16 @@ struct var_decl_node final : public decl_node {
struct func_decl_node final : public decl_node {
decl_type_e decl_type() const override { return Function; }
std::string name;
ast_type type;
std::vector<var_decl_node> params;
std::optional<comp_stmt_node> body;
struct def_s {
comp_stmt_node body;
std::vector<expr_node*> preConds;
std::vector<expr_node*> postConds;
};
std::string name;
ast_type type;
std::vector<var_decl_node> params;
std::optional<def_s> def;
};
class expr_node : public stmt_node {
+4
View File
@@ -76,6 +76,8 @@ struct token {
While, /**< `while` */
Public, /**< `public` */
Private, /**< `private` */
Pre, /**< `pre` */
Post, /**< `post` */
Pointerof, /**< `pointerof` */
Sizeof, /**< `sizeof` */
@@ -186,6 +188,8 @@ struct token {
case token::While: return os << "while";
case token::Public: return os << "public";
case token::Private: return os << "private";
case token::Pre: return os << "pre";
case token::Post: return os << "post";
case token::Pointerof: return os << "pointerof";
case token::Sizeof: return os << "sizeof";
case token::Lengthof: return os << "lengthof";
+2
View File
@@ -52,6 +52,8 @@ token lexer::next_token() {
{ "while", token::While },
{ "public", token::Public },
{ "private", token::Private },
{ "pre", token::Pre },
{ "post", token::Post },
{ "pointerof", token::Pointerof },
{ "sizeof", token::Sizeof },
{ "lengthof", token::Lengthof },
+21 -1
View File
@@ -99,7 +99,27 @@ decl_node* parser::parse_decl() {
return m_arena->allocate<func_decl_node>(std::move(func));
}
func.body = parse_comp();
func_decl_node::def_s def;
while (m_lexer.peek_token().type == token::Pre || m_lexer.peek_token().type == token::Post) {
auto token = m_lexer.next_token();
eat_token(token::LParen);
auto* expr = parse_expr();
eat_token(token::RParen);
switch (token.type) {
case token::Pre: {
def.preConds.push_back(expr);
} break;
case token::Post: {
def.postConds.push_back(expr);
} break;
default: throw std::runtime_error("unreachable");
}
}
def.body = parse_comp();
func.def = std::move(def);
return m_arena->allocate<func_decl_node>(std::move(func));
}
+1 -1
View File
@@ -6,7 +6,7 @@ int main(void) {
furlang::arena arena;
std::string_view content = R"(
func main(argc: u64) -> s32 {
func main(argc: u64) -> s32 pre(arc > 1) {
x: s32 = 1 + 2 * 3;
if (x == 9) return 1;
else return 0;