Parse rules

This commit is contained in:
2026-04-29 18:03:02 -06:00
parent e864ea9145
commit 5d250ea9ad

View File

@@ -72,13 +72,19 @@ pub fn items<'db>(db: &'db dyn Database, file: workspace::File) -> Vec<ItemMeta<
/// Parses an [ItemMeta] into its corresponding [Item].
pub fn item<'db>(db: &'db dyn Database, meta: ItemMeta<'db>) -> WithAst<Item<'db>> {
match meta.kind(db) {
ItemKind::Relation => todo!(),
ItemKind::TypeAlias => todo!(),
ItemKind::Import => todo!(),
ItemKind::Rule => todo!(),
ItemKind::Assumption => todo!(),
}
use Item::*;
let ast = meta.ast(db);
let item = match meta.kind(db) {
ItemKind::Relation => Relation(relation(db, ast)),
ItemKind::TypeAlias => TypeAlias(type_alias(db, ast)),
ItemKind::Import => Import(import(db, ast)),
ItemKind::Rule => Rule(rule(db, ast)),
ItemKind::Assumption => Assumption(assumption(db, ast)),
};
WithAst::new(ast, item)
}
/// Common information on top-level items.
@@ -106,6 +112,12 @@ pub enum Item<'db> {
Assumption(Assumption<'db>),
}
/// Parses [Relation] from an [AstNode].
#[salsa::tracked]
pub fn relation<'db>(db: &'db dyn Database, ast: AstNode) -> Relation<'db> {
todo!()
}
/// A definition of a relation.
#[salsa::tracked]
pub struct Relation<'db> {
@@ -122,6 +134,12 @@ pub struct Relation<'db> {
pub ty: WithAst<Type>,
}
/// Parses [TypeAlias] from an [AstNode].
#[salsa::tracked]
pub fn type_alias<'db>(db: &'db dyn Database, ast: AstNode) -> TypeAlias<'db> {
todo!()
}
/// An abstract type alias (syntax representation).
#[salsa::tracked]
pub struct TypeAlias<'db> {
@@ -132,18 +150,68 @@ pub struct TypeAlias<'db> {
pub ty: WithAst<Type>,
}
/// Parses [Rule] from an [AstNode].
// TODO: after confirming that syntax is desirable, parse negation syntax
#[salsa::tracked]
pub fn rule<'db>(db: &'db dyn Database, ast: AstNode) -> Rule<'db> {
let relation = ast.expect_field(db, "relation").with_contents(db);
let head = expr(db, ast.expect_field(db, "head"));
let body = ast.get_field(db, "body").map(|ast| rule_body(db, ast));
Rule::new(db, relation, head, body)
}
/// An abstract rule.
#[salsa::tracked]
pub struct Rule<'db> {}
pub struct Rule<'db> {
/// The name of the relation this rule stores to.
pub relation: WithAst<String>,
/// The expression making up this rule's head.
pub head: Expr,
/// This rule's body.
pub body: Option<RuleBody<'db>>,
}
/// Parses [Import] from an [AstNode].
#[salsa::tracked]
pub fn import<'db>(db: &'db dyn Database, ast: AstNode) -> Import<'db> {
todo!()
}
/// An abstract import item.
#[salsa::tracked]
pub struct Import<'db> {}
/// Parses [Assumption] from an [AstNode].
#[salsa::tracked]
pub fn assumption<'db>(db: &'db dyn Database, ast: AstNode) -> Assumption<'db> {
todo!()
}
/// An abstract assumption.
#[salsa::tracked]
pub struct Assumption<'db> {}
/// Parses a rule body.
// TODO: parallelize?
#[salsa::tracked]
pub fn rule_body<'db>(db: &'db dyn Database, ast: AstNode) -> RuleBody<'db> {
let clauses = ast
.get_fields(db, "clause")
.map(|clause| expr(db, clause))
.collect();
RuleBody::new(db, clauses)
}
/// An abstract rule body.
#[salsa::tracked]
pub struct RuleBody<'db> {
/// Each clause in the body.
pub clauses: Vec<Expr>,
}
/// Parse an expression from the AST.
#[salsa::tracked]
pub fn expr(db: &dyn Database, ast: AstNode) -> Expr {
@@ -222,7 +290,7 @@ impl ir::ProgramInfo for AstProgramInfo {
}
/// Extra [ExprKind] variants in the parse stage.
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ExprExtra {
/// A structured tuple of sub-expressions.
Tuple(Vec<Expr>),