docs: create SBIR v0.3.0 specification

Updated binary format spec for v0.3.0 type system changes:
- Section 3 (Types): concept, sub_concept, concept_comparison encoding
- Section 4 (Characters): Value/Expression discriminant renames
- Section 5 (Templates): species_base field for inheritance
- Section 12 (Life Arcs): required_fields with type annotations
- Section 13 (Enums): note on sub_concept enum distinction
- Changelog and version history updated

Also fixed clippy/import issues in LSP semantic tokens module.
This commit is contained in:
2026-02-14 14:36:34 +00:00
parent b3110c8b0f
commit 6e11126267
2 changed files with 1351 additions and 5 deletions

1247
docs/SBIR-v0.3.0-SPEC.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -16,6 +16,7 @@ use crate::syntax::{
ast::{
Declaration,
Field,
SubConceptKind,
Value,
},
lexer::{
@@ -378,11 +379,109 @@ pub fn get_semantic_tokens(doc: &Document) -> Option<SemanticTokensResult> {
}
}
},
| Declaration::Concept(_) |
Declaration::SubConcept(_) |
Declaration::ConceptComparison(_) => {
// TODO: Implement semantic highlighting for type system
// declarations
| Declaration::Concept(concept) => {
// Highlight concept name as TYPE
builder.add_token(
concept.span.start_line,
concept.span.start_col,
concept.name.len(),
token_type_index(SemanticTokenType::TYPE),
0,
);
},
| Declaration::SubConcept(sub_concept) => {
// Highlight parent concept as TYPE
let parent_positions = find_identifiers_in_span(
&doc.text,
sub_concept.span.start,
sub_concept.span.end,
std::slice::from_ref(&sub_concept.parent_concept),
);
if let Some((offset, parent_name)) = parent_positions.into_iter().next() {
let (line, col) = positions.offset_to_position(offset);
builder.add_token(
line,
col,
parent_name.len(),
token_type_index(SemanticTokenType::TYPE),
0,
);
}
// Highlight sub_concept name as ENUM
let name_positions = find_identifiers_in_span(
&doc.text,
sub_concept.span.start,
sub_concept.span.end,
std::slice::from_ref(&sub_concept.name),
);
if let Some((offset, name)) = name_positions.into_iter().next() {
let (line, col) = positions.offset_to_position(offset);
builder.add_token(
line,
col,
name.len(),
token_type_index(SemanticTokenType::ENUM),
0,
);
}
// Highlight enum variants as ENUM_MEMBER, or record fields
match &sub_concept.kind {
| SubConceptKind::Enum { variants } => {
let variant_positions = find_identifiers_in_span(
&doc.text,
sub_concept.span.start,
sub_concept.span.end,
variants,
);
for (offset, variant_name) in variant_positions {
let (line, col) = positions.offset_to_position(offset);
builder.add_token(
line,
col,
variant_name.len(),
token_type_index(SemanticTokenType::ENUM_MEMBER),
0,
);
}
},
| SubConceptKind::Record { fields } => {
for field in fields {
highlight_field(&mut builder, field);
}
},
}
},
| Declaration::ConceptComparison(comparison) => {
// Highlight comparison name as TYPE
builder.add_token(
comparison.span.start_line,
comparison.span.start_col,
comparison.name.len(),
token_type_index(SemanticTokenType::TYPE),
0,
);
// Highlight variant names as ENUM_MEMBER
for variant in &comparison.variants {
let variant_positions = find_identifiers_in_span(
&doc.text,
variant.span.start,
variant.span.end,
std::slice::from_ref(&variant.name),
);
if let Some((offset, name)) = variant_positions.into_iter().next() {
let (line, col) = positions.offset_to_position(offset);
builder.add_token(
line,
col,
name.len(),
token_type_index(SemanticTokenType::ENUM_MEMBER),
0,
);
}
}
},
}
}