Add basic classes example.

This commit is contained in:
Jesse Brault 2026-03-12 16:24:20 -05:00
parent 75802e6ee4
commit 940671822c
2 changed files with 42 additions and 1 deletions

View File

@ -1,7 +1,7 @@
use crate::ast::constructor::Constructor;
use crate::ast::field::Field;
use crate::ast::function::Function;
use crate::diagnostic::Diagnostic;
use crate::diagnostic::{Diagnostic, SecondaryLabel};
use crate::source_range::SourceRange;
use crate::symbol::class_symbol::ClassSymbol;
use crate::symbol_table::{SymbolInsertError, SymbolTable};
@ -48,6 +48,7 @@ impl Class {
.insert_class_symbol(to_insert)
.map_err(|e| match e {
SymbolInsertError::AlreadyDeclared(already_declared) => {
let symbol = already_declared.symbol().borrow();
vec![
Diagnostic::new(
&format!(
@ -57,6 +58,11 @@ impl Class {
self.declared_name_source_range.start(),
self.declared_name_source_range.end(),
)
.with_secondary_labels(&[SecondaryLabel::new(
symbol.declared_name_source_range().start(),
symbol.declared_name_source_range().end(),
Some("Symbol declared here.".to_string()),
)])
.with_reporter(file!(), line!()),
]
}
@ -151,6 +157,10 @@ impl Class {
.flatten()
.for_each(|diagnostic| diagnostics.push(diagnostic));
if !diagnostics.is_empty() {
return Err(diagnostics);
}
if let Some(constructor) = &mut self.constructor {
match constructor.type_check(symbol_table) {
Ok(_) => {}
@ -160,6 +170,10 @@ impl Class {
}
}
if !diagnostics.is_empty() {
return Err(diagnostics);
}
self.functions
.iter_mut()
.map(|function| function.type_check(symbol_table))
@ -167,6 +181,10 @@ impl Class {
.flatten()
.for_each(|diagnostic| diagnostics.push(diagnostic));
if !diagnostics.is_empty() {
return Err(diagnostics);
}
// We need to determine if fields are initialized or not (the latter is an error).
// First phase: check all fields, then check constructor, leaving pending those things that
// are fields <- initialized by constructor. Then circle back to fields and check all are
@ -199,6 +217,9 @@ impl Class {
field.declared_name_source_range().start(),
field.declared_name_source_range().end(),
)
.with_primary_label_message(
"Must be initialized in declaration or constructor.",
)
.with_reporter(file!(), line!()),
)
}

20
examples/basic_classes.dm Normal file
View File

@ -0,0 +1,20 @@
class Foo
mut bar: Int = 42
ctor(_bar: Int)
end
fn baz() -> Int
bar
end
end
class Qux
fn foo() -> Foo
Foo(42)
end
end
fn main()
let crash = Qux()
end