Add basic classes example.
This commit is contained in:
parent
75802e6ee4
commit
940671822c
@ -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
20
examples/basic_classes.dm
Normal 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
|
||||
Loading…
Reference in New Issue
Block a user