mod lower;
#[cfg(test)]
mod tests;
use crate::diagnostic::{Diagnostic, Severity};
use crate::symbol::{
AliasId, Cardinality, EnumId, FieldId, ImportedKind, PrimitiveType, Requiredness, TypeId,
};
#[derive(Debug, Clone)]
pub struct PhenotypeModule {
pub namespace: String,
pub types: Vec<PhenotypeType>,
pub enums: Vec<EnumType>,
pub aliases: Vec<TypeAlias>,
}
#[derive(Debug, Clone)]
pub struct PhenotypeType {
pub id: TypeId,
pub singular_name: String,
pub plural_name: Option<String>,
pub fields: Vec<FieldDef>,
pub render: Vec<RenderNode>,
pub parent_context: Option<String>,
}
#[derive(Debug, Clone)]
pub struct FieldDef {
pub id: FieldId,
pub name: String,
pub requiredness: Requiredness,
pub cardinality: Cardinality,
pub ty: ValueType,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ValueType {
Primitive(PrimitiveType),
UserSingular(TypeId),
UserPlural { collection_of: TypeId },
Enum(EnumId),
TypeAlias(AliasId),
Imported(ImportedRef),
Union(Vec<ValueType>),
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ImportedRef {
pub namespace: String,
pub name: String,
pub kind: ImportedKind,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum RenderNode {
Text(String),
Emit(FieldId),
ParentFieldRef {
parent_type: String,
field_name: String,
},
Join {
field: FieldId,
separator: SeparatorExpr,
},
Eol { field: Option<FieldId> },
IfSet {
field: FieldId,
body: Vec<RenderNode>,
},
IfNotEmpty {
field: FieldId,
body: Vec<RenderNode>,
},
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SeparatorExpr {
Literal(String),
Field(FieldId),
}
#[derive(Debug, Clone)]
pub struct EnumType {
pub id: EnumId,
pub name: String,
pub members: Vec<String>,
}
#[derive(Debug, Clone)]
pub struct TypeAlias {
pub id: AliasId,
pub name: String,
pub target: ValueType,
}
pub fn lower(
ast: &crate::parser::phenotyper_actions::File,
table: &crate::symbol::SymbolTable,
file: &str,
) -> (PhenotypeModule, Vec<Diagnostic>) {
lower::lower_module(ast, table, file)
}
fn error(file: &str, summary: String) -> Diagnostic {
Diagnostic {
severity: Severity::Error,
summary,
file: file.to_string(),
line: 0,
col: 0,
explanation: None,
suggestion: None,
}
}