More work on getting example to compile, need to use fqns and proper returns.
This commit is contained in:
parent
320cdcf805
commit
55a84a98b3
@ -7,11 +7,8 @@ use crate::source_range::SourceRange;
|
|||||||
use crate::symbol::Symbol;
|
use crate::symbol::Symbol;
|
||||||
use crate::symbol::callable_symbol::CallableSymbol;
|
use crate::symbol::callable_symbol::CallableSymbol;
|
||||||
use crate::symbol::expressible_symbol::ExpressibleSymbol;
|
use crate::symbol::expressible_symbol::ExpressibleSymbol;
|
||||||
use crate::symbol::function_symbol::FunctionSymbol;
|
|
||||||
use crate::symbol_table::SymbolTable;
|
use crate::symbol_table::SymbolTable;
|
||||||
use crate::type_info::TypeInfo;
|
use crate::type_info::TypeInfo;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
pub struct Call {
|
pub struct Call {
|
||||||
callee: Box<Expression>,
|
callee: Box<Expression>,
|
||||||
@ -156,12 +153,17 @@ impl Call {
|
|||||||
self.return_type_info.as_ref().unwrap()
|
self.return_type_info.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_callee_symbol(&self) -> Rc<RefCell<FunctionSymbol>> {
|
fn get_callee_symbol(&self) -> CallableSymbol {
|
||||||
match self.callee() {
|
match self.callee() {
|
||||||
Expression::Identifier(identifier) => {
|
Expression::Identifier(identifier) => {
|
||||||
let expressible_symbol = identifier.expressible_symbol();
|
let expressible_symbol = identifier.expressible_symbol();
|
||||||
match expressible_symbol {
|
match expressible_symbol {
|
||||||
ExpressibleSymbol::Function(function_symbol) => function_symbol.clone(),
|
ExpressibleSymbol::Function(function_symbol) => {
|
||||||
|
CallableSymbol::Function(function_symbol.clone())
|
||||||
|
}
|
||||||
|
ExpressibleSymbol::Class(class_symbol) => {
|
||||||
|
CallableSymbol::Class(class_symbol.clone())
|
||||||
|
}
|
||||||
_ => panic!("Calling things other than functions not yet supported."),
|
_ => panic!("Calling things other than functions not yet supported."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,12 +183,26 @@ impl Call {
|
|||||||
})
|
})
|
||||||
.map(Option::unwrap)
|
.map(Option::unwrap)
|
||||||
.collect();
|
.collect();
|
||||||
let function_symbol = self.get_callee_symbol();
|
let callable_symbol = self.get_callee_symbol();
|
||||||
IrCall::new(
|
match callable_symbol {
|
||||||
function_symbol.borrow().declared_name_owned(),
|
CallableSymbol::Function(function_symbol) => IrCall::new(
|
||||||
arguments,
|
function_symbol.borrow().declared_name_owned(),
|
||||||
function_symbol.clone(),
|
arguments,
|
||||||
)
|
function_symbol.borrow().is_extern(),
|
||||||
|
),
|
||||||
|
CallableSymbol::Class(class_symbol) => {
|
||||||
|
let constructor_symbol = class_symbol
|
||||||
|
.borrow()
|
||||||
|
.constructor_symbol()
|
||||||
|
.cloned()
|
||||||
|
.expect("Default constructors not supported yet.");
|
||||||
|
IrCall::new(
|
||||||
|
constructor_symbol.borrow().declared_name_owned(),
|
||||||
|
arguments,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn source_range(&self) -> &SourceRange {
|
pub fn source_range(&self) -> &SourceRange {
|
||||||
|
|||||||
@ -103,10 +103,13 @@ impl Class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 5. gather functions
|
// 5. gather functions
|
||||||
|
// note: for each function, insert at index 0 a self parameter
|
||||||
let functions_diagnostics: Vec<Diagnostic> = self
|
let functions_diagnostics: Vec<Diagnostic> = self
|
||||||
.functions
|
.functions
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|function| function.gather_declared_names(symbol_table))
|
.map(|function| {
|
||||||
|
function.gather_declared_names(symbol_table, self.class_symbol.as_ref())
|
||||||
|
})
|
||||||
.filter_map(Result::err)
|
.filter_map(Result::err)
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
@ -124,13 +127,15 @@ impl Class {
|
|||||||
pub fn check_name_usages(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec<Diagnostic>> {
|
pub fn check_name_usages(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec<Diagnostic>> {
|
||||||
self.constructor
|
self.constructor
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.map(|constructor| constructor.check_name_usages(symbol_table))
|
.map(|constructor| {
|
||||||
|
constructor.check_name_usages(symbol_table, self.class_symbol.as_ref())
|
||||||
|
})
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
let fields_diagnostics: Vec<Diagnostic> = self
|
let fields_diagnostics: Vec<Diagnostic> = self
|
||||||
.fields
|
.fields
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|field| field.check_name_usages(symbol_table))
|
.map(|field| field.check_name_usages(symbol_table, self.class_symbol.as_ref()))
|
||||||
.filter_map(Result::err)
|
.filter_map(Result::err)
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
@ -139,13 +144,13 @@ impl Class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(constructor) = &mut self.constructor {
|
if let Some(constructor) = &mut self.constructor {
|
||||||
constructor.check_name_usages(symbol_table)?;
|
constructor.check_name_usages(symbol_table, self.class_symbol.as_ref())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let functions_diagnostics: Vec<Diagnostic> = self
|
let functions_diagnostics: Vec<Diagnostic> = self
|
||||||
.functions
|
.functions
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|function| function.check_name_usages(symbol_table))
|
.map(|function| function.check_name_usages(symbol_table, self.class_symbol.as_ref()))
|
||||||
.filter_map(Result::err)
|
.filter_map(Result::err)
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
@ -253,7 +258,10 @@ impl Class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for function in &self.functions {
|
for function in &self.functions {
|
||||||
ir_functions.push(function.to_ir(symbol_table));
|
ir_functions.push(function.to_ir(
|
||||||
|
symbol_table,
|
||||||
|
Some(self.class_symbol.as_ref().unwrap().clone()),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_functions
|
ir_functions
|
||||||
@ -321,9 +329,10 @@ mod tests {
|
|||||||
let mut ir_functions = compilation_unit.to_ir(&symbol_table);
|
let mut ir_functions = compilation_unit.to_ir(&symbol_table);
|
||||||
let mut constants_table = ConstantsTable::new();
|
let mut constants_table = ConstantsTable::new();
|
||||||
for ir_function in &mut ir_functions {
|
for ir_function in &mut ir_functions {
|
||||||
|
println!("{}", ir_function);
|
||||||
let (_, stack_size) = ir_function.assign_registers(8);
|
let (_, stack_size) = ir_function.assign_registers(8);
|
||||||
let vm_function = ir_function.assemble(stack_size, &mut constants_table);
|
// let vm_function = ir_function.assemble(stack_size, &mut constants_table);
|
||||||
println!("{}", vm_function)
|
// println!("{}", vm_function)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,7 @@ impl CompilationUnit {
|
|||||||
let mut diagnostics: Vec<Diagnostic> = vec![];
|
let mut diagnostics: Vec<Diagnostic> = vec![];
|
||||||
self.functions
|
self.functions
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|f| f.gather_declared_names(symbol_table))
|
.map(|f| f.gather_declared_names(symbol_table, None))
|
||||||
.filter_map(Result::err)
|
.filter_map(Result::err)
|
||||||
.flatten()
|
.flatten()
|
||||||
.for_each(|diagnostic| diagnostics.push(diagnostic));
|
.for_each(|diagnostic| diagnostics.push(diagnostic));
|
||||||
@ -78,14 +78,14 @@ impl CompilationUnit {
|
|||||||
|
|
||||||
self.functions
|
self.functions
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|f| f.check_name_usages(symbol_table))
|
.map(|f| f.check_name_usages(symbol_table, None))
|
||||||
.filter_map(Result::err)
|
.filter_map(Result::err)
|
||||||
.flatten()
|
.flatten()
|
||||||
.for_each(|diagnostic| diagnostics.push(diagnostic));
|
.for_each(|diagnostic| diagnostics.push(diagnostic));
|
||||||
|
|
||||||
self.extern_functions
|
self.extern_functions
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|f| f.check_name_usages(symbol_table))
|
.map(|f| f.check_name_usages(symbol_table, None))
|
||||||
.filter_map(Result::err)
|
.filter_map(Result::err)
|
||||||
.flatten()
|
.flatten()
|
||||||
.for_each(|diagnostic| diagnostics.push(diagnostic));
|
.for_each(|diagnostic| diagnostics.push(diagnostic));
|
||||||
@ -139,7 +139,7 @@ impl CompilationUnit {
|
|||||||
let mut functions: Vec<IrFunction> = vec![];
|
let mut functions: Vec<IrFunction> = vec![];
|
||||||
self.functions
|
self.functions
|
||||||
.iter()
|
.iter()
|
||||||
.map(|f| f.to_ir(symbol_table))
|
.map(|f| f.to_ir(symbol_table, None))
|
||||||
.for_each(|f| functions.push(f));
|
.for_each(|f| functions.push(f));
|
||||||
self.classes
|
self.classes
|
||||||
.iter()
|
.iter()
|
||||||
|
|||||||
@ -116,11 +116,15 @@ impl Constructor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_name_usages(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec<Diagnostic>> {
|
pub fn check_name_usages(
|
||||||
|
&mut self,
|
||||||
|
symbol_table: &SymbolTable,
|
||||||
|
class_context: Option<&Rc<RefCell<ClassSymbol>>>,
|
||||||
|
) -> Result<(), Vec<Diagnostic>> {
|
||||||
let parameters_diagnostics: Vec<Diagnostic> = self
|
let parameters_diagnostics: Vec<Diagnostic> = self
|
||||||
.parameters
|
.parameters
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|param| param.check_name_usages(symbol_table))
|
.map(|param| param.check_name_usages(symbol_table, class_context))
|
||||||
.filter_map(Result::err)
|
.filter_map(Result::err)
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
|
|||||||
@ -149,7 +149,7 @@ impl Expression {
|
|||||||
}
|
}
|
||||||
Expression::Identifier(identifier) => {
|
Expression::Identifier(identifier) => {
|
||||||
let expressible_symbol = identifier.expressible_symbol();
|
let expressible_symbol = identifier.expressible_symbol();
|
||||||
Some(expressible_symbol.ir_expression())
|
Some(expressible_symbol.ir_expression(builder))
|
||||||
}
|
}
|
||||||
Expression::Add(additive_expression) => {
|
Expression::Add(additive_expression) => {
|
||||||
let ir_add = additive_expression.to_ir(builder, symbol_table);
|
let ir_add = additive_expression.to_ir(builder, symbol_table);
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use crate::ast::parameter::Parameter;
|
|||||||
use crate::ast::type_use::TypeUse;
|
use crate::ast::type_use::TypeUse;
|
||||||
use crate::diagnostic::Diagnostic;
|
use crate::diagnostic::Diagnostic;
|
||||||
use crate::source_range::SourceRange;
|
use crate::source_range::SourceRange;
|
||||||
|
use crate::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::symbol::function_symbol::FunctionSymbol;
|
use crate::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::symbol_table::{SymbolInsertError, SymbolTable};
|
use crate::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -104,16 +105,23 @@ impl ExternFunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_name_usages(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec<Diagnostic>> {
|
pub fn check_name_usages(
|
||||||
|
&mut self,
|
||||||
|
symbol_table: &SymbolTable,
|
||||||
|
class_context: Option<&Rc<RefCell<ClassSymbol>>>,
|
||||||
|
) -> Result<(), Vec<Diagnostic>> {
|
||||||
let mut diagnostics: Vec<Diagnostic> = self
|
let mut diagnostics: Vec<Diagnostic> = self
|
||||||
.parameters
|
.parameters
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|parameter| parameter.check_name_usages(symbol_table))
|
.map(|parameter| parameter.check_name_usages(symbol_table, class_context))
|
||||||
.filter_map(Result::err)
|
.filter_map(Result::err)
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
match self.return_type.check_name_usages(symbol_table) {
|
match self
|
||||||
|
.return_type
|
||||||
|
.check_name_usages(symbol_table, class_context)
|
||||||
|
{
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(mut return_type_diagnostics) => {
|
Err(mut return_type_diagnostics) => {
|
||||||
diagnostics.append(&mut return_type_diagnostics);
|
diagnostics.append(&mut return_type_diagnostics);
|
||||||
@ -126,7 +134,7 @@ impl ExternFunction {
|
|||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.set_return_type_info(self.return_type.to_type_info());
|
.set_return_type_info(self.return_type.type_info().clone());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use crate::ast::expression::Expression;
|
|||||||
use crate::ast::type_use::TypeUse;
|
use crate::ast::type_use::TypeUse;
|
||||||
use crate::diagnostic::Diagnostic;
|
use crate::diagnostic::Diagnostic;
|
||||||
use crate::source_range::SourceRange;
|
use crate::source_range::SourceRange;
|
||||||
|
use crate::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::symbol::field_symbol::FieldSymbol;
|
use crate::symbol::field_symbol::FieldSymbol;
|
||||||
use crate::symbol_table::{SymbolInsertError, SymbolTable};
|
use crate::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
@ -95,9 +96,13 @@ impl Field {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_name_usages(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec<Diagnostic>> {
|
pub fn check_name_usages(
|
||||||
|
&mut self,
|
||||||
|
symbol_table: &SymbolTable,
|
||||||
|
class_context: Option<&Rc<RefCell<ClassSymbol>>>,
|
||||||
|
) -> Result<(), Vec<Diagnostic>> {
|
||||||
if let Some(type_use) = &mut self.declared_type {
|
if let Some(type_use) = &mut self.declared_type {
|
||||||
type_use.check_name_usages(symbol_table)?;
|
type_use.check_name_usages(symbol_table, class_context)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is going to get hairy, because users might attempt to use a field in an initializer
|
// This is going to get hairy, because users might attempt to use a field in an initializer
|
||||||
@ -137,7 +142,7 @@ impl Field {
|
|||||||
match self.initializer.as_ref() {
|
match self.initializer.as_ref() {
|
||||||
Some(initializer) => {
|
Some(initializer) => {
|
||||||
let initializer_type_info = initializer.type_info();
|
let initializer_type_info = initializer.type_info();
|
||||||
let declared_type_info = type_use.to_type_info();
|
let declared_type_info = type_use.type_info();
|
||||||
if declared_type_info.is_assignable_from(initializer_type_info) {
|
if declared_type_info.is_assignable_from(initializer_type_info) {
|
||||||
declared_type_info
|
declared_type_info
|
||||||
} else {
|
} else {
|
||||||
@ -156,14 +161,14 @@ impl Field {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// easy: the declared type
|
// easy: the declared type
|
||||||
type_use.to_type_info()
|
type_use.type_info()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// type is the initializer
|
// type is the initializer
|
||||||
match self.initializer.as_ref() {
|
match self.initializer.as_ref() {
|
||||||
Some(initializer) => initializer.type_info().clone(),
|
Some(initializer) => initializer.type_info(),
|
||||||
None => {
|
None => {
|
||||||
// this is an error
|
// this is an error
|
||||||
return Err(vec![Diagnostic::new(
|
return Err(vec![Diagnostic::new(
|
||||||
@ -181,7 +186,7 @@ impl Field {
|
|||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.set_type_info(field_type_info);
|
.set_type_info(field_type_info.clone());
|
||||||
|
|
||||||
if diagnostics.is_empty() {
|
if diagnostics.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -3,10 +3,16 @@ use crate::ast::parameter::Parameter;
|
|||||||
use crate::ast::statement::Statement;
|
use crate::ast::statement::Statement;
|
||||||
use crate::ast::type_use::TypeUse;
|
use crate::ast::type_use::TypeUse;
|
||||||
use crate::diagnostic::Diagnostic;
|
use crate::diagnostic::Diagnostic;
|
||||||
|
use crate::ir::ir_assign::IrAssign;
|
||||||
|
use crate::ir::ir_expression::IrExpression;
|
||||||
use crate::ir::ir_function::IrFunction;
|
use crate::ir::ir_function::IrFunction;
|
||||||
|
use crate::ir::ir_operation::IrOperation;
|
||||||
use crate::ir::ir_parameter::IrParameter;
|
use crate::ir::ir_parameter::IrParameter;
|
||||||
|
use crate::ir::ir_statement::IrStatement;
|
||||||
|
use crate::ir::ir_variable::IrVariable;
|
||||||
use crate::source_range::SourceRange;
|
use crate::source_range::SourceRange;
|
||||||
use crate::symbol::Symbol;
|
use crate::symbol::Symbol;
|
||||||
|
use crate::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::symbol::function_symbol::FunctionSymbol;
|
use crate::symbol::function_symbol::FunctionSymbol;
|
||||||
use crate::symbol_table::{SymbolInsertError, SymbolTable};
|
use crate::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
use crate::type_info::TypeInfo;
|
use crate::type_info::TypeInfo;
|
||||||
@ -55,6 +61,7 @@ impl Function {
|
|||||||
pub fn gather_declared_names(
|
pub fn gather_declared_names(
|
||||||
&mut self,
|
&mut self,
|
||||||
symbol_table: &mut SymbolTable,
|
symbol_table: &mut SymbolTable,
|
||||||
|
class_context: Option<&Rc<RefCell<ClassSymbol>>>,
|
||||||
) -> Result<(), Vec<Diagnostic>> {
|
) -> Result<(), Vec<Diagnostic>> {
|
||||||
let mut diagnostics = vec![];
|
let mut diagnostics = vec![];
|
||||||
|
|
||||||
@ -94,6 +101,20 @@ impl Function {
|
|||||||
|
|
||||||
// handle parameters
|
// handle parameters
|
||||||
symbol_table.push_function_scope(&format!("function_scope({})", self.declared_name));
|
symbol_table.push_function_scope(&format!("function_scope({})", self.declared_name));
|
||||||
|
|
||||||
|
// first, if we are in a class context, insert a "fake" self parameter
|
||||||
|
if let Some(class_symbol) = class_context {
|
||||||
|
self.parameters.insert(
|
||||||
|
0,
|
||||||
|
Parameter::new(
|
||||||
|
"self",
|
||||||
|
SourceRange::new(0, 0),
|
||||||
|
TypeUse::new("Self", SourceRange::new(0, 0)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// now gather all names for the params
|
||||||
let mut parameter_symbols = vec![];
|
let mut parameter_symbols = vec![];
|
||||||
for parameter in &mut self.parameters {
|
for parameter in &mut self.parameters {
|
||||||
match parameter.gather_declared_names(symbol_table) {
|
match parameter.gather_declared_names(symbol_table) {
|
||||||
@ -105,6 +126,8 @@ impl Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set params on function symbol
|
||||||
function_symbol
|
function_symbol
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.set_parameters(parameter_symbols);
|
.set_parameters(parameter_symbols);
|
||||||
@ -138,7 +161,11 @@ impl Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_name_usages(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec<Diagnostic>> {
|
pub fn check_name_usages(
|
||||||
|
&mut self,
|
||||||
|
symbol_table: &SymbolTable,
|
||||||
|
class_context: Option<&Rc<RefCell<ClassSymbol>>>,
|
||||||
|
) -> Result<(), Vec<Diagnostic>> {
|
||||||
let mut diagnostics = vec![];
|
let mut diagnostics = vec![];
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
@ -146,7 +173,7 @@ impl Function {
|
|||||||
&mut self
|
&mut self
|
||||||
.parameters
|
.parameters
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.map(|parameter| parameter.check_name_usages(symbol_table))
|
.map(|parameter| parameter.check_name_usages(symbol_table, class_context))
|
||||||
.filter_map(|result| result.err())
|
.filter_map(|result| result.err())
|
||||||
.flatten()
|
.flatten()
|
||||||
.collect(),
|
.collect(),
|
||||||
@ -154,14 +181,14 @@ impl Function {
|
|||||||
|
|
||||||
// return type
|
// return type
|
||||||
if let Some(type_use) = &mut self.return_type {
|
if let Some(type_use) = &mut self.return_type {
|
||||||
match type_use.check_name_usages(symbol_table) {
|
match type_use.check_name_usages(symbol_table, class_context) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
// set return type info on function symbol
|
// set return type info on function symbol
|
||||||
self.function_symbol
|
self.function_symbol
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.set_return_type_info(type_use.to_type_info());
|
.set_return_type_info(type_use.type_info().clone());
|
||||||
}
|
}
|
||||||
Err(mut type_use_diagnostics) => {
|
Err(mut type_use_diagnostics) => {
|
||||||
diagnostics.append(&mut type_use_diagnostics);
|
diagnostics.append(&mut type_use_diagnostics);
|
||||||
@ -237,7 +264,11 @@ impl Function {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_ir(&self, symbol_table: &SymbolTable) -> IrFunction {
|
pub fn to_ir(
|
||||||
|
&self,
|
||||||
|
symbol_table: &SymbolTable,
|
||||||
|
class_context: Option<Rc<RefCell<ClassSymbol>>>,
|
||||||
|
) -> IrFunction {
|
||||||
let mut builder = IrBuilder::new();
|
let mut builder = IrBuilder::new();
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
@ -256,6 +287,26 @@ impl Function {
|
|||||||
|
|
||||||
let entry_block_id = builder.new_block();
|
let entry_block_id = builder.new_block();
|
||||||
|
|
||||||
|
// preamble
|
||||||
|
// if we are a method, we need to put parameter 0 in a register
|
||||||
|
if let Some(class_symbol) = class_context {
|
||||||
|
let self_variable = IrVariable::new_vr(
|
||||||
|
"__self".into(),
|
||||||
|
entry_block_id,
|
||||||
|
&TypeInfo::ClassInstance(class_symbol.clone()),
|
||||||
|
);
|
||||||
|
let as_rc = Rc::new(RefCell::new(self_variable));
|
||||||
|
let parameter_0 = builder.parameters()[0].clone();
|
||||||
|
// put it in the self variable
|
||||||
|
builder
|
||||||
|
.current_block_mut()
|
||||||
|
.add_statement(IrStatement::Assign(IrAssign::new(
|
||||||
|
as_rc.clone(),
|
||||||
|
IrOperation::Load(IrExpression::Parameter(parameter_0)),
|
||||||
|
)));
|
||||||
|
builder.set_self_variable(as_rc);
|
||||||
|
}
|
||||||
|
|
||||||
let function_symbol = self.function_symbol.as_ref().unwrap().borrow();
|
let function_symbol = self.function_symbol.as_ref().unwrap().borrow();
|
||||||
let return_type_info = function_symbol.return_type_info();
|
let return_type_info = function_symbol.return_type_info();
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use crate::ir::ir_block::IrBlock;
|
use crate::ir::ir_block::IrBlock;
|
||||||
use crate::ir::ir_parameter::IrParameter;
|
use crate::ir::ir_parameter::IrParameter;
|
||||||
use crate::ir::ir_statement::IrStatement;
|
use crate::ir::ir_statement::IrStatement;
|
||||||
|
use crate::ir::ir_variable::IrVariable;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -11,6 +12,7 @@ pub struct IrBuilder {
|
|||||||
t_var_counter: usize,
|
t_var_counter: usize,
|
||||||
blocks: HashMap<usize, Rc<RefCell<IrBlock>>>,
|
blocks: HashMap<usize, Rc<RefCell<IrBlock>>>,
|
||||||
current_block_builder: Option<IrBlockBuilder>,
|
current_block_builder: Option<IrBlockBuilder>,
|
||||||
|
self_variable: Option<Rc<RefCell<IrVariable>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IrBuilder {
|
impl IrBuilder {
|
||||||
@ -21,6 +23,7 @@ impl IrBuilder {
|
|||||||
t_var_counter: 0,
|
t_var_counter: 0,
|
||||||
blocks: HashMap::new(),
|
blocks: HashMap::new(),
|
||||||
current_block_builder: None,
|
current_block_builder: None,
|
||||||
|
self_variable: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +75,14 @@ impl IrBuilder {
|
|||||||
self.t_var_counter += 1;
|
self.t_var_counter += 1;
|
||||||
format!("t{}", id)
|
format!("t{}", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_self_variable(&mut self, self_variable: Rc<RefCell<IrVariable>>) {
|
||||||
|
self.self_variable = Some(self_variable);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn self_variable(&self) -> &Rc<RefCell<IrVariable>> {
|
||||||
|
self.self_variable.as_ref().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct IrBlockBuilder {
|
pub struct IrBlockBuilder {
|
||||||
|
|||||||
@ -114,7 +114,7 @@ impl LetStatement {
|
|||||||
IrOperation::Load(IrExpression::String(string_literal.content().into()))
|
IrOperation::Load(IrExpression::String(string_literal.content().into()))
|
||||||
}
|
}
|
||||||
Expression::Identifier(identifier) => {
|
Expression::Identifier(identifier) => {
|
||||||
IrOperation::Load(identifier.expressible_symbol().ir_expression())
|
IrOperation::Load(identifier.expressible_symbol().ir_expression(builder))
|
||||||
}
|
}
|
||||||
Expression::Add(additive_expression) => {
|
Expression::Add(additive_expression) => {
|
||||||
IrOperation::Add(additive_expression.to_ir(builder, symbol_table))
|
IrOperation::Add(additive_expression.to_ir(builder, symbol_table))
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
use crate::ast::type_use::TypeUse;
|
use crate::ast::type_use::TypeUse;
|
||||||
use crate::diagnostic::Diagnostic;
|
use crate::diagnostic::Diagnostic;
|
||||||
use crate::source_range::SourceRange;
|
use crate::source_range::SourceRange;
|
||||||
|
use crate::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::symbol::parameter_symbol::ParameterSymbol;
|
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||||
use crate::symbol_table::{SymbolInsertError, SymbolTable};
|
use crate::symbol_table::{SymbolInsertError, SymbolTable};
|
||||||
use crate::type_info::TypeInfo;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
@ -36,7 +36,6 @@ impl Parameter {
|
|||||||
let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new(
|
let insert_result = symbol_table.insert_parameter_symbol(ParameterSymbol::new(
|
||||||
&self.declared_name,
|
&self.declared_name,
|
||||||
self.declared_name_source_range.clone(),
|
self.declared_name_source_range.clone(),
|
||||||
TypeInfo::from_declared_name(self.type_use.declared_name()), // todo: this will blow up if type is a Class
|
|
||||||
));
|
));
|
||||||
match insert_result {
|
match insert_result {
|
||||||
Ok(parameter_symbol) => {
|
Ok(parameter_symbol) => {
|
||||||
@ -64,8 +63,21 @@ impl Parameter {
|
|||||||
Ok(self.parameter_symbol.clone().unwrap())
|
Ok(self.parameter_symbol.clone().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_name_usages(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec<Diagnostic>> {
|
pub fn check_name_usages(
|
||||||
self.type_use.check_name_usages(symbol_table)?;
|
&mut self,
|
||||||
|
symbol_table: &SymbolTable,
|
||||||
|
class_context: Option<&Rc<RefCell<ClassSymbol>>>,
|
||||||
|
) -> Result<(), Vec<Diagnostic>> {
|
||||||
|
// check the type use
|
||||||
|
self.type_use
|
||||||
|
.check_name_usages(symbol_table, class_context)?;
|
||||||
|
|
||||||
|
// set type on parameter symbol
|
||||||
|
self.parameter_symbol
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.borrow_mut()
|
||||||
|
.set_type_info(self.type_use.type_info().clone());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
use crate::diagnostic::Diagnostic;
|
use crate::diagnostic::Diagnostic;
|
||||||
use crate::source_range::SourceRange;
|
use crate::source_range::SourceRange;
|
||||||
use crate::symbol::type_symbol::{PrimitiveTypeSymbol, TypeSymbol};
|
use crate::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::symbol_table::SymbolTable;
|
use crate::symbol_table::SymbolTable;
|
||||||
use crate::type_info::TypeInfo;
|
use crate::type_info::TypeInfo;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct TypeUse {
|
pub struct TypeUse {
|
||||||
declared_name: String,
|
declared_name: String,
|
||||||
declared_name_source_range: SourceRange,
|
declared_name_source_range: SourceRange,
|
||||||
scope_id: Option<usize>,
|
scope_id: Option<usize>,
|
||||||
type_symbol: Option<TypeSymbol>,
|
type_info: Option<TypeInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeUse {
|
impl TypeUse {
|
||||||
@ -17,7 +19,7 @@ impl TypeUse {
|
|||||||
declared_name: declared_name.into(),
|
declared_name: declared_name.into(),
|
||||||
declared_name_source_range,
|
declared_name_source_range,
|
||||||
scope_id: None,
|
scope_id: None,
|
||||||
type_symbol: None,
|
type_info: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,16 +35,18 @@ impl TypeUse {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_name_usages(&mut self, symbol_table: &SymbolTable) -> Result<(), Vec<Diagnostic>> {
|
pub fn check_name_usages(
|
||||||
let maybe_type_symbol =
|
&mut self,
|
||||||
symbol_table.find_type_symbol(self.scope_id.unwrap(), &self.declared_name);
|
symbol_table: &SymbolTable,
|
||||||
if let Some(type_symbol) = maybe_type_symbol {
|
class_context: Option<&Rc<RefCell<ClassSymbol>>>,
|
||||||
self.type_symbol = Some(type_symbol);
|
) -> Result<(), Vec<Diagnostic>> {
|
||||||
Ok(())
|
if let Some(type_info) = TypeInfo::from_declared_name(
|
||||||
} else if let Some(primitive_type_symbol) =
|
&self.declared_name,
|
||||||
PrimitiveTypeSymbol::try_from_declared_name(self.declared_name())
|
self.scope_id.unwrap(),
|
||||||
{
|
symbol_table,
|
||||||
self.type_symbol = Some(TypeSymbol::Primitive(primitive_type_symbol));
|
class_context,
|
||||||
|
) {
|
||||||
|
self.type_info = Some(type_info);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(vec![
|
Err(vec![
|
||||||
@ -60,16 +64,7 @@ impl TypeUse {
|
|||||||
Ok(()) // no-op, for now
|
Ok(()) // no-op, for now
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_type_info(&self) -> TypeInfo {
|
pub fn type_info(&self) -> &TypeInfo {
|
||||||
match self.type_symbol.as_ref().unwrap() {
|
self.type_info.as_ref().unwrap()
|
||||||
TypeSymbol::Class(class_symbol) => TypeInfo::ClassInstance(class_symbol.clone()),
|
|
||||||
TypeSymbol::Primitive(primitive_type) => match primitive_type {
|
|
||||||
PrimitiveTypeSymbol::Any => TypeInfo::Any,
|
|
||||||
PrimitiveTypeSymbol::Int => TypeInfo::Integer,
|
|
||||||
PrimitiveTypeSymbol::Double => TypeInfo::Double,
|
|
||||||
PrimitiveTypeSymbol::String => TypeInfo::String,
|
|
||||||
PrimitiveTypeSymbol::Void => TypeInfo::Void,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -154,7 +154,7 @@ mod tests {
|
|||||||
.find(|f| f.declared_name() == "main")
|
.find(|f| f.declared_name() == "main")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut main_ir = main.to_ir(&symbol_table);
|
let mut main_ir = main.to_ir(&symbol_table, None);
|
||||||
let (register_assignments, _) = main_ir.assign_registers(2);
|
let (register_assignments, _) = main_ir.assign_registers(2);
|
||||||
assert_eq!(register_assignments.len(), 4);
|
assert_eq!(register_assignments.len(), 4);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,10 +3,7 @@ use crate::ir::assemble::{Assemble, InstructionsBuilder};
|
|||||||
use crate::ir::ir_expression::IrExpression;
|
use crate::ir::ir_expression::IrExpression;
|
||||||
use crate::ir::ir_variable::IrVrVariableDescriptor;
|
use crate::ir::ir_variable::IrVrVariableDescriptor;
|
||||||
use crate::ir::register_allocation::{OffsetCounter, VrUser};
|
use crate::ir::register_allocation::{OffsetCounter, VrUser};
|
||||||
use crate::symbol::Symbol;
|
|
||||||
use crate::symbol::function_symbol::FunctionSymbol;
|
|
||||||
use dvm_lib::instruction::Instruction;
|
use dvm_lib::instruction::Instruction;
|
||||||
use std::cell::RefCell;
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -14,19 +11,15 @@ use std::rc::Rc;
|
|||||||
pub struct IrCall {
|
pub struct IrCall {
|
||||||
function_name: Rc<str>,
|
function_name: Rc<str>,
|
||||||
arguments: Vec<IrExpression>,
|
arguments: Vec<IrExpression>,
|
||||||
function_symbol: Rc<RefCell<FunctionSymbol>>,
|
is_extern: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IrCall {
|
impl IrCall {
|
||||||
pub fn new(
|
pub fn new(function_name: Rc<str>, arguments: Vec<IrExpression>, is_extern: bool) -> Self {
|
||||||
function_name: Rc<str>,
|
|
||||||
arguments: Vec<IrExpression>,
|
|
||||||
function_symbol: Rc<RefCell<FunctionSymbol>>,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
function_name,
|
function_name,
|
||||||
arguments,
|
arguments,
|
||||||
function_symbol,
|
is_extern,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,16 +60,15 @@ impl Assemble for IrCall {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|ir_expression| ir_expression.push_operand(constants_table))
|
.map(|ir_expression| ir_expression.push_operand(constants_table))
|
||||||
.for_each(|push_operand| builder.push(Instruction::Push(push_operand)));
|
.for_each(|push_operand| builder.push(Instruction::Push(push_operand)));
|
||||||
let symbol = self.function_symbol.borrow();
|
if self.is_extern {
|
||||||
if symbol.is_extern() {
|
|
||||||
builder.push(Instruction::InvokePlatformStatic(
|
builder.push(Instruction::InvokePlatformStatic(
|
||||||
symbol.declared_name_owned(),
|
self.function_name.clone(),
|
||||||
symbol.parameters().len(),
|
self.arguments.len(),
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
builder.push(Instruction::InvokeStatic(
|
builder.push(Instruction::InvokeStatic(
|
||||||
symbol.declared_name_owned(),
|
self.function_name.clone(),
|
||||||
symbol.parameters().len(),
|
self.arguments.len(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
use crate::constants_table::ConstantsTable;
|
use crate::constants_table::ConstantsTable;
|
||||||
|
use crate::ir::assemble::InstructionsBuilder;
|
||||||
use crate::ir::ir_parameter::IrParameter;
|
use crate::ir::ir_parameter::IrParameter;
|
||||||
use crate::ir::ir_variable::{
|
use crate::ir::ir_variable::{
|
||||||
IrStackVariableDescriptor, IrVariable, IrVariableDescriptor, IrVrVariableDescriptor,
|
IrStackVariableDescriptor, IrVariable, IrVariableDescriptor, IrVrVariableDescriptor,
|
||||||
@ -179,7 +180,7 @@ impl IrExpression {
|
|||||||
|
|
||||||
pub fn return_operand(&self, constants_table: &mut ConstantsTable) -> ReturnOperand {
|
pub fn return_operand(&self, constants_table: &mut ConstantsTable) -> ReturnOperand {
|
||||||
match self {
|
match self {
|
||||||
IrExpression::Field(self_variable, _) => {
|
IrExpression::Field(self_variable, field_index) => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
IrExpression::Parameter(ir_parameter) => {
|
IrExpression::Parameter(ir_parameter) => {
|
||||||
|
|||||||
@ -53,9 +53,8 @@ impl VrUser for IrReturn {
|
|||||||
impl Assemble for IrReturn {
|
impl Assemble for IrReturn {
|
||||||
fn assemble(&self, builder: &mut InstructionsBuilder, constants_table: &mut ConstantsTable) {
|
fn assemble(&self, builder: &mut InstructionsBuilder, constants_table: &mut ConstantsTable) {
|
||||||
if let Some(ir_expression) = self.value.as_ref() {
|
if let Some(ir_expression) = self.value.as_ref() {
|
||||||
builder.push(Instruction::SetReturnValue(
|
let return_operand = ir_expression.return_operand(constants_table);
|
||||||
ir_expression.return_operand(constants_table),
|
builder.push(Instruction::SetReturnValue(return_operand));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
builder.push(Instruction::Return);
|
builder.push(Instruction::Return);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,10 +14,7 @@ impl CallableSymbol {
|
|||||||
pub fn return_type_info(&self) -> TypeInfo {
|
pub fn return_type_info(&self) -> TypeInfo {
|
||||||
match self {
|
match self {
|
||||||
CallableSymbol::Function(function) => function.borrow().return_type_info().clone(),
|
CallableSymbol::Function(function) => function.borrow().return_type_info().clone(),
|
||||||
CallableSymbol::Class(class_symbol) => {
|
CallableSymbol::Class(class_symbol) => TypeInfo::ClassInstance(class_symbol.clone()),
|
||||||
// At the language level, constructors "return" an instance of their type
|
|
||||||
TypeInfo::ClassInstance(class_symbol.clone())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
use crate::ast::ir_builder::IrBuilder;
|
||||||
use crate::ir::ir_expression::IrExpression;
|
use crate::ir::ir_expression::IrExpression;
|
||||||
use crate::symbol::class_symbol::ClassSymbol;
|
use crate::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::symbol::field_symbol::FieldSymbol;
|
use crate::symbol::field_symbol::FieldSymbol;
|
||||||
@ -33,16 +34,15 @@ impl ExpressibleSymbol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ir_expression(&self) -> IrExpression {
|
pub fn ir_expression(&self, builder: &mut IrBuilder) -> IrExpression {
|
||||||
match self {
|
match self {
|
||||||
ExpressibleSymbol::Class(class_symbol) => {
|
ExpressibleSymbol::Class(class_symbol) => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
ExpressibleSymbol::Field(field_symbol) => {
|
ExpressibleSymbol::Field(field_symbol) => IrExpression::Field(
|
||||||
// this, unfortunately, is going to need more context, because fields live longer
|
builder.self_variable().clone(),
|
||||||
// than function calls
|
field_symbol.borrow().field_index(),
|
||||||
todo!()
|
),
|
||||||
}
|
|
||||||
ExpressibleSymbol::Function(_) => {
|
ExpressibleSymbol::Function(_) => {
|
||||||
panic!("Cannot get ir_variable for FunctionSymbol");
|
panic!("Cannot get ir_variable for FunctionSymbol");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,26 +7,26 @@ use std::rc::Rc;
|
|||||||
pub struct ParameterSymbol {
|
pub struct ParameterSymbol {
|
||||||
declared_name: Rc<str>,
|
declared_name: Rc<str>,
|
||||||
declared_name_source_range: SourceRange,
|
declared_name_source_range: SourceRange,
|
||||||
type_info: TypeInfo,
|
type_info: Option<TypeInfo>,
|
||||||
ir_parameter: Option<Rc<IrParameter>>,
|
ir_parameter: Option<Rc<IrParameter>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ParameterSymbol {
|
impl ParameterSymbol {
|
||||||
pub fn new(
|
pub fn new(declared_name: &Rc<str>, declared_name_source_range: SourceRange) -> Self {
|
||||||
declared_name: &Rc<str>,
|
|
||||||
declared_name_source_range: SourceRange,
|
|
||||||
type_info: TypeInfo,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
declared_name: declared_name.clone(),
|
declared_name: declared_name.clone(),
|
||||||
declared_name_source_range,
|
declared_name_source_range,
|
||||||
type_info,
|
type_info: None,
|
||||||
ir_parameter: None,
|
ir_parameter: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_type_info(&mut self, type_info: TypeInfo) {
|
||||||
|
self.type_info = Some(type_info);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn type_info(&self) -> &TypeInfo {
|
pub fn type_info(&self) -> &TypeInfo {
|
||||||
&self.type_info
|
self.type_info.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_ir_parameter(&mut self, ir_parameter: Rc<IrParameter>) {
|
pub fn set_ir_parameter(&mut self, ir_parameter: Rc<IrParameter>) {
|
||||||
|
|||||||
@ -4,26 +4,4 @@ use std::rc::Rc;
|
|||||||
|
|
||||||
pub enum TypeSymbol {
|
pub enum TypeSymbol {
|
||||||
Class(Rc<RefCell<ClassSymbol>>),
|
Class(Rc<RefCell<ClassSymbol>>),
|
||||||
Primitive(PrimitiveTypeSymbol),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum PrimitiveTypeSymbol {
|
|
||||||
Any,
|
|
||||||
Int,
|
|
||||||
Double,
|
|
||||||
String,
|
|
||||||
Void,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PrimitiveTypeSymbol {
|
|
||||||
pub fn try_from_declared_name(declared_name: &str) -> Option<PrimitiveTypeSymbol> {
|
|
||||||
match declared_name {
|
|
||||||
"Any" => Some(PrimitiveTypeSymbol::Any),
|
|
||||||
"Int" => Some(PrimitiveTypeSymbol::Int),
|
|
||||||
"Double" => Some(PrimitiveTypeSymbol::Double),
|
|
||||||
"String" => Some(PrimitiveTypeSymbol::String),
|
|
||||||
"Void" => Some(PrimitiveTypeSymbol::Void),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
use crate::symbol::Symbol;
|
use crate::symbol::Symbol;
|
||||||
use crate::symbol::class_symbol::ClassSymbol;
|
use crate::symbol::class_symbol::ClassSymbol;
|
||||||
use crate::symbol::function_symbol::FunctionSymbol;
|
use crate::symbol::function_symbol::FunctionSymbol;
|
||||||
|
use crate::symbol::type_symbol::TypeSymbol;
|
||||||
|
use crate::symbol_table::SymbolTable;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -39,16 +41,25 @@ impl Display for TypeInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TypeInfo {
|
impl TypeInfo {
|
||||||
// This is very naive but works for now
|
pub fn from_declared_name(
|
||||||
#[deprecated]
|
declared_name: &str,
|
||||||
pub fn from_declared_name(declared_name: &str) -> Self {
|
scope_id: usize,
|
||||||
|
symbol_table: &SymbolTable,
|
||||||
|
class_context: Option<&Rc<RefCell<ClassSymbol>>>,
|
||||||
|
) -> Option<Self> {
|
||||||
match declared_name {
|
match declared_name {
|
||||||
"Any" => TypeInfo::Any,
|
"Any" => Some(TypeInfo::Any),
|
||||||
"Int" => TypeInfo::Integer,
|
"Int" => Some(TypeInfo::Integer),
|
||||||
"Double" => TypeInfo::Double,
|
"Double" => Some(TypeInfo::Double),
|
||||||
"String" => TypeInfo::String,
|
"String" => Some(TypeInfo::String),
|
||||||
"Void" => TypeInfo::Void,
|
"Void" => Some(TypeInfo::Void),
|
||||||
_ => panic!("Unknown type: {}", declared_name),
|
"Self" => Some(TypeInfo::ClassInstance(class_context.unwrap().clone())),
|
||||||
|
_ => match symbol_table.find_type_symbol(scope_id, declared_name) {
|
||||||
|
None => None,
|
||||||
|
Some(type_symbol) => match type_symbol {
|
||||||
|
TypeSymbol::Class(class_symbol) => Some(TypeInfo::ClassInstance(class_symbol)),
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user