Add interface/class test case.
This commit is contained in:
parent
d8fe97b401
commit
41ab922f2c
13
sketching/may_2025/int.dm
Normal file
13
sketching/may_2025/int.dm
Normal file
@ -0,0 +1,13 @@
|
||||
int Greeter {
|
||||
fn greet() -> Void
|
||||
}
|
||||
|
||||
class MyGreeter(fld greeting: String) : Greeter {
|
||||
fn greet() {
|
||||
println(greeting);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let greeter: Greeter = MyGreeter("Hello, World!");
|
||||
}
|
@ -494,7 +494,7 @@ fn build_interface_declaration(file_id: usize, interface_pair: Pair<Rule>) -> In
|
||||
Rule::Pub => {
|
||||
is_public = true;
|
||||
}
|
||||
Rule::Int => {}
|
||||
Rule::IntKw => {}
|
||||
Rule::Identifier => {
|
||||
identifier = Some(build_identifier(file_id, inner_pair));
|
||||
}
|
||||
@ -671,7 +671,46 @@ fn build_interface_function_declaration(
|
||||
file_id: usize,
|
||||
interface_function_pair: Pair<Rule>,
|
||||
) -> InterfaceFunctionDeclaration {
|
||||
todo!()
|
||||
let mut modifier = None;
|
||||
let mut generics = GenericParameters::default();
|
||||
let mut identifier = None;
|
||||
let mut parameters = Parameters::default();
|
||||
let mut return_type = None;
|
||||
let mut body = None;
|
||||
|
||||
for inner_pair in interface_function_pair.into_inner() {
|
||||
match inner_pair.as_rule() {
|
||||
Rule::Def | Rule::Fn => {},
|
||||
Rule::FunctionModifier => {
|
||||
modifier = Some(build_function_modifier(file_id, inner_pair));
|
||||
},
|
||||
Rule::GenericParameters => {
|
||||
generics = build_generic_parameters(file_id, inner_pair);
|
||||
}
|
||||
Rule::Identifier => {
|
||||
identifier = Some(build_identifier(file_id, inner_pair));
|
||||
}
|
||||
Rule::Parameters => {
|
||||
parameters = build_parameters(file_id, inner_pair);
|
||||
}
|
||||
Rule::ReturnType => {
|
||||
return_type = Some(build_return_type(file_id, inner_pair));
|
||||
}
|
||||
Rule::FunctionBody => {
|
||||
body = Some(build_function_body(file_id, inner_pair));
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
InterfaceFunctionDeclaration {
|
||||
modifier,
|
||||
generics,
|
||||
identifier: identifier.unwrap(),
|
||||
parameters,
|
||||
return_type: return_type.unwrap(),
|
||||
body
|
||||
}
|
||||
}
|
||||
|
||||
fn build_interface_operator_function_declaration(
|
||||
|
@ -906,7 +906,16 @@ fn gather_class_constructor(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
todo!()
|
||||
for parameter in &mut class_constructor.0 {
|
||||
match parameter {
|
||||
ClassConstructorParameter::Property(property) => {
|
||||
gather_property_declaration(property, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
ClassConstructorParameter::Field(field) => {
|
||||
gather_field_declaration(field, symbol_table, fqn_context, diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn gather_property_declaration(
|
||||
@ -915,7 +924,23 @@ fn gather_property_declaration(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
todo!()
|
||||
let insert_result = symbol_table.insert_class_member_symbol(
|
||||
ClassMemberSymbol::new(
|
||||
&property_declaration.identifier.name(),
|
||||
false,
|
||||
Some(SourceDefinition::from_identifier(&property_declaration.identifier))
|
||||
)
|
||||
);
|
||||
if let Err(insert_error) = insert_result {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
&property_declaration.identifier.name(),
|
||||
property_declaration.identifier.file_id(),
|
||||
property_declaration.identifier.range(),
|
||||
"Data Member",
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn gather_field_declaration(
|
||||
@ -924,7 +949,23 @@ fn gather_field_declaration(
|
||||
fqn_context: &mut FqnContext,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
todo!()
|
||||
let insert_result = symbol_table.insert_class_member_symbol(
|
||||
ClassMemberSymbol::new(
|
||||
&field_declaration.identifier.name(),
|
||||
true,
|
||||
Some(SourceDefinition::from_identifier(&field_declaration.identifier))
|
||||
)
|
||||
);
|
||||
if let Err(insert_error) = insert_result {
|
||||
handle_insert_error(
|
||||
insert_error,
|
||||
&field_declaration.identifier.name(),
|
||||
field_declaration.identifier.file_id(),
|
||||
field_declaration.identifier.range(),
|
||||
"Data Member",
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* Statements */
|
||||
|
@ -146,7 +146,9 @@ fn resolve_implements_list(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
todo!()
|
||||
for type_use in &mut implements_list.0 {
|
||||
resolve_type_use(type_use, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
/* Function parameters */
|
||||
@ -278,18 +280,23 @@ fn resolve_module_level_declaration(
|
||||
) {
|
||||
use crate::ast::ModuleLevelDeclaration::*;
|
||||
match declaration {
|
||||
Module(module_declaration) => {
|
||||
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
|
||||
}
|
||||
Interface(interface_declaration) => {
|
||||
resolve_interface_declaration(interface_declaration, symbol_table, diagnostics);
|
||||
}
|
||||
Function(function_definition) => {
|
||||
resolve_function_definition(function_definition, symbol_table, diagnostics)
|
||||
}
|
||||
Class(class_declaration) => {
|
||||
resolve_class_declaration(class_declaration, symbol_table, diagnostics);
|
||||
}
|
||||
PlatformFunction(platform_function_declaration) => resolve_platform_function_declaration(
|
||||
platform_function_declaration,
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
),
|
||||
Class(class_declaration) => {
|
||||
// todo
|
||||
}
|
||||
_ => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,7 +305,32 @@ fn resolve_interface_level_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
todo!()
|
||||
use crate::ast::InterfaceLevelDeclaration::*;
|
||||
match declaration {
|
||||
Module(module_declaration) => {
|
||||
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
|
||||
}
|
||||
Interface(interface_declaration) => {
|
||||
resolve_interface_declaration(interface_declaration, symbol_table, diagnostics);
|
||||
}
|
||||
Class(class_declaration) => {
|
||||
resolve_class_declaration(class_declaration, symbol_table, diagnostics);
|
||||
}
|
||||
Function(interface_function_declaration) => {
|
||||
resolve_interface_function_declaration(
|
||||
interface_function_declaration,
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
OperatorFunction(interface_operator_function_declaration) => {
|
||||
resolve_interface_operator_function_declaration(
|
||||
interface_operator_function_declaration,
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_class_level_declaration(
|
||||
@ -306,7 +338,41 @@ fn resolve_class_level_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
todo!()
|
||||
use crate::ast::ClassLevelDeclaration::*;
|
||||
match declaration {
|
||||
Module(module_declaration) => {
|
||||
resolve_module_declaration(module_declaration, symbol_table, diagnostics);
|
||||
}
|
||||
Interface(interface_declaration) => {
|
||||
resolve_interface_declaration(interface_declaration, symbol_table, diagnostics);
|
||||
}
|
||||
Class(class_declaration) => {
|
||||
resolve_class_declaration(class_declaration, symbol_table, diagnostics);
|
||||
}
|
||||
Function(function_definition) => {
|
||||
resolve_function_definition(function_definition, symbol_table, diagnostics);
|
||||
}
|
||||
OperatorFunction(operator_function_definition) => {
|
||||
resolve_operator_function_definition(
|
||||
operator_function_definition,
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
PlatformFunction(platform_function_declaration) => {
|
||||
resolve_platform_function_declaration(
|
||||
platform_function_declaration,
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
Property(property_declaration) => {
|
||||
resolve_property_declaration(property_declaration, symbol_table, diagnostics);
|
||||
}
|
||||
Field(field_declaration) => {
|
||||
resolve_field_declaration(field_declaration, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Main Declarations */
|
||||
@ -400,7 +466,19 @@ fn resolve_interface_function_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
todo!()
|
||||
resolve_parameters(
|
||||
&mut interface_function_declaration.parameters,
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
resolve_return_type(
|
||||
&mut interface_function_declaration.return_type,
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
if let Some(body) = &mut interface_function_declaration.body {
|
||||
resolve_function_body(body, symbol_table, diagnostics);
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_interface_operator_function_declaration(
|
||||
@ -439,7 +517,13 @@ fn resolve_class_constructor(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
todo!()
|
||||
use crate::ast::ClassConstructorParameter::*;
|
||||
for parameter in &mut class_constructor.0 {
|
||||
match parameter {
|
||||
Property(property) => resolve_property_declaration(property, symbol_table, diagnostics),
|
||||
Field(field) => resolve_field_declaration(field, symbol_table, diagnostics),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_property_declaration(
|
||||
@ -447,7 +531,11 @@ fn resolve_property_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
todo!()
|
||||
resolve_type_use(
|
||||
&mut property_declaration.declared_type,
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
|
||||
fn resolve_field_declaration(
|
||||
@ -455,7 +543,11 @@ fn resolve_field_declaration(
|
||||
symbol_table: &mut SymbolTable,
|
||||
diagnostics: &mut Vec<DmDiagnostic>,
|
||||
) {
|
||||
todo!()
|
||||
resolve_type_use(
|
||||
&mut field_declaration.declared_type,
|
||||
symbol_table,
|
||||
diagnostics,
|
||||
);
|
||||
}
|
||||
|
||||
/* Statements */
|
||||
|
@ -60,6 +60,7 @@ pub enum Symbol {
|
||||
Function(Rc<RefCell<FunctionSymbol>>),
|
||||
Parameter(Rc<ParameterSymbol>),
|
||||
Variable(Rc<VariableSymbol>),
|
||||
ClassMember(Rc<ClassMemberSymbol>),
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
@ -74,6 +75,7 @@ impl Symbol {
|
||||
Symbol::Function(s) => s.borrow().definition(),
|
||||
Symbol::Parameter(s) => s.definition(),
|
||||
Symbol::Variable(s) => s.definition(),
|
||||
Symbol::ClassMember(s) => s.definition(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -446,3 +448,39 @@ impl Debug for VariableSymbol {
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/* Class Member */
|
||||
|
||||
pub struct ClassMemberSymbol {
|
||||
declared_name: String,
|
||||
is_field: bool,
|
||||
definition: Option<SourceDefinition>,
|
||||
}
|
||||
|
||||
impl ClassMemberSymbol {
|
||||
pub fn new(declared_name: &str, is_field: bool, definition: Option<SourceDefinition>) -> Self {
|
||||
ClassMemberSymbol {
|
||||
declared_name: declared_name.to_string(),
|
||||
is_field,
|
||||
definition,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl SymbolInner for ClassMemberSymbol {
|
||||
fn declared_name(&self) -> &str {
|
||||
self.declared_name.as_str()
|
||||
}
|
||||
|
||||
fn definition(&self) -> Option<SourceDefinition> {
|
||||
self.definition.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for ClassMemberSymbol {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("ClassMemberSymbol")
|
||||
.field("declared_name", &self.declared_name)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ use std::collections::HashMap;
|
||||
use std::fmt::Display;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
||||
/* Scope */
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -17,6 +18,7 @@ struct Scope {
|
||||
function_symbols: HashMap<String, Rc<RefCell<FunctionSymbol>>>,
|
||||
parameter_symbols: HashMap<String, Rc<ParameterSymbol>>,
|
||||
variable_symbols: HashMap<String, Rc<VariableSymbol>>,
|
||||
class_member_symbols: HashMap<String, Rc<ClassMemberSymbol>>,
|
||||
debug_name: String,
|
||||
}
|
||||
|
||||
@ -30,6 +32,7 @@ impl Scope {
|
||||
function_symbols: HashMap::new(),
|
||||
parameter_symbols: HashMap::new(),
|
||||
variable_symbols: HashMap::new(),
|
||||
class_member_symbols: HashMap::new(),
|
||||
debug_name,
|
||||
}
|
||||
}
|
||||
@ -128,6 +131,11 @@ impl Scope {
|
||||
.get(declared_name)
|
||||
.map(|p| Symbol::Parameter(p.clone()))
|
||||
})
|
||||
.or_else(|| {
|
||||
self.class_member_symbols
|
||||
.get(declared_name)
|
||||
.map(|cms| Symbol::ClassMember(cms.clone()))
|
||||
})
|
||||
.or_else(|| {
|
||||
self.function_symbols
|
||||
.get(declared_name)
|
||||
@ -318,6 +326,22 @@ impl SymbolTable {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_class_member_symbol(
|
||||
&mut self,
|
||||
class_member_symbol: ClassMemberSymbol,
|
||||
) -> Result<(), SymbolInsertError> {
|
||||
let current_scope = self.scopes.get_mut(self.current_scope_id).unwrap();
|
||||
if let Some(defined_symbol) = current_scope.get_expressible_by_declared_name(class_member_symbol.declared_name()) {
|
||||
Err(SymbolAlreadyDefined(defined_symbol))
|
||||
} else {
|
||||
current_scope.class_member_symbols.insert(
|
||||
class_member_symbol.declared_name().to_string(),
|
||||
Rc::new(class_member_symbol),
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup_type_by_declared_name(
|
||||
&self,
|
||||
declared_name: &str,
|
||||
|
Loading…
Reference in New Issue
Block a user