feat(type-system): implement concept_comparison with pattern matching

Added complete support for the new type system syntax including:

- concept: Base type declarations
- sub_concept: Enum and record sub-type definitions
- concept_comparison: Compile-time pattern matching with conditional guards

Parser changes:
- Added VariantPattern, FieldCondition, and Condition AST nodes
- Implemented "is" keyword for pattern matching (e.g., "CupType is Glass or CupType is Plastic")
- Added Value::Any variant to support universal type matching
- Disambiguated enum-like vs record-like sub_concept syntax

LSP updates:
- Added Value::Any match arms across code_actions, completion, hover, inlay_hints, and semantic_tokens
- Type inference and formatting support for Any values

Example fixes:
- Fixed syntax error in baker-family behaviors (missing closing brace in nested if)
- Removed deprecated core_enums.sb file
This commit is contained in:
2026-02-14 09:28:20 +00:00
parent 6e3b35e68f
commit 25d59d6107
30 changed files with 8639 additions and 6536 deletions

View File

@@ -92,7 +92,6 @@ fn get_token_documentation(token: &Token) -> Option<&'static str> {
Token::Relationship => Some("**relationship** - Defines a multi-party relationship\n\nSyntax: `relationship Name { ... }`"),
Token::Location => Some("**location** - Defines a place or setting\n\nSyntax: `location Name { ... }`"),
Token::Species => Some("**species** - Defines a species with templates\n\nSyntax: `species Name { ... }`"),
Token::Enum => Some("**enum** - Defines an enumeration type\n\nSyntax: `enum Name { ... }`"),
Token::Use => Some("**use** - Imports declarations from other files\n\nSyntax: `use path::to::item;`"),
Token::From => Some("**from** - Applies templates to a character\n\nSyntax: `character Name from Template { ... }`"),
Token::Include => Some("**include** - Includes another template\n\nSyntax: `include TemplateName`"),
@@ -171,7 +170,6 @@ fn get_declaration_name(decl: &Declaration) -> Option<String> {
| Declaration::Character(c) => Some(c.name.clone()),
| Declaration::Template(t) => Some(t.name.clone()),
| Declaration::Species(s) => Some(s.name.clone()),
| Declaration::Enum(e) => Some(e.name.clone()),
| Declaration::Location(l) => Some(l.name.clone()),
| Declaration::Institution(i) => Some(i.name.clone()),
| Declaration::Relationship(r) => Some(r.name.clone()),
@@ -191,7 +189,6 @@ fn format_declaration_hover(decl: &Declaration, _kind: &DeclKind) -> Hover {
| Declaration::Character(c) => format_character_hover(c),
| Declaration::Template(t) => format_template_hover(t),
| Declaration::Species(s) => format_species_hover(s),
| Declaration::Enum(e) => format_enum_hover(e),
| Declaration::Location(l) => format_location_hover(l),
| Declaration::Institution(i) => format_institution_hover(i),
| Declaration::Relationship(r) => format_relationship_hover(r),
@@ -319,21 +316,6 @@ fn format_species_hover(s: &crate::syntax::ast::Species) -> String {
content
}
/// Format enum hover information
fn format_enum_hover(e: &crate::syntax::ast::EnumDecl) -> String {
let mut content = format!("**enum** `{}`\n\n", e.name);
if !e.variants.is_empty() {
content.push_str("**Variants:**\n");
for variant in &e.variants {
content.push_str(&format!("- `{}`\n", variant));
}
content.push('\n');
}
content
}
/// Format location hover information
fn format_location_hover(l: &crate::syntax::ast::Location) -> String {
let mut content = format!("**location** `{}`\n\n", l.name);
@@ -567,6 +549,7 @@ fn format_value_as_type(value: &Value) -> String {
| Value::Duration(_) => "Duration".to_string(),
| Value::ProseBlock(_) => "ProseBlock".to_string(),
| Value::Override(_) => "Override".to_string(),
| Value::Any => "Any".to_string(),
}
}
@@ -597,6 +580,7 @@ fn format_value_preview(value: &Value) -> String {
| Value::Duration(duration) => format_duration(duration),
| Value::ProseBlock(prose) => format!("*prose ({} chars)*", prose.content.len()),
| Value::Override(override_val) => format!("*{} overrides*", override_val.overrides.len()),
| Value::Any => "any".to_string(),
}
}