More fixes to type info, etc. WIP.
This commit is contained in:
parent
fc83cf7827
commit
344761022b
@ -262,11 +262,12 @@ mod tests {
|
||||
fn compile_up_to_type_check(
|
||||
compilation_unit: &mut CompilationUnit,
|
||||
symbol_table: &mut SymbolTable,
|
||||
) -> Result<TypesTable, Vec<Diagnostic>> {
|
||||
types_table: &mut TypesTable,
|
||||
) -> Result<(), Vec<Diagnostic>> {
|
||||
compilation_unit.init_scopes(symbol_table);
|
||||
compilation_unit.gather_symbols_into(symbol_table)?;
|
||||
compilation_unit.check_names(symbol_table)?;
|
||||
compilation_unit.gather_types(symbol_table)
|
||||
compilation_unit.gather_types_into(symbol_table, types_table)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -281,7 +282,8 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut types_table = compile_up_to_type_check(&mut compilation_unit, &mut symbol_table)?;
|
||||
let mut types_table = TypesTable::new();
|
||||
compile_up_to_type_check(&mut compilation_unit, &mut symbol_table, &mut types_table)?;
|
||||
let diagnostics = compilation_unit
|
||||
.type_check(&symbol_table, &mut types_table)
|
||||
.unwrap_err();
|
||||
@ -303,7 +305,8 @@ mod tests {
|
||||
",
|
||||
)?;
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut types_table = compile_up_to_type_check(&mut compilation_unit, &mut symbol_table)?;
|
||||
let mut types_table = TypesTable::new();
|
||||
compile_up_to_type_check(&mut compilation_unit, &mut symbol_table, &mut types_table)?;
|
||||
let diagnostics = compilation_unit
|
||||
.type_check(&symbol_table, &mut types_table)
|
||||
.unwrap_err();
|
||||
@ -323,7 +326,8 @@ mod tests {
|
||||
",
|
||||
)?;
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut types_table = compile_up_to_type_check(&mut compilation_unit, &mut symbol_table)?;
|
||||
let mut types_table = TypesTable::new();
|
||||
compile_up_to_type_check(&mut compilation_unit, &mut symbol_table, &mut types_table)?;
|
||||
let diagnostics = compilation_unit
|
||||
.type_check(&symbol_table, &mut types_table)
|
||||
.unwrap_err();
|
||||
|
||||
@ -125,8 +125,7 @@ impl Call {
|
||||
TypeInfo::Function(function_symbol) => {
|
||||
CallableSymbol::Function(function_symbol.clone())
|
||||
}
|
||||
TypeInfo::ClassInstance(class_symbol) => {
|
||||
match class_symbol.constructor_symbol_owned() {
|
||||
TypeInfo::Class(class_symbol) => match class_symbol.constructor_symbol_owned() {
|
||||
None => {
|
||||
diagnostics.push(class_has_no_constructor(
|
||||
class_symbol.declared_name(),
|
||||
@ -135,8 +134,7 @@ impl Call {
|
||||
return Err(diagnostics);
|
||||
}
|
||||
Some(constructor_symbol) => CallableSymbol::Constructor(constructor_symbol),
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
&format!(
|
||||
|
||||
@ -203,12 +203,11 @@ impl Class {
|
||||
symbol_table: &SymbolTable,
|
||||
types_table: &mut TypesTable,
|
||||
) -> Result<(), Vec<Diagnostic>> {
|
||||
// instance type
|
||||
// class type
|
||||
let class_symbol = self.get_class_symbol_owned(symbol_table);
|
||||
types_table.class_instance_types_mut().insert(
|
||||
class_symbol.clone(),
|
||||
TypeInfo::ClassInstance(class_symbol.clone()),
|
||||
);
|
||||
types_table
|
||||
.class_types_mut()
|
||||
.insert(class_symbol.clone(), TypeInfo::Class(class_symbol.clone()));
|
||||
|
||||
// constructor return type
|
||||
// this works for both declared and default constructors
|
||||
@ -219,6 +218,11 @@ impl Class {
|
||||
.constructor_return_types_mut()
|
||||
.insert(constructor_symbol, TypeInfo::ClassInstance(class_symbol));
|
||||
|
||||
// now the constructor (parameters, etc.)
|
||||
if let Some(constructor) = &self.constructor {
|
||||
constructor.gather_types_into(symbol_table, types_table);
|
||||
}
|
||||
|
||||
let mut diagnostics = Vec::new();
|
||||
|
||||
// generic params
|
||||
|
||||
@ -95,26 +95,26 @@ impl CompilationUnit {
|
||||
diagnostics_result!(diagnostics)
|
||||
}
|
||||
|
||||
pub fn gather_types(&self, symbol_table: &SymbolTable) -> Result<TypesTable, Vec<Diagnostic>> {
|
||||
let mut types_table = TypesTable::new();
|
||||
pub fn gather_types_into(
|
||||
&self,
|
||||
symbol_table: &SymbolTable,
|
||||
types_table: &mut TypesTable,
|
||||
) -> Result<(), Vec<Diagnostic>> {
|
||||
let mut diagnostics = Vec::new();
|
||||
|
||||
for class in &self.classes {
|
||||
handle_diagnostics!(
|
||||
class.gather_types(symbol_table, &mut types_table),
|
||||
diagnostics
|
||||
);
|
||||
handle_diagnostics!(class.gather_types(symbol_table, types_table), diagnostics);
|
||||
}
|
||||
|
||||
for function in &self.functions {
|
||||
function.gather_types(symbol_table, &mut types_table);
|
||||
function.gather_types(symbol_table, types_table);
|
||||
}
|
||||
|
||||
for extern_function in &self.extern_functions {
|
||||
extern_function.gather_types(symbol_table, &mut types_table);
|
||||
extern_function.gather_types(symbol_table, types_table);
|
||||
}
|
||||
|
||||
ok_or_err_diagnostics!(types_table, diagnostics)
|
||||
diagnostics_result!(diagnostics)
|
||||
}
|
||||
|
||||
pub fn type_check(
|
||||
|
||||
@ -113,6 +113,12 @@ impl Constructor {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn gather_types_into(&self, symbol_table: &SymbolTable, types_table: &mut TypesTable) {
|
||||
for parameter in &self.parameters {
|
||||
parameter.gather_types_into(symbol_table, types_table);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn type_check(
|
||||
&mut self,
|
||||
symbol_table: &SymbolTable,
|
||||
@ -187,7 +193,7 @@ impl Constructor {
|
||||
let alloc_assign_destination = IrVariable::new_vr(
|
||||
ir_builder.new_t_var().into(),
|
||||
ir_builder.current_block().id(),
|
||||
&TypeInfo::ClassInstance(class_symbol.clone()),
|
||||
&TypeInfo::Class(class_symbol.clone()),
|
||||
);
|
||||
let self_variable = Rc::new(RefCell::new(alloc_assign_destination));
|
||||
|
||||
@ -276,7 +282,7 @@ impl Constructor {
|
||||
IrFunction::new(
|
||||
fqn_parts_to_string(constructor_symbol.fqn_parts()),
|
||||
ir_parameters,
|
||||
&TypeInfo::ClassInstance(class_symbol.clone()),
|
||||
&TypeInfo::Class(class_symbol.clone()),
|
||||
entry_block.clone(),
|
||||
)
|
||||
}
|
||||
|
||||
@ -92,6 +92,11 @@ impl ExternFunction {
|
||||
types_table
|
||||
.function_return_types_mut()
|
||||
.insert(function_symbol, resolved_return_type);
|
||||
|
||||
// parameters
|
||||
for parameter in &self.parameters {
|
||||
parameter.gather_types_into(symbol_table, types_table);
|
||||
}
|
||||
}
|
||||
|
||||
fn type_check_parameters(
|
||||
|
||||
@ -141,6 +141,14 @@ impl Function {
|
||||
let function_symbol = symbol_table
|
||||
.get_function_symbol_owned(self.scope_id.unwrap(), self.declared_name())
|
||||
.unwrap();
|
||||
|
||||
// self type (the signature)
|
||||
types_table.function_types_mut().insert(
|
||||
function_symbol.clone(),
|
||||
TypeInfo::Function(function_symbol.clone()),
|
||||
);
|
||||
|
||||
// put return type (temporary, this is deprecated)
|
||||
if let Some(type_use) = &self.return_type {
|
||||
let resolved_return_type = type_use.type_info(symbol_table, types_table).clone();
|
||||
types_table
|
||||
@ -151,6 +159,11 @@ impl Function {
|
||||
.function_return_types_mut()
|
||||
.insert(function_symbol, TypeInfo::Void);
|
||||
}
|
||||
|
||||
// parameters
|
||||
for parameter in &self.parameters {
|
||||
parameter.gather_types_into(symbol_table, types_table);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_return_type_info(
|
||||
|
||||
@ -224,10 +224,27 @@ impl Identifier {
|
||||
symbol_table: &SymbolTable,
|
||||
types_table: &'a TypesTable,
|
||||
) -> &'a TypeInfo {
|
||||
let variable_symbol = symbol_table
|
||||
.get_variable_symbol(self.scope_id.unwrap(), &self.name)
|
||||
let expressible_symbol = symbol_table
|
||||
.find_expressible_symbol(self.scope_id.unwrap(), &self.name)
|
||||
.unwrap();
|
||||
types_table.variable_types().get(variable_symbol).unwrap()
|
||||
match expressible_symbol {
|
||||
ExpressibleSymbol::Class(class_symbol) => {
|
||||
types_table.class_types().get(&class_symbol).unwrap()
|
||||
}
|
||||
ExpressibleSymbol::Field(field_symbol) => {
|
||||
types_table.field_types().get(&field_symbol).unwrap()
|
||||
}
|
||||
ExpressibleSymbol::Function(function_symbol) => {
|
||||
types_table.function_types().get(&function_symbol).unwrap()
|
||||
}
|
||||
ExpressibleSymbol::Parameter(parameter_symbol) => types_table
|
||||
.parameter_types()
|
||||
.get(¶meter_symbol)
|
||||
.unwrap(),
|
||||
ExpressibleSymbol::Variable(variable_symbol) => {
|
||||
types_table.variable_types().get(&variable_symbol).unwrap()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ir_expression(
|
||||
|
||||
@ -52,6 +52,16 @@ impl Parameter {
|
||||
self.type_use.check_names(symbol_table)
|
||||
}
|
||||
|
||||
pub fn gather_types_into(&self, symbol_table: &SymbolTable, types_table: &mut TypesTable) {
|
||||
let type_info = self.type_use.type_info(symbol_table, types_table).clone();
|
||||
let parameter_symbol = symbol_table
|
||||
.get_parameter_symbol_owned(self.scope_id.unwrap(), &self.declared_name)
|
||||
.unwrap();
|
||||
types_table
|
||||
.parameter_types_mut()
|
||||
.insert(parameter_symbol, type_info);
|
||||
}
|
||||
|
||||
pub fn type_check(
|
||||
&mut self,
|
||||
symbol_table: &SymbolTable,
|
||||
|
||||
@ -89,7 +89,10 @@ impl TypeUse {
|
||||
TypeSymbol::Class(class_symbol) => types_table
|
||||
.class_instance_types()
|
||||
.get(&class_symbol)
|
||||
.unwrap(),
|
||||
.expect(&format!(
|
||||
"Could not get TypeInfo for {}",
|
||||
self.declared_name
|
||||
)),
|
||||
TypeSymbol::GenericParameter(generic_parameter_symbol) => types_table
|
||||
.generic_parameter_types()
|
||||
.get(&generic_parameter_symbol)
|
||||
@ -105,7 +108,7 @@ impl TypeUse {
|
||||
let mut diagnostics: Vec<Diagnostic> = vec![];
|
||||
|
||||
match self.type_info(symbol_table, types_table) {
|
||||
TypeInfo::ClassInstance(class_symbol) => {
|
||||
TypeInfo::Class(class_symbol) => {
|
||||
// check number of params/args match
|
||||
let generic_parameters = class_symbol.generic_parameters();
|
||||
if generic_parameters.len() != self.generic_arguments.len() {
|
||||
@ -168,6 +171,7 @@ mod tests {
|
||||
use crate::diagnostic::Diagnostic;
|
||||
use crate::parser::parse_compilation_unit;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
use crate::types_table::TypesTable;
|
||||
|
||||
#[test]
|
||||
fn type_check_generics() -> Result<(), Vec<Diagnostic>> {
|
||||
@ -184,11 +188,12 @@ mod tests {
|
||||
)?;
|
||||
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut types_table = TypesTable::new();
|
||||
|
||||
compilation_unit.init_scopes(&mut symbol_table);
|
||||
compilation_unit.gather_symbols_into(&mut symbol_table)?;
|
||||
compilation_unit.check_names(&mut symbol_table)?;
|
||||
let mut types_table = compilation_unit.gather_types(&symbol_table)?;
|
||||
compilation_unit.gather_types_into(&symbol_table, &mut types_table)?;
|
||||
compilation_unit.type_check(&mut symbol_table, &mut types_table)?;
|
||||
|
||||
Ok(())
|
||||
|
||||
@ -1 +1,46 @@
|
||||
mod symbols;
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
use crate::type_info::TypeInfo;
|
||||
use crate::types_table::TypesTable;
|
||||
use std::rc::Rc;
|
||||
|
||||
fn create_simple_primitive(name: &str) -> ClassSymbol {
|
||||
ClassSymbol::new(
|
||||
&Rc::from(name),
|
||||
None,
|
||||
vec![Rc::from(name)],
|
||||
true,
|
||||
0, // global
|
||||
vec![],
|
||||
None,
|
||||
vec![],
|
||||
vec![],
|
||||
)
|
||||
}
|
||||
|
||||
pub fn insert_intrinsic_symbols(symbol_table: &mut SymbolTable) {
|
||||
let primitives = [
|
||||
create_simple_primitive("Int"),
|
||||
create_simple_primitive("Double"),
|
||||
create_simple_primitive("String"),
|
||||
];
|
||||
for primitive in primitives {
|
||||
symbol_table.insert_class_symbol(Rc::new(primitive));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_intrinsic_types(symbol_table: &SymbolTable, types_table: &mut TypesTable) {
|
||||
let primitives = ["Int", "Double", "String"];
|
||||
for primitive in primitives {
|
||||
let symbol = symbol_table.get_class_symbol(0, primitive).unwrap().clone();
|
||||
let type_info = match primitive {
|
||||
"Int" => TypeInfo::Integer,
|
||||
"Double" => TypeInfo::Double,
|
||||
"String" => TypeInfo::String,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
types_table
|
||||
.class_instance_types_mut()
|
||||
.insert(symbol, type_info);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
use crate::symbol_table::SymbolTable;
|
||||
|
||||
pub fn add_intrinsic_symbols(symbol_table: &mut SymbolTable) {}
|
||||
@ -124,6 +124,7 @@ mod tests {
|
||||
use crate::diagnostic::Diagnostic;
|
||||
use crate::parser::parse_compilation_unit;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
use crate::types_table::TypesTable;
|
||||
|
||||
#[test]
|
||||
fn overlapping_assignments_bug_when_k_2() -> Result<(), Vec<Diagnostic>> {
|
||||
@ -139,12 +140,13 @@ mod tests {
|
||||
)?;
|
||||
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
let mut types_table = TypesTable::new();
|
||||
|
||||
compilation_unit.init_scopes(&mut symbol_table);
|
||||
compilation_unit.gather_symbols_into(&mut symbol_table)?;
|
||||
compilation_unit.check_names(&mut symbol_table)?;
|
||||
let mut types_table = compilation_unit.gather_types(&symbol_table)?;
|
||||
compilation_unit.type_check(&mut symbol_table, &mut types_table)?;
|
||||
compilation_unit.gather_types_into(&symbol_table, &mut types_table)?;
|
||||
compilation_unit.type_check(&symbol_table, &mut types_table)?;
|
||||
|
||||
let main = compilation_unit
|
||||
.functions()
|
||||
|
||||
@ -51,7 +51,7 @@ impl IrField {
|
||||
TypeInfo::Integer => VmTypeInfo::Int,
|
||||
TypeInfo::Double => VmTypeInfo::Double,
|
||||
TypeInfo::String => VmTypeInfo::String,
|
||||
TypeInfo::ClassInstance(class_symbol) => {
|
||||
TypeInfo::Class(class_symbol) => {
|
||||
VmTypeInfo::ClassInstance(fqn_parts_to_string(class_symbol.fqn_parts()).into())
|
||||
}
|
||||
TypeInfo::GenericType(_) => VmTypeInfo::Any,
|
||||
|
||||
@ -2,7 +2,7 @@ pub mod ast;
|
||||
pub mod constants_table;
|
||||
pub mod diagnostic;
|
||||
pub mod error_codes;
|
||||
mod intrinsics;
|
||||
pub mod intrinsics;
|
||||
pub mod ir;
|
||||
pub mod lexer;
|
||||
pub mod parser;
|
||||
|
||||
@ -11,7 +11,11 @@ pub enum TypeInfo {
|
||||
Double,
|
||||
String,
|
||||
Function(Rc<FunctionSymbol>),
|
||||
Class(Rc<ClassSymbol>),
|
||||
|
||||
#[deprecated]
|
||||
ClassInstance(Rc<ClassSymbol>),
|
||||
|
||||
GenericType(Rc<GenericParameterSymbol>),
|
||||
Void,
|
||||
}
|
||||
@ -33,6 +37,9 @@ impl Display for TypeInfo {
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
TypeInfo::Class(class_symbol) => {
|
||||
write!(f, "Class({:?})", class_symbol)
|
||||
}
|
||||
TypeInfo::ClassInstance(class_symbol) => {
|
||||
write!(f, "{}", class_symbol.declared_name())
|
||||
}
|
||||
@ -68,6 +75,10 @@ impl TypeInfo {
|
||||
TypeInfo::Function(_) => {
|
||||
unimplemented!("Type matching on Functions not yet supported.")
|
||||
}
|
||||
TypeInfo::Class(class_symbol) => match other {
|
||||
TypeInfo::Class(other_class_symbol) => class_symbol == other_class_symbol,
|
||||
_ => false,
|
||||
},
|
||||
TypeInfo::ClassInstance(class_symbol) => {
|
||||
match other {
|
||||
TypeInfo::ClassInstance(other_class_symbol) => {
|
||||
|
||||
@ -10,10 +10,12 @@ use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct TypesTable {
|
||||
class_types: HashMap<Rc<ClassSymbol>, TypeInfo>,
|
||||
class_instance_types: HashMap<Rc<ClassSymbol>, TypeInfo>,
|
||||
generic_parameter_types: HashMap<Rc<GenericParameterSymbol>, TypeInfo>,
|
||||
field_types: HashMap<Rc<FieldSymbol>, TypeInfo>,
|
||||
constructor_return_types: HashMap<Rc<ConstructorSymbol>, TypeInfo>,
|
||||
function_types: HashMap<Rc<FunctionSymbol>, TypeInfo>,
|
||||
function_return_types: HashMap<Rc<FunctionSymbol>, TypeInfo>,
|
||||
parameter_types: HashMap<Rc<ParameterSymbol>, TypeInfo>,
|
||||
variable_types: HashMap<Rc<VariableSymbol>, TypeInfo>,
|
||||
@ -22,16 +24,26 @@ pub struct TypesTable {
|
||||
impl TypesTable {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
class_types: HashMap::new(),
|
||||
class_instance_types: HashMap::new(),
|
||||
generic_parameter_types: HashMap::new(),
|
||||
field_types: HashMap::new(),
|
||||
parameter_types: HashMap::new(),
|
||||
variable_types: HashMap::new(),
|
||||
function_types: HashMap::new(),
|
||||
function_return_types: HashMap::new(),
|
||||
constructor_return_types: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn class_types(&self) -> &HashMap<Rc<ClassSymbol>, TypeInfo> {
|
||||
&self.class_types
|
||||
}
|
||||
|
||||
pub fn class_types_mut(&mut self) -> &mut HashMap<Rc<ClassSymbol>, TypeInfo> {
|
||||
&mut self.class_types
|
||||
}
|
||||
|
||||
pub fn class_instance_types(&self) -> &HashMap<Rc<ClassSymbol>, TypeInfo> {
|
||||
&self.class_instance_types
|
||||
}
|
||||
@ -74,18 +86,30 @@ impl TypesTable {
|
||||
&mut self.variable_types
|
||||
}
|
||||
|
||||
pub fn function_types(&self) -> &HashMap<Rc<FunctionSymbol>, TypeInfo> {
|
||||
&self.function_types
|
||||
}
|
||||
|
||||
pub fn function_types_mut(&mut self) -> &mut HashMap<Rc<FunctionSymbol>, TypeInfo> {
|
||||
&mut self.function_types
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub fn function_return_types(&self) -> &HashMap<Rc<FunctionSymbol>, TypeInfo> {
|
||||
&self.function_return_types
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub fn function_return_types_mut(&mut self) -> &mut HashMap<Rc<FunctionSymbol>, TypeInfo> {
|
||||
&mut self.function_return_types
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub fn constructor_return_types(&self) -> &HashMap<Rc<ConstructorSymbol>, TypeInfo> {
|
||||
&self.constructor_return_types
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub fn constructor_return_types_mut(
|
||||
&mut self,
|
||||
) -> &mut HashMap<Rc<ConstructorSymbol>, TypeInfo> {
|
||||
|
||||
@ -2,8 +2,10 @@
|
||||
mod e2e_tests {
|
||||
use dmc_lib::constants_table::ConstantsTable;
|
||||
use dmc_lib::diagnostic::Diagnostic;
|
||||
use dmc_lib::intrinsics::{insert_intrinsic_symbols, insert_intrinsic_types};
|
||||
use dmc_lib::parser::parse_compilation_unit;
|
||||
use dmc_lib::symbol_table::SymbolTable;
|
||||
use dmc_lib::types_table::TypesTable;
|
||||
use dvm_lib::vm::class::Class;
|
||||
use dvm_lib::vm::constant::{Constant, StringConstant};
|
||||
use dvm_lib::vm::function::Function;
|
||||
@ -36,11 +38,16 @@ mod e2e_tests {
|
||||
};
|
||||
|
||||
let mut symbol_table = SymbolTable::new();
|
||||
symbol_table.push_module_scope("global_scope");
|
||||
insert_intrinsic_symbols(&mut symbol_table);
|
||||
|
||||
let mut types_table = TypesTable::new();
|
||||
insert_intrinsic_types(&symbol_table, &mut types_table);
|
||||
|
||||
compilation_unit.init_scopes(&mut symbol_table);
|
||||
compilation_unit.gather_symbols_into(&mut symbol_table)?;
|
||||
compilation_unit.check_names(&mut symbol_table)?;
|
||||
let mut types_table = compilation_unit.gather_types(&symbol_table)?;
|
||||
compilation_unit.gather_types_into(&symbol_table, &mut types_table)?;
|
||||
compilation_unit.type_check(&symbol_table, &mut types_table)?;
|
||||
|
||||
let (ir_classes, mut ir_functions) = compilation_unit.to_ir(&symbol_table, &types_table);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user