Delete more old unused code.
This commit is contained in:
parent
e7145de68e
commit
dbbcda638f
@ -1,22 +1,18 @@
|
||||
use crate::ast::NodeId;
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::type_info::TypeInfo;
|
||||
|
||||
pub struct DoubleLiteral {
|
||||
node_id: NodeId,
|
||||
value: f64,
|
||||
source_range: SourceRange,
|
||||
type_info: &'static TypeInfo,
|
||||
}
|
||||
|
||||
impl DoubleLiteral {
|
||||
pub fn new(node_id: NodeId, value: f64, source_range: SourceRange) -> Self {
|
||||
const TYPE_INFO: TypeInfo = TypeInfo::Double;
|
||||
Self {
|
||||
node_id,
|
||||
value,
|
||||
source_range,
|
||||
type_info: &TYPE_INFO,
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,10 +24,6 @@ impl DoubleLiteral {
|
||||
self.value
|
||||
}
|
||||
|
||||
pub fn type_info(&self) -> &TypeInfo {
|
||||
&self.type_info
|
||||
}
|
||||
|
||||
pub fn source_range(&self) -> &SourceRange {
|
||||
&self.source_range
|
||||
}
|
||||
|
||||
@ -1,22 +1,18 @@
|
||||
use crate::ast::NodeId;
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::type_info::TypeInfo;
|
||||
|
||||
pub struct IntegerLiteral {
|
||||
node_id: NodeId,
|
||||
value: i32,
|
||||
source_range: SourceRange,
|
||||
type_info: &'static TypeInfo,
|
||||
}
|
||||
|
||||
impl IntegerLiteral {
|
||||
pub fn new(node_id: NodeId, value: i32, source_range: SourceRange) -> Self {
|
||||
const TYPE_INFO: TypeInfo = TypeInfo::Integer;
|
||||
Self {
|
||||
node_id,
|
||||
value,
|
||||
source_range,
|
||||
type_info: &TYPE_INFO,
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,10 +24,6 @@ impl IntegerLiteral {
|
||||
self.node_id
|
||||
}
|
||||
|
||||
pub fn type_info(&self) -> &TypeInfo {
|
||||
&self.type_info
|
||||
}
|
||||
|
||||
pub fn source_range(&self) -> &SourceRange {
|
||||
&self.source_range
|
||||
}
|
||||
|
||||
@ -1,22 +1,18 @@
|
||||
use crate::ast::NodeId;
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::type_info::TypeInfo;
|
||||
|
||||
pub struct StringLiteral {
|
||||
node_id: NodeId,
|
||||
content: String,
|
||||
source_range: SourceRange,
|
||||
type_info: &'static TypeInfo,
|
||||
}
|
||||
|
||||
impl StringLiteral {
|
||||
pub fn new(node_id: NodeId, content: &str, source_range: SourceRange) -> Self {
|
||||
const TYPE_INFO: TypeInfo = TypeInfo::String;
|
||||
Self {
|
||||
node_id,
|
||||
content: content.into(),
|
||||
source_range,
|
||||
type_info: &TYPE_INFO,
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,10 +24,6 @@ impl StringLiteral {
|
||||
&self.content
|
||||
}
|
||||
|
||||
pub fn type_info(&self) -> &TypeInfo {
|
||||
&self.type_info
|
||||
}
|
||||
|
||||
pub fn source_range(&self) -> &SourceRange {
|
||||
&self.source_range
|
||||
}
|
||||
|
||||
@ -1,15 +1,6 @@
|
||||
use crate::diagnostic::{Diagnostic, SecondaryLabel};
|
||||
use crate::error_codes::{
|
||||
ASSIGN_LHS_IMMUTABLE, ASSIGN_MISMATCHED_TYPES, ASSIGN_NO_L_VALUE,
|
||||
CANNOT_PROVIDE_GENERIC_ARGS_GENERIC_TYPE, CLASS_NO_CONSTRUCTOR, FIELD_NO_TYPE_OR_INIT,
|
||||
MISMATCHED_TYPES, NOT_ASSIGNABLE, OUTER_CLASS_FIELD_USED_IN_INIT,
|
||||
OUTER_CLASS_METHOD_USED_IN_INIT, RECEIVER_NOT_CALLABLE, SELF_CONSTRUCTOR_USED_IN_INIT,
|
||||
SELF_FIELD_USED_IN_INIT, SELF_METHOD_USED_IN_INIT, SYMBOL_ALREADY_DECLARED, SYMBOL_NOT_FOUND,
|
||||
UNARY_INCOMPATIBLE_TYPE, WRONG_NUMBER_OF_ARGUMENTS,
|
||||
};
|
||||
use crate::diagnostic::Diagnostic;
|
||||
use crate::error_codes::SYMBOL_NOT_FOUND;
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::type_info::TypeInfo;
|
||||
|
||||
pub fn symbol_not_found(name: &str, source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
@ -19,255 +10,3 @@ pub fn symbol_not_found(name: &str, source_range: &SourceRange) -> Diagnostic {
|
||||
)
|
||||
.with_error_code(SYMBOL_NOT_FOUND)
|
||||
}
|
||||
|
||||
pub fn field_has_no_type_or_init(name: &str, source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
&format!("Field {} has no declared type nor initializer.", name),
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(FIELD_NO_TYPE_OR_INIT)
|
||||
.with_primary_label_message("Declare a type and/or an initializer.")
|
||||
}
|
||||
|
||||
pub fn cannot_reference_field_in_init(name: &str, source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
&format!("Cannot reference field {} during initialization.", name),
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(SELF_FIELD_USED_IN_INIT)
|
||||
}
|
||||
|
||||
pub fn symbol_already_declared(already_inserted: &Symbol, would_insert: &Symbol) -> Diagnostic {
|
||||
let secondary_label = if let Some(source_range) = already_inserted.declared_name_source_range()
|
||||
{
|
||||
Some(SecondaryLabel::new(
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
Some("Symbol already declared here.".to_string()),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let diagnostic = Diagnostic::new(
|
||||
&format!(
|
||||
"Symbol {} already declared in current scope.",
|
||||
would_insert.declared_name()
|
||||
),
|
||||
would_insert.declared_name_source_range().unwrap().start(), // unwrap should be okay, since this is user code
|
||||
would_insert.declared_name_source_range().unwrap().end(),
|
||||
)
|
||||
.with_error_code(SYMBOL_ALREADY_DECLARED);
|
||||
|
||||
if let Some(secondary_label) = secondary_label {
|
||||
diagnostic.with_secondary_labels(&[secondary_label])
|
||||
} else {
|
||||
diagnostic
|
||||
}
|
||||
}
|
||||
|
||||
pub fn self_constructor_used_in_init(source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
"Cannot call Self constructor during initialization.",
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(SELF_CONSTRUCTOR_USED_IN_INIT)
|
||||
}
|
||||
|
||||
pub fn self_field_used_in_init(source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
"Cannot reference Self field during initialization.",
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(SELF_FIELD_USED_IN_INIT)
|
||||
}
|
||||
|
||||
pub fn self_method_used_in_init(source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
"Cannot call Self method during initialization.",
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(SELF_METHOD_USED_IN_INIT)
|
||||
}
|
||||
|
||||
pub fn outer_class_field_usage(source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
"Cannot reference an outer class member.",
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(OUTER_CLASS_FIELD_USED_IN_INIT)
|
||||
}
|
||||
|
||||
pub fn outer_class_method_usage(source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
"Cannot call an outer class method.",
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(OUTER_CLASS_METHOD_USED_IN_INIT)
|
||||
}
|
||||
|
||||
pub fn class_has_no_constructor(name: &str, source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
&format!("Class {} has no constructor.", name),
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(CLASS_NO_CONSTRUCTOR)
|
||||
}
|
||||
|
||||
pub fn not_assignable(name: &str, source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
&format!("Symbol {} is not assignable.", name),
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(NOT_ASSIGNABLE)
|
||||
}
|
||||
|
||||
pub fn cannot_reassign_immutable_field(source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
"Cannot reassign an immutable field.",
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(ASSIGN_LHS_IMMUTABLE)
|
||||
}
|
||||
|
||||
pub fn cannot_provide_generic_args_generic_type(source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
"Cannot provide generic arguments to an already generic type.",
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(CANNOT_PROVIDE_GENERIC_ARGS_GENERIC_TYPE)
|
||||
}
|
||||
|
||||
pub fn must_be_l_value(source_range: &SourceRange) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
"Left-hand side of assign mut be an L value",
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(ASSIGN_NO_L_VALUE)
|
||||
}
|
||||
|
||||
pub fn destination_must_be_mutable(
|
||||
source_range: &SourceRange,
|
||||
secondary_source_range: Option<&SourceRange>,
|
||||
) -> Diagnostic {
|
||||
let secondary_label = secondary_source_range.map(|sr| {
|
||||
SecondaryLabel::new(
|
||||
sr.start(),
|
||||
sr.end(),
|
||||
Some("Destination declared here is immutable".to_string()),
|
||||
)
|
||||
});
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
"Destination is immutable and cannot be reassigned.",
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(ASSIGN_LHS_IMMUTABLE);
|
||||
|
||||
if let Some(secondary_label) = secondary_label {
|
||||
diagnostic = diagnostic.with_secondary_labels(&[secondary_label])
|
||||
}
|
||||
|
||||
diagnostic
|
||||
}
|
||||
|
||||
pub fn mismatched_assign_types(
|
||||
rhs_type: &TypeInfo,
|
||||
lhs_type: &TypeInfo,
|
||||
source_range: &SourceRange,
|
||||
secondary_source_range: Option<&SourceRange>,
|
||||
) -> Diagnostic {
|
||||
let secondary_label = secondary_source_range.map(|sr| {
|
||||
SecondaryLabel::new(
|
||||
sr.start(),
|
||||
sr.end(),
|
||||
Some(format!(
|
||||
"Destination declared here is of type {}.",
|
||||
lhs_type
|
||||
)),
|
||||
)
|
||||
});
|
||||
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
&format!("Mismatched types: right-hand side of type {} is not assignable to left-hand side of type {}", rhs_type, lhs_type),
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(ASSIGN_MISMATCHED_TYPES);
|
||||
|
||||
if let Some(secondary_label) = secondary_label {
|
||||
diagnostic = diagnostic.with_secondary_labels(&[secondary_label])
|
||||
}
|
||||
|
||||
diagnostic
|
||||
}
|
||||
|
||||
pub fn receiver_not_callable(
|
||||
receiver_type_info: &TypeInfo,
|
||||
source_range: &SourceRange,
|
||||
) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
&format!("Receiver of type {} is not callable.", receiver_type_info),
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(RECEIVER_NOT_CALLABLE)
|
||||
}
|
||||
|
||||
pub fn wrong_number_of_arguments(
|
||||
source_range: &SourceRange,
|
||||
found: usize,
|
||||
expected: usize,
|
||||
) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
&format!(
|
||||
"Wrong number of arguments: expected {} but found {}",
|
||||
expected, found
|
||||
),
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(WRONG_NUMBER_OF_ARGUMENTS)
|
||||
}
|
||||
|
||||
pub fn mismatched_types(
|
||||
expected_type_info: &TypeInfo,
|
||||
found_type_info: &TypeInfo,
|
||||
source_range: &SourceRange,
|
||||
) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
&format!(
|
||||
"Mismatched types; expected {} but found {}",
|
||||
expected_type_info, found_type_info
|
||||
),
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(MISMATCHED_TYPES)
|
||||
}
|
||||
|
||||
pub fn unary_incompatible_type(
|
||||
source_range: &SourceRange,
|
||||
operator_name: &str,
|
||||
type_info: &TypeInfo,
|
||||
) -> Diagnostic {
|
||||
Diagnostic::new(
|
||||
&format!("Cannot apply {} to {}", operator_name, type_info),
|
||||
source_range.start(),
|
||||
source_range.end(),
|
||||
)
|
||||
.with_error_code(UNARY_INCOMPATIBLE_TYPE)
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
#[inline]
|
||||
pub fn fqn_parts_to_string(parts: &[Rc<str>]) -> Rc<str> {
|
||||
parts.join("::").into()
|
||||
}
|
||||
@ -1,48 +0,0 @@
|
||||
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"),
|
||||
create_simple_primitive("Void"),
|
||||
create_simple_primitive("Any"),
|
||||
];
|
||||
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", "Void", "Any"];
|
||||
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,
|
||||
"Void" => TypeInfo::Void,
|
||||
"Any" => TypeInfo::Any,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
types_table.class_types_mut().insert(symbol, type_info);
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,3 @@
|
||||
use crate::fqn_util::fqn_parts_to_string;
|
||||
use crate::type_info::TypeInfo;
|
||||
use dvm_lib::vm::class::{Class, Field};
|
||||
use dvm_lib::vm::type_info::TypeInfo as VmTypeInfo;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct IrClass {
|
||||
@ -18,45 +14,18 @@ impl IrClass {
|
||||
fields,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_vm_class(&self) -> Class {
|
||||
Class::new(
|
||||
self.declared_name.clone(),
|
||||
self.fqn.clone(),
|
||||
self.fields.iter().map(IrField::to_vm_field).collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IrField {
|
||||
debug_name: Rc<str>,
|
||||
field_index: usize,
|
||||
type_info: TypeInfo,
|
||||
}
|
||||
|
||||
impl IrField {
|
||||
pub fn new(debug_name: Rc<str>, field_index: usize, type_info: TypeInfo) -> Self {
|
||||
pub fn new(debug_name: Rc<str>, field_index: usize) -> Self {
|
||||
Self {
|
||||
debug_name,
|
||||
field_index,
|
||||
type_info,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_vm_field(&self) -> Field {
|
||||
Field::new(
|
||||
self.debug_name.clone(),
|
||||
self.field_index,
|
||||
match &self.type_info {
|
||||
TypeInfo::Integer => VmTypeInfo::Int,
|
||||
TypeInfo::Double => VmTypeInfo::Double,
|
||||
TypeInfo::String => VmTypeInfo::String,
|
||||
TypeInfo::Class(class_symbol) => {
|
||||
VmTypeInfo::ClassInstance(fqn_parts_to_string(class_symbol.fqn_parts()).into())
|
||||
}
|
||||
TypeInfo::GenericType(_) => VmTypeInfo::Any,
|
||||
_ => panic!(),
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,23 +17,14 @@ pub mod ast;
|
||||
pub mod constants_table;
|
||||
pub mod diagnostic;
|
||||
mod diagnostic_factories;
|
||||
pub mod error_codes;
|
||||
pub mod fqn_util;
|
||||
pub mod intrinsics;
|
||||
mod error_codes;
|
||||
pub mod ir;
|
||||
pub mod lexer;
|
||||
pub mod lowering;
|
||||
pub mod offset_counter;
|
||||
pub mod parser;
|
||||
pub mod scope;
|
||||
pub mod semantic_analysis;
|
||||
pub mod source_range;
|
||||
pub mod symbol;
|
||||
pub mod symbol_table;
|
||||
pub mod token;
|
||||
pub mod type_info;
|
||||
pub mod types_table;
|
||||
mod util;
|
||||
|
||||
pub type Filename = Rc<str>;
|
||||
pub type FileId = usize;
|
||||
|
||||
@ -1,23 +0,0 @@
|
||||
pub struct OffsetCounter {
|
||||
counter: usize,
|
||||
}
|
||||
|
||||
impl OffsetCounter {
|
||||
pub fn new() -> Self {
|
||||
Self { counter: 0 }
|
||||
}
|
||||
|
||||
pub fn with_base(base: usize) -> Self {
|
||||
Self { counter: base }
|
||||
}
|
||||
|
||||
pub fn next(&mut self) -> usize {
|
||||
let offset = self.counter;
|
||||
self.counter += 1;
|
||||
offset
|
||||
}
|
||||
|
||||
pub fn get_count(&self) -> usize {
|
||||
self.counter
|
||||
}
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
use crate::symbol::variable_symbol::VariableSymbol;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct BlockScope {
|
||||
debug_name: String,
|
||||
parent_id: usize,
|
||||
variable_symbols: HashMap<Rc<str>, Rc<VariableSymbol>>,
|
||||
}
|
||||
|
||||
impl BlockScope {
|
||||
pub fn new(debug_name: &str, parent_id: usize) -> Self {
|
||||
Self {
|
||||
debug_name: debug_name.into(),
|
||||
parent_id,
|
||||
variable_symbols: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn variable_symbols(&self) -> &HashMap<Rc<str>, Rc<VariableSymbol>> {
|
||||
&self.variable_symbols
|
||||
}
|
||||
|
||||
pub fn variable_symbols_mut(&mut self) -> &mut HashMap<Rc<str>, Rc<VariableSymbol>> {
|
||||
&mut self.variable_symbols
|
||||
}
|
||||
|
||||
pub fn parent_id(&self) -> usize {
|
||||
self.parent_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for BlockScope {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "BlockScope({}, {})", self.debug_name, self.parent_id)
|
||||
}
|
||||
}
|
||||
@ -1,71 +0,0 @@
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol::constructor_symbol::ConstructorSymbol;
|
||||
use crate::symbol::field_symbol::FieldSymbol;
|
||||
use crate::symbol::function_symbol::FunctionSymbol;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct ClassBodyScope {
|
||||
debug_name: String,
|
||||
parent_id: usize,
|
||||
class_symbols: HashMap<Rc<str>, Rc<ClassSymbol>>,
|
||||
field_symbols: HashMap<Rc<str>, Rc<FieldSymbol>>,
|
||||
function_symbols: HashMap<Rc<str>, Rc<FunctionSymbol>>,
|
||||
constructor_symbol: Option<Rc<ConstructorSymbol>>,
|
||||
}
|
||||
|
||||
impl ClassBodyScope {
|
||||
pub fn new(debug_name: &str, parent_id: usize) -> Self {
|
||||
Self {
|
||||
debug_name: debug_name.into(),
|
||||
parent_id,
|
||||
class_symbols: HashMap::new(),
|
||||
field_symbols: HashMap::new(),
|
||||
function_symbols: HashMap::new(),
|
||||
constructor_symbol: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn class_symbols(&self) -> &HashMap<Rc<str>, Rc<ClassSymbol>> {
|
||||
&self.class_symbols
|
||||
}
|
||||
|
||||
pub fn class_symbols_mut(&mut self) -> &mut HashMap<Rc<str>, Rc<ClassSymbol>> {
|
||||
&mut self.class_symbols
|
||||
}
|
||||
|
||||
pub fn field_symbols(&self) -> &HashMap<Rc<str>, Rc<FieldSymbol>> {
|
||||
&self.field_symbols
|
||||
}
|
||||
|
||||
pub fn field_symbols_mut(&mut self) -> &mut HashMap<Rc<str>, Rc<FieldSymbol>> {
|
||||
&mut self.field_symbols
|
||||
}
|
||||
|
||||
pub fn function_symbols(&self) -> &HashMap<Rc<str>, Rc<FunctionSymbol>> {
|
||||
&self.function_symbols
|
||||
}
|
||||
|
||||
pub fn function_symbols_mut(&mut self) -> &mut HashMap<Rc<str>, Rc<FunctionSymbol>> {
|
||||
&mut self.function_symbols
|
||||
}
|
||||
|
||||
pub fn constructor_symbol(&self) -> Option<&Rc<ConstructorSymbol>> {
|
||||
self.constructor_symbol.as_ref()
|
||||
}
|
||||
|
||||
pub fn constructor_symbol_mut(&mut self) -> &mut Option<Rc<ConstructorSymbol>> {
|
||||
&mut self.constructor_symbol
|
||||
}
|
||||
|
||||
pub fn parent_id(&self) -> usize {
|
||||
self.parent_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for ClassBodyScope {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "ClassBodyScope({}, {})", self.debug_name, self.parent_id)
|
||||
}
|
||||
}
|
||||
@ -1,40 +0,0 @@
|
||||
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct ClassScope {
|
||||
debug_name: String,
|
||||
parent_id: usize,
|
||||
generic_parameter_symbols: HashMap<Rc<str>, Rc<GenericParameterSymbol>>,
|
||||
}
|
||||
|
||||
impl ClassScope {
|
||||
pub fn new(debug_name: &str, parent_id: usize) -> Self {
|
||||
Self {
|
||||
debug_name: debug_name.into(),
|
||||
parent_id,
|
||||
generic_parameter_symbols: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parent_id(&self) -> usize {
|
||||
self.parent_id
|
||||
}
|
||||
|
||||
pub fn generic_parameter_symbols(&self) -> &HashMap<Rc<str>, Rc<GenericParameterSymbol>> {
|
||||
&self.generic_parameter_symbols
|
||||
}
|
||||
|
||||
pub fn generic_parameter_symbols_mut(
|
||||
&mut self,
|
||||
) -> &mut HashMap<Rc<str>, Rc<GenericParameterSymbol>> {
|
||||
&mut self.generic_parameter_symbols
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for ClassScope {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "ClassScope({}, {})", self.debug_name, self.parent_id)
|
||||
}
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct FunctionScope {
|
||||
debug_name: String,
|
||||
parent_id: usize,
|
||||
parameter_symbols: HashMap<Rc<str>, Rc<ParameterSymbol>>,
|
||||
}
|
||||
|
||||
impl FunctionScope {
|
||||
pub fn new(debug_name: &str, parent_id: usize) -> Self {
|
||||
Self {
|
||||
debug_name: debug_name.into(),
|
||||
parent_id,
|
||||
parameter_symbols: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parameter_symbols(&self) -> &HashMap<Rc<str>, Rc<ParameterSymbol>> {
|
||||
&self.parameter_symbols
|
||||
}
|
||||
|
||||
pub fn parameter_symbols_mut(&mut self) -> &mut HashMap<Rc<str>, Rc<ParameterSymbol>> {
|
||||
&mut self.parameter_symbols
|
||||
}
|
||||
|
||||
pub fn parent_id(&self) -> usize {
|
||||
self.parent_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for FunctionScope {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "FunctionScope({}, {})", self.debug_name, self.parent_id)
|
||||
}
|
||||
}
|
||||
@ -1,54 +0,0 @@
|
||||
use crate::scope::block_scope::BlockScope;
|
||||
use crate::scope::class_body_scope::ClassBodyScope;
|
||||
use crate::scope::class_scope::ClassScope;
|
||||
use crate::scope::function_scope::FunctionScope;
|
||||
use crate::scope::module_scope::ModuleScope;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
|
||||
pub mod block_scope;
|
||||
pub mod class_body_scope;
|
||||
pub mod class_scope;
|
||||
pub mod function_scope;
|
||||
pub mod module_scope;
|
||||
|
||||
pub enum Scope {
|
||||
Module(ModuleScope),
|
||||
Class(ClassScope),
|
||||
ClassBody(ClassBodyScope),
|
||||
Function(FunctionScope),
|
||||
Block(BlockScope),
|
||||
}
|
||||
|
||||
impl Scope {
|
||||
pub fn parent_id(&self) -> Option<usize> {
|
||||
match self {
|
||||
Scope::Module(module_scope) => module_scope.parent_id(),
|
||||
Scope::Class(class_scope) => Some(class_scope.parent_id()),
|
||||
Scope::ClassBody(class_body_scope) => Some(class_body_scope.parent_id()),
|
||||
Scope::Function(function_scope) => Some(function_scope.parent_id()),
|
||||
Scope::Block(block_scope) => Some(block_scope.parent_id()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for Scope {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Scope::Module(module_scope) => {
|
||||
write!(f, "{:?}", module_scope)
|
||||
}
|
||||
Scope::Class(class_scope) => {
|
||||
write!(f, "{:?}", class_scope)
|
||||
}
|
||||
Scope::ClassBody(class_body_scope) => {
|
||||
write!(f, "{:?}", class_body_scope)
|
||||
}
|
||||
Scope::Function(function_scope) => {
|
||||
write!(f, "{:?}", function_scope)
|
||||
}
|
||||
Scope::Block(block_scope) => {
|
||||
write!(f, "{:?}", block_scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,49 +0,0 @@
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol::function_symbol::FunctionSymbol;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct ModuleScope {
|
||||
debug_name: String,
|
||||
parent_id: Option<usize>,
|
||||
class_symbols: HashMap<Rc<str>, Rc<ClassSymbol>>,
|
||||
function_symbols: HashMap<Rc<str>, Rc<FunctionSymbol>>,
|
||||
}
|
||||
|
||||
impl ModuleScope {
|
||||
pub fn new(debug_name: &str, parent_id: Option<usize>) -> Self {
|
||||
Self {
|
||||
debug_name: debug_name.into(),
|
||||
parent_id,
|
||||
class_symbols: HashMap::new(),
|
||||
function_symbols: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn class_symbols(&self) -> &HashMap<Rc<str>, Rc<ClassSymbol>> {
|
||||
&self.class_symbols
|
||||
}
|
||||
|
||||
pub fn class_symbols_mut(&mut self) -> &mut HashMap<Rc<str>, Rc<ClassSymbol>> {
|
||||
&mut self.class_symbols
|
||||
}
|
||||
|
||||
pub fn function_symbols(&self) -> &HashMap<Rc<str>, Rc<FunctionSymbol>> {
|
||||
&self.function_symbols
|
||||
}
|
||||
|
||||
pub fn function_symbols_mut(&mut self) -> &mut HashMap<Rc<str>, Rc<FunctionSymbol>> {
|
||||
&mut self.function_symbols
|
||||
}
|
||||
|
||||
pub fn parent_id(&self) -> Option<usize> {
|
||||
self.parent_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for ModuleScope {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "ModuleScope({}, {:?})", self.debug_name, self.parent_id)
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
use crate::symbol::constructor_symbol::ConstructorSymbol;
|
||||
use crate::symbol::function_symbol::FunctionSymbol;
|
||||
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub enum CallableSymbol {
|
||||
Function(Rc<FunctionSymbol>),
|
||||
Constructor(Rc<ConstructorSymbol>),
|
||||
ErrorPlaceholder,
|
||||
}
|
||||
|
||||
impl CallableSymbol {
|
||||
pub fn parameters(&self) -> Vec<Rc<ParameterSymbol>> {
|
||||
match self {
|
||||
CallableSymbol::Function(function_symbol) => function_symbol.parameters().to_vec(),
|
||||
CallableSymbol::Constructor(constructor_symbol) => {
|
||||
constructor_symbol.parameters().to_vec()
|
||||
}
|
||||
CallableSymbol::ErrorPlaceholder => Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,115 +0,0 @@
|
||||
use crate::fqn_util::fqn_parts_to_string;
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::symbol::constructor_symbol::ConstructorSymbol;
|
||||
use crate::symbol::field_symbol::FieldSymbol;
|
||||
use crate::symbol::function_symbol::FunctionSymbol;
|
||||
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct ClassSymbol {
|
||||
declared_name: Rc<str>,
|
||||
declared_name_source_range: Option<SourceRange>,
|
||||
fqn_parts: Vec<Rc<str>>,
|
||||
is_extern: bool,
|
||||
scope_id: usize,
|
||||
generic_parameters: Vec<Rc<GenericParameterSymbol>>,
|
||||
constructor_symbol: Option<Rc<ConstructorSymbol>>,
|
||||
fields: HashMap<Rc<str>, Rc<FieldSymbol>>,
|
||||
functions: HashMap<Rc<str>, Rc<FunctionSymbol>>,
|
||||
}
|
||||
|
||||
impl ClassSymbol {
|
||||
pub fn new(
|
||||
declared_name: &Rc<str>,
|
||||
declared_name_source_range: Option<SourceRange>,
|
||||
fqn_parts: Vec<Rc<str>>,
|
||||
is_extern: bool,
|
||||
scope_id: usize,
|
||||
generic_parameters: Vec<Rc<GenericParameterSymbol>>,
|
||||
constructor_symbol: Option<Rc<ConstructorSymbol>>,
|
||||
fields: Vec<Rc<FieldSymbol>>,
|
||||
functions: Vec<Rc<FunctionSymbol>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
declared_name: declared_name.clone(),
|
||||
declared_name_source_range,
|
||||
fqn_parts,
|
||||
is_extern,
|
||||
scope_id,
|
||||
generic_parameters,
|
||||
constructor_symbol,
|
||||
fields: fields
|
||||
.into_iter()
|
||||
.map(|fs| (fs.declared_name_owned(), fs))
|
||||
.collect(),
|
||||
functions: functions
|
||||
.into_iter()
|
||||
.map(|fs| (fs.declared_name_owned(), fs))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_name(&self) -> &str {
|
||||
&self.declared_name
|
||||
}
|
||||
|
||||
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||
self.declared_name.clone()
|
||||
}
|
||||
|
||||
pub fn declared_name_source_range(&self) -> Option<&SourceRange> {
|
||||
self.declared_name_source_range.as_ref()
|
||||
}
|
||||
|
||||
pub fn fqn_parts(&self) -> &[Rc<str>] {
|
||||
&self.fqn_parts
|
||||
}
|
||||
|
||||
pub fn scope_id(&self) -> usize {
|
||||
self.scope_id
|
||||
}
|
||||
|
||||
pub fn generic_parameters(&self) -> &[Rc<GenericParameterSymbol>] {
|
||||
&self.generic_parameters
|
||||
}
|
||||
|
||||
pub fn constructor_symbol(&self) -> Option<&ConstructorSymbol> {
|
||||
self.constructor_symbol.as_ref().map(|s| s.as_ref())
|
||||
}
|
||||
|
||||
pub fn constructor_symbol_owned(&self) -> Option<Rc<ConstructorSymbol>> {
|
||||
self.constructor_symbol.as_ref().cloned()
|
||||
}
|
||||
|
||||
pub fn fields(&self) -> &HashMap<Rc<str>, Rc<FieldSymbol>> {
|
||||
&self.fields
|
||||
}
|
||||
|
||||
pub fn functions(&self) -> &HashMap<Rc<str>, Rc<FunctionSymbol>> {
|
||||
&self.functions
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for ClassSymbol {}
|
||||
|
||||
impl PartialEq for ClassSymbol {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.declared_name == other.declared_name && self.scope_id == other.scope_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for ClassSymbol {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.declared_name.hash(state);
|
||||
self.scope_id.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for ClassSymbol {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "ClassSymbol({})", fqn_parts_to_string(&self.fqn_parts))
|
||||
}
|
||||
}
|
||||
@ -1,75 +0,0 @@
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct ConstructorSymbol {
|
||||
keyword_source_range: SourceRange,
|
||||
fqn_parts: Vec<Rc<str>>,
|
||||
is_extern: bool,
|
||||
is_default: bool,
|
||||
scope_id: usize,
|
||||
parameters: Vec<Rc<ParameterSymbol>>,
|
||||
}
|
||||
|
||||
impl ConstructorSymbol {
|
||||
pub fn new(
|
||||
keyword_source_range: &SourceRange,
|
||||
fqn_parts: Vec<Rc<str>>,
|
||||
is_extern: bool,
|
||||
is_default: bool,
|
||||
scope_id: usize,
|
||||
parameters: Vec<Rc<ParameterSymbol>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
keyword_source_range: keyword_source_range.clone(),
|
||||
fqn_parts,
|
||||
is_extern,
|
||||
is_default,
|
||||
scope_id,
|
||||
parameters,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_name(&self) -> &str {
|
||||
"ctor"
|
||||
}
|
||||
|
||||
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||
Rc::from(self.declared_name())
|
||||
}
|
||||
|
||||
pub fn declared_name_source_range(&self) -> &SourceRange {
|
||||
&self.keyword_source_range
|
||||
}
|
||||
|
||||
pub fn fqn_parts(&self) -> &[Rc<str>] {
|
||||
&self.fqn_parts
|
||||
}
|
||||
|
||||
pub fn scope_id(&self) -> usize {
|
||||
self.scope_id
|
||||
}
|
||||
|
||||
pub fn parameters(&self) -> &[Rc<ParameterSymbol>] {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
pub fn is_extern(&self) -> bool {
|
||||
self.is_extern
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for ConstructorSymbol {}
|
||||
|
||||
impl PartialEq for ConstructorSymbol {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.scope_id == other.scope_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for ConstructorSymbol {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.scope_id.hash(state);
|
||||
}
|
||||
}
|
||||
@ -1,46 +0,0 @@
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol::field_symbol::FieldSymbol;
|
||||
use crate::symbol::function_symbol::FunctionSymbol;
|
||||
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||
use crate::symbol::variable_symbol::VariableSymbol;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub enum ExpressibleSymbol {
|
||||
Class(Rc<ClassSymbol>),
|
||||
Field(Rc<FieldSymbol>),
|
||||
Function(Rc<FunctionSymbol>),
|
||||
Parameter(Rc<ParameterSymbol>),
|
||||
Variable(Rc<VariableSymbol>),
|
||||
}
|
||||
|
||||
impl ExpressibleSymbol {
|
||||
pub fn into_symbol(self) -> Symbol {
|
||||
match self {
|
||||
ExpressibleSymbol::Class(class_symbol) => Symbol::Class(class_symbol),
|
||||
ExpressibleSymbol::Field(field_symbol) => Symbol::Field(field_symbol),
|
||||
ExpressibleSymbol::Function(function_symbol) => Symbol::Function(function_symbol),
|
||||
ExpressibleSymbol::Parameter(parameter_symbol) => Symbol::Parameter(parameter_symbol),
|
||||
ExpressibleSymbol::Variable(variable_symbol) => Symbol::Variable(variable_symbol),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn source_range(&self) -> Option<&SourceRange> {
|
||||
match self {
|
||||
ExpressibleSymbol::Class(class_symbol) => class_symbol.declared_name_source_range(),
|
||||
ExpressibleSymbol::Field(field_symbol) => {
|
||||
Some(field_symbol.declared_name_source_range())
|
||||
}
|
||||
ExpressibleSymbol::Function(function_symbol) => {
|
||||
Some(function_symbol.declared_name_source_range())
|
||||
}
|
||||
ExpressibleSymbol::Parameter(parameter_symbol) => {
|
||||
parameter_symbol.declared_name_source_range()
|
||||
}
|
||||
ExpressibleSymbol::Variable(variable_symbol) => {
|
||||
Some(variable_symbol.declared_name_source_range())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,68 +0,0 @@
|
||||
use crate::source_range::SourceRange;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct FieldSymbol {
|
||||
declared_name: Rc<str>,
|
||||
declared_name_source_range: SourceRange,
|
||||
is_mut: bool,
|
||||
scope_id: usize,
|
||||
field_index: usize,
|
||||
}
|
||||
|
||||
impl FieldSymbol {
|
||||
pub fn new(
|
||||
declared_name: &Rc<str>,
|
||||
declared_name_source_range: SourceRange,
|
||||
is_mut: bool,
|
||||
scope_id: usize,
|
||||
field_index: usize,
|
||||
) -> Self {
|
||||
Self {
|
||||
declared_name: declared_name.clone(),
|
||||
declared_name_source_range,
|
||||
is_mut,
|
||||
scope_id,
|
||||
field_index,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_name(&self) -> &str {
|
||||
&self.declared_name
|
||||
}
|
||||
|
||||
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||
self.declared_name.clone()
|
||||
}
|
||||
|
||||
pub fn declared_name_source_range(&self) -> &SourceRange {
|
||||
&self.declared_name_source_range
|
||||
}
|
||||
|
||||
pub fn scope_id(&self) -> usize {
|
||||
self.scope_id
|
||||
}
|
||||
|
||||
pub fn is_mut(&self) -> bool {
|
||||
self.is_mut
|
||||
}
|
||||
|
||||
pub fn field_index(&self) -> usize {
|
||||
self.field_index
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for FieldSymbol {}
|
||||
|
||||
impl PartialEq for FieldSymbol {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.declared_name == other.declared_name && self.scope_id == other.scope_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for FieldSymbol {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.declared_name.hash(state);
|
||||
self.scope_id.hash(state);
|
||||
}
|
||||
}
|
||||
@ -1,94 +0,0 @@
|
||||
use crate::fqn_util::fqn_parts_to_string;
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::hash::Hash;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct FunctionSymbol {
|
||||
declared_name: Rc<str>,
|
||||
declared_name_source_range: SourceRange,
|
||||
fqn_parts: Vec<Rc<str>>,
|
||||
is_extern: bool,
|
||||
is_method: bool,
|
||||
scope_id: usize,
|
||||
parameters: Vec<Rc<ParameterSymbol>>,
|
||||
}
|
||||
|
||||
impl FunctionSymbol {
|
||||
pub fn new(
|
||||
declared_name: &Rc<str>,
|
||||
declared_name_source_range: SourceRange,
|
||||
fqn_parts: Vec<Rc<str>>,
|
||||
is_extern: bool,
|
||||
is_method: bool,
|
||||
scope_id: usize,
|
||||
parameters: Vec<Rc<ParameterSymbol>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
declared_name: declared_name.clone(),
|
||||
declared_name_source_range,
|
||||
fqn_parts,
|
||||
is_extern,
|
||||
is_method,
|
||||
scope_id,
|
||||
parameters,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_name(&self) -> &str {
|
||||
&self.declared_name
|
||||
}
|
||||
|
||||
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||
self.declared_name.clone()
|
||||
}
|
||||
|
||||
pub fn declared_name_source_range(&self) -> &SourceRange {
|
||||
&self.declared_name_source_range
|
||||
}
|
||||
|
||||
pub fn fqn_parts(&self) -> &[Rc<str>] {
|
||||
&self.fqn_parts
|
||||
}
|
||||
|
||||
pub fn is_method(&self) -> bool {
|
||||
self.is_method
|
||||
}
|
||||
|
||||
pub fn scope_id(&self) -> usize {
|
||||
self.scope_id
|
||||
}
|
||||
pub fn parameters(&self) -> &[Rc<ParameterSymbol>] {
|
||||
&self.parameters
|
||||
}
|
||||
|
||||
pub fn is_extern(&self) -> bool {
|
||||
self.is_extern
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for FunctionSymbol {}
|
||||
|
||||
impl PartialEq for FunctionSymbol {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.declared_name == other.declared_name && self.scope_id == other.scope_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for FunctionSymbol {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.declared_name.hash(state);
|
||||
self.scope_id.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for FunctionSymbol {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"FunctionSymbol({})",
|
||||
fqn_parts_to_string(&self.fqn_parts)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1,54 +0,0 @@
|
||||
use crate::source_range::SourceRange;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct GenericParameterSymbol {
|
||||
declared_name: Rc<str>,
|
||||
declared_name_source_range: SourceRange,
|
||||
scope_id: usize,
|
||||
}
|
||||
|
||||
impl GenericParameterSymbol {
|
||||
pub fn new(
|
||||
declared_name: &Rc<str>,
|
||||
declared_name_source_range: &SourceRange,
|
||||
scope_id: usize,
|
||||
) -> Self {
|
||||
Self {
|
||||
declared_name: declared_name.clone(),
|
||||
declared_name_source_range: declared_name_source_range.clone(),
|
||||
scope_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_name(&self) -> &str {
|
||||
&self.declared_name
|
||||
}
|
||||
|
||||
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||
self.declared_name.clone()
|
||||
}
|
||||
|
||||
pub fn declared_name_source_range(&self) -> &SourceRange {
|
||||
&self.declared_name_source_range
|
||||
}
|
||||
|
||||
pub fn scope_id(&self) -> usize {
|
||||
self.scope_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for GenericParameterSymbol {}
|
||||
|
||||
impl PartialEq for GenericParameterSymbol {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.declared_name == other.declared_name && self.scope_id == other.scope_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for GenericParameterSymbol {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.declared_name.hash(state);
|
||||
self.scope_id.hash(state);
|
||||
}
|
||||
}
|
||||
@ -1,148 +0,0 @@
|
||||
use crate::source_range::SourceRange;
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol::constructor_symbol::ConstructorSymbol;
|
||||
use crate::symbol::expressible_symbol::ExpressibleSymbol;
|
||||
use crate::symbol::field_symbol::FieldSymbol;
|
||||
use crate::symbol::function_symbol::FunctionSymbol;
|
||||
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
|
||||
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||
use crate::symbol::type_symbol::TypeSymbol;
|
||||
use crate::symbol::variable_symbol::VariableSymbol;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub mod callable_symbol;
|
||||
pub mod class_symbol;
|
||||
pub mod constructor_symbol;
|
||||
pub mod expressible_symbol;
|
||||
pub mod field_symbol;
|
||||
pub mod function_symbol;
|
||||
pub mod generic_parameter_symbol;
|
||||
pub mod parameter_symbol;
|
||||
pub mod type_symbol;
|
||||
pub mod variable_symbol;
|
||||
|
||||
#[derive(Clone, Eq, PartialEq, Hash)]
|
||||
pub enum Symbol {
|
||||
Class(Rc<ClassSymbol>),
|
||||
GenericParameter(Rc<GenericParameterSymbol>),
|
||||
Field(Rc<FieldSymbol>),
|
||||
Constructor(Rc<ConstructorSymbol>),
|
||||
Function(Rc<FunctionSymbol>),
|
||||
Parameter(Rc<ParameterSymbol>),
|
||||
Variable(Rc<VariableSymbol>),
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
pub fn scope_id(&self) -> usize {
|
||||
match self {
|
||||
Symbol::Class(class_symbol) => class_symbol.scope_id(),
|
||||
Symbol::GenericParameter(generic_parameter_symbol) => {
|
||||
generic_parameter_symbol.scope_id()
|
||||
}
|
||||
Symbol::Field(field_symbol) => field_symbol.scope_id(),
|
||||
Symbol::Constructor(constructor_symbol) => constructor_symbol.scope_id(),
|
||||
Symbol::Function(function_symbol) => function_symbol.scope_id(),
|
||||
Symbol::Parameter(parameter_symbol) => parameter_symbol.scope_id(),
|
||||
Symbol::Variable(variable_symbol) => variable_symbol.scope_id(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_name(&self) -> &str {
|
||||
match self {
|
||||
Symbol::Class(class_symbol) => class_symbol.declared_name(),
|
||||
Symbol::GenericParameter(generic_parameter_symbol) => {
|
||||
generic_parameter_symbol.declared_name()
|
||||
}
|
||||
Symbol::Field(field_symbol) => field_symbol.declared_name(),
|
||||
Symbol::Constructor(constructor_symbol) => constructor_symbol.declared_name(),
|
||||
Symbol::Function(function_symbol) => function_symbol.declared_name(),
|
||||
Symbol::Parameter(parameter_symbol) => parameter_symbol.declared_name(),
|
||||
Symbol::Variable(variable_symbol) => variable_symbol.declared_name(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_name_source_range(&self) -> Option<&SourceRange> {
|
||||
match self {
|
||||
Symbol::Class(class_symbol) => class_symbol.declared_name_source_range(),
|
||||
Symbol::GenericParameter(generic_parameter_symbol) => {
|
||||
Some(generic_parameter_symbol.declared_name_source_range())
|
||||
}
|
||||
Symbol::Field(field_symbol) => Some(field_symbol.declared_name_source_range()),
|
||||
Symbol::Constructor(constructor_symbol) => {
|
||||
Some(constructor_symbol.declared_name_source_range())
|
||||
}
|
||||
Symbol::Function(function_symbol) => Some(function_symbol.declared_name_source_range()),
|
||||
Symbol::Parameter(parameter_symbol) => parameter_symbol.declared_name_source_range(),
|
||||
Symbol::Variable(variable_symbol) => Some(variable_symbol.declared_name_source_range()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_type_symbol(&self) -> TypeSymbol {
|
||||
match self {
|
||||
Symbol::Class(class_symbol) => TypeSymbol::Class(class_symbol.clone()),
|
||||
Symbol::GenericParameter(generic_parameter_symbol) => {
|
||||
TypeSymbol::GenericParameter(generic_parameter_symbol.clone())
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_expressible_symbol(&self) -> ExpressibleSymbol {
|
||||
match self {
|
||||
Symbol::Class(class_symbol) => ExpressibleSymbol::Class(class_symbol.clone()),
|
||||
Symbol::Field(field_symbol) => ExpressibleSymbol::Field(field_symbol.clone()),
|
||||
Symbol::Function(function_symbol) => {
|
||||
ExpressibleSymbol::Function(function_symbol.clone())
|
||||
}
|
||||
Symbol::Parameter(parameter_symbol) => {
|
||||
ExpressibleSymbol::Parameter(parameter_symbol.clone())
|
||||
}
|
||||
Symbol::Variable(variable_symbol) => {
|
||||
ExpressibleSymbol::Variable(variable_symbol.clone())
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_function_symbol(&self) -> &Rc<FunctionSymbol> {
|
||||
match self {
|
||||
Symbol::Function(function_symbol) => function_symbol,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_variable_symbol(&self) -> &Rc<VariableSymbol> {
|
||||
match self {
|
||||
Symbol::Variable(variable_symbol) => variable_symbol,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_class_symbol(&self) -> &Rc<ClassSymbol> {
|
||||
match self {
|
||||
Symbol::Class(class_symbol) => class_symbol,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_field_symbol(&self) -> &Rc<FieldSymbol> {
|
||||
match self {
|
||||
Symbol::Field(field_symbol) => field_symbol,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_parameter_symbol(&self) -> &Rc<ParameterSymbol> {
|
||||
match self {
|
||||
Symbol::Parameter(parameter_symbol) => parameter_symbol,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap_constructor_symbol(&self) -> &Rc<ConstructorSymbol> {
|
||||
match self {
|
||||
Symbol::Constructor(constructor_symbol) => constructor_symbol,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,54 +0,0 @@
|
||||
use crate::source_range::SourceRange;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct ParameterSymbol {
|
||||
declared_name: Rc<str>,
|
||||
declared_name_source_range: Option<SourceRange>,
|
||||
scope_id: usize,
|
||||
}
|
||||
|
||||
impl ParameterSymbol {
|
||||
pub fn new(
|
||||
declared_name: &Rc<str>,
|
||||
declared_name_source_range: Option<SourceRange>,
|
||||
scope_id: usize,
|
||||
) -> Self {
|
||||
Self {
|
||||
declared_name: declared_name.clone(),
|
||||
declared_name_source_range,
|
||||
scope_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_name(&self) -> &str {
|
||||
&self.declared_name
|
||||
}
|
||||
|
||||
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||
self.declared_name.clone()
|
||||
}
|
||||
|
||||
pub fn declared_name_source_range(&self) -> Option<&SourceRange> {
|
||||
self.declared_name_source_range.as_ref()
|
||||
}
|
||||
|
||||
pub fn scope_id(&self) -> usize {
|
||||
self.scope_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for ParameterSymbol {}
|
||||
|
||||
impl PartialEq for ParameterSymbol {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.declared_name == other.declared_name && self.scope_id == other.scope_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for ParameterSymbol {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.declared_name.hash(state);
|
||||
self.scope_id.hash(state);
|
||||
}
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
use crate::symbol::Symbol;
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub enum TypeSymbol {
|
||||
Class(Rc<ClassSymbol>),
|
||||
GenericParameter(Rc<GenericParameterSymbol>),
|
||||
}
|
||||
|
||||
impl TypeSymbol {
|
||||
pub fn into_symbol(self) -> Symbol {
|
||||
match self {
|
||||
TypeSymbol::Class(class_symbol) => Symbol::Class(class_symbol),
|
||||
TypeSymbol::GenericParameter(generic_parameter_symbol) => {
|
||||
Symbol::GenericParameter(generic_parameter_symbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,72 +0,0 @@
|
||||
use crate::source_range::SourceRange;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct VariableSymbol {
|
||||
declared_name: Rc<str>,
|
||||
declared_name_source_range: SourceRange,
|
||||
is_mut: bool,
|
||||
scope_id: usize,
|
||||
}
|
||||
|
||||
impl VariableSymbol {
|
||||
pub fn new(
|
||||
name: &Rc<str>,
|
||||
declared_name_source_range: &SourceRange,
|
||||
is_mut: bool,
|
||||
scope_id: usize,
|
||||
) -> Self {
|
||||
Self {
|
||||
declared_name: name.clone(),
|
||||
declared_name_source_range: declared_name_source_range.clone(),
|
||||
is_mut,
|
||||
scope_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn declared_name(&self) -> &str {
|
||||
&self.declared_name
|
||||
}
|
||||
|
||||
pub fn declared_name_owned(&self) -> Rc<str> {
|
||||
self.declared_name.clone()
|
||||
}
|
||||
|
||||
pub fn declared_name_source_range(&self) -> &SourceRange {
|
||||
&self.declared_name_source_range
|
||||
}
|
||||
|
||||
pub fn is_mut(&self) -> bool {
|
||||
self.is_mut
|
||||
}
|
||||
|
||||
pub fn scope_id(&self) -> usize {
|
||||
self.scope_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for VariableSymbol {}
|
||||
|
||||
impl PartialEq for VariableSymbol {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.declared_name == other.declared_name && self.scope_id == other.scope_id
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for VariableSymbol {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.declared_name.hash(state);
|
||||
self.scope_id.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for VariableSymbol {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"VariableSymbol({:?}, {})",
|
||||
self.declared_name, self.scope_id
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -1,241 +0,0 @@
|
||||
use crate::scope::Scope;
|
||||
use crate::scope::block_scope::BlockScope;
|
||||
use crate::scope::class_body_scope::ClassBodyScope;
|
||||
use crate::scope::class_scope::ClassScope;
|
||||
use crate::scope::function_scope::FunctionScope;
|
||||
use crate::scope::module_scope::ModuleScope;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol::expressible_symbol::ExpressibleSymbol;
|
||||
use crate::symbol::field_symbol::FieldSymbol;
|
||||
use crate::symbol::function_symbol::FunctionSymbol;
|
||||
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
|
||||
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||
use crate::symbol::type_symbol::TypeSymbol;
|
||||
use crate::symbol::variable_symbol::VariableSymbol;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
fn find_class_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<ClassSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<Symbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| Symbol::Class(symbol.clone()))
|
||||
}
|
||||
|
||||
fn find_generic_parameter_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<GenericParameterSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<Symbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| Symbol::GenericParameter(symbol.clone()))
|
||||
}
|
||||
|
||||
fn find_field_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<FieldSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<Symbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| Symbol::Field(symbol.clone()))
|
||||
}
|
||||
|
||||
fn find_function_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<FunctionSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<Symbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| Symbol::Function(symbol.clone()))
|
||||
}
|
||||
|
||||
fn find_parameter_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<ParameterSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<Symbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| Symbol::Parameter(symbol.clone()))
|
||||
}
|
||||
|
||||
fn find_variable_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<VariableSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<Symbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| Symbol::Variable(symbol.clone()))
|
||||
}
|
||||
|
||||
/* Expressible symbol refs */
|
||||
|
||||
fn find_class_expressible_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<ClassSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<ExpressibleSymbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| ExpressibleSymbol::Class(symbol.clone()))
|
||||
}
|
||||
|
||||
fn find_field_expressible_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<FieldSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<ExpressibleSymbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| ExpressibleSymbol::Field(symbol.clone()))
|
||||
}
|
||||
|
||||
fn find_function_expressible_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<FunctionSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<ExpressibleSymbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| ExpressibleSymbol::Function(symbol.clone()))
|
||||
}
|
||||
|
||||
fn find_parameter_expressible_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<ParameterSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<ExpressibleSymbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| ExpressibleSymbol::Parameter(symbol.clone()))
|
||||
}
|
||||
|
||||
fn find_variable_expressible_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<VariableSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<ExpressibleSymbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| ExpressibleSymbol::Variable(symbol.clone()))
|
||||
}
|
||||
|
||||
/* Find type symbols */
|
||||
|
||||
fn find_class_type_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<ClassSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<TypeSymbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| TypeSymbol::Class(symbol.clone()))
|
||||
}
|
||||
|
||||
fn find_generic_parameter_type_symbol_ref(
|
||||
symbols: &HashMap<Rc<str>, Rc<GenericParameterSymbol>>,
|
||||
name: &str,
|
||||
) -> Option<TypeSymbol> {
|
||||
symbols
|
||||
.get(name)
|
||||
.map(|symbol| TypeSymbol::GenericParameter(symbol.clone()))
|
||||
}
|
||||
|
||||
/* Public helper functions */
|
||||
/* Various find in functions */
|
||||
|
||||
pub fn find_in_module_by_name(module_scope: &ModuleScope, name: &str) -> Option<Symbol> {
|
||||
find_function_symbol_ref(&module_scope.function_symbols(), name)
|
||||
.or_else(|| find_class_symbol_ref(&module_scope.class_symbols(), name))
|
||||
}
|
||||
|
||||
pub fn find_in_class_by_name(class_scope: &ClassScope, name: &str) -> Option<Symbol> {
|
||||
find_generic_parameter_symbol_ref(&class_scope.generic_parameter_symbols(), name)
|
||||
}
|
||||
|
||||
pub fn find_in_class_body_by_name(class_body_scope: &ClassBodyScope, name: &str) -> Option<Symbol> {
|
||||
find_class_symbol_ref(&class_body_scope.class_symbols(), name)
|
||||
.or_else(|| find_function_symbol_ref(&class_body_scope.function_symbols(), name))
|
||||
.or_else(|| find_field_symbol_ref(&class_body_scope.field_symbols(), name))
|
||||
}
|
||||
|
||||
pub fn find_in_function_by_name(function_scope: &FunctionScope, name: &str) -> Option<Symbol> {
|
||||
find_parameter_symbol_ref(&function_scope.parameter_symbols(), name)
|
||||
}
|
||||
|
||||
pub fn find_in_block_by_name(block_scope: &BlockScope, name: &str) -> Option<Symbol> {
|
||||
find_variable_symbol_ref(&block_scope.variable_symbols(), name)
|
||||
}
|
||||
|
||||
/* Find expressible */
|
||||
|
||||
fn find_expressible_in_module_by_name(
|
||||
module_scope: &ModuleScope,
|
||||
name: &str,
|
||||
) -> Option<ExpressibleSymbol> {
|
||||
find_class_expressible_symbol_ref(&module_scope.class_symbols(), name)
|
||||
.or_else(|| find_function_expressible_symbol_ref(&module_scope.function_symbols(), name))
|
||||
}
|
||||
|
||||
fn find_expressible_in_class_body_by_name(
|
||||
class_body_scope: &ClassBodyScope,
|
||||
name: &str,
|
||||
) -> Option<ExpressibleSymbol> {
|
||||
find_class_expressible_symbol_ref(&class_body_scope.class_symbols(), name)
|
||||
.or_else(|| {
|
||||
find_function_expressible_symbol_ref(&class_body_scope.function_symbols(), name)
|
||||
})
|
||||
.or_else(|| find_field_expressible_symbol_ref(&class_body_scope.field_symbols(), name))
|
||||
}
|
||||
|
||||
fn find_expressible_in_function_by_name(
|
||||
function_scope: &FunctionScope,
|
||||
name: &str,
|
||||
) -> Option<ExpressibleSymbol> {
|
||||
find_parameter_expressible_symbol_ref(function_scope.parameter_symbols(), name)
|
||||
}
|
||||
|
||||
fn find_expressible_in_block_by_name(
|
||||
block_scope: &BlockScope,
|
||||
name: &str,
|
||||
) -> Option<ExpressibleSymbol> {
|
||||
find_variable_expressible_symbol_ref(block_scope.variable_symbols(), name)
|
||||
}
|
||||
|
||||
pub fn find_expressible_symbol(scope: &Scope, name: &str) -> Option<ExpressibleSymbol> {
|
||||
match scope {
|
||||
Scope::Module(module_scope) => find_expressible_in_module_by_name(module_scope, name),
|
||||
Scope::Class(_) => None,
|
||||
Scope::ClassBody(class_body_scope) => {
|
||||
find_expressible_in_class_body_by_name(class_body_scope, name)
|
||||
}
|
||||
Scope::Function(function_scope) => {
|
||||
find_expressible_in_function_by_name(function_scope, name)
|
||||
}
|
||||
Scope::Block(block_scope) => find_expressible_in_block_by_name(block_scope, name),
|
||||
}
|
||||
}
|
||||
|
||||
/* Find type */
|
||||
|
||||
fn find_type_symbol_in_module(module_scope: &ModuleScope, name: &str) -> Option<TypeSymbol> {
|
||||
find_class_type_symbol_ref(&module_scope.class_symbols(), name)
|
||||
}
|
||||
|
||||
fn find_type_symbol_in_class_body(
|
||||
class_body_scope: &ClassBodyScope,
|
||||
name: &str,
|
||||
) -> Option<TypeSymbol> {
|
||||
find_class_type_symbol_ref(&class_body_scope.class_symbols(), name)
|
||||
}
|
||||
|
||||
fn find_type_symbol_in_class(class_scope: &ClassScope, name: &str) -> Option<TypeSymbol> {
|
||||
find_generic_parameter_type_symbol_ref(&class_scope.generic_parameter_symbols(), name)
|
||||
}
|
||||
|
||||
pub fn find_type_symbol(scope: &Scope, name: &str) -> Option<TypeSymbol> {
|
||||
match scope {
|
||||
Scope::Module(module_scope) => find_type_symbol_in_module(module_scope, name),
|
||||
Scope::Class(class_scope) => find_type_symbol_in_class(class_scope, name),
|
||||
Scope::ClassBody(class_body_scope) => {
|
||||
find_type_symbol_in_class_body(class_body_scope, name)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -1,420 +0,0 @@
|
||||
mod helpers;
|
||||
pub mod util;
|
||||
|
||||
use crate::scope::Scope;
|
||||
use crate::scope::block_scope::BlockScope;
|
||||
use crate::scope::class_body_scope::ClassBodyScope;
|
||||
use crate::scope::class_scope::ClassScope;
|
||||
use crate::scope::function_scope::FunctionScope;
|
||||
use crate::scope::module_scope::ModuleScope;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol::constructor_symbol::ConstructorSymbol;
|
||||
use crate::symbol::expressible_symbol::ExpressibleSymbol;
|
||||
use crate::symbol::field_symbol::FieldSymbol;
|
||||
use crate::symbol::function_symbol::FunctionSymbol;
|
||||
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
|
||||
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||
use crate::symbol::type_symbol::TypeSymbol;
|
||||
use crate::symbol::variable_symbol::VariableSymbol;
|
||||
use crate::symbol_table::helpers::{
|
||||
find_expressible_symbol, find_in_block_by_name, find_in_class_body_by_name,
|
||||
find_in_class_by_name, find_in_function_by_name, find_in_module_by_name, find_type_symbol,
|
||||
};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct SymbolTable {
|
||||
scopes: Vec<Scope>,
|
||||
current_scope_id: Option<usize>,
|
||||
}
|
||||
|
||||
impl SymbolTable {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
scopes: vec![],
|
||||
current_scope_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn new_scope_id(&self) -> usize {
|
||||
self.scopes.len()
|
||||
}
|
||||
|
||||
fn push_scope(&mut self, scope: Scope) -> usize {
|
||||
let scope_id = self.new_scope_id();
|
||||
self.scopes.push(scope);
|
||||
self.current_scope_id = Some(scope_id);
|
||||
scope_id
|
||||
}
|
||||
|
||||
pub fn push_module_scope(&mut self, debug_name: &str) -> usize {
|
||||
self.push_scope(Scope::Module(ModuleScope::new(
|
||||
debug_name,
|
||||
self.current_scope_id,
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn push_class_scope(&mut self, debug_name: &str) -> usize {
|
||||
self.push_scope(Scope::Class(ClassScope::new(
|
||||
debug_name,
|
||||
self.current_scope_id.unwrap(),
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn push_class_body_scope(&mut self, debug_name: &str) -> usize {
|
||||
self.push_scope(Scope::ClassBody(ClassBodyScope::new(
|
||||
debug_name,
|
||||
self.current_scope_id.unwrap(),
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn push_function_scope(&mut self, debug_name: &str) -> usize {
|
||||
self.push_scope(Scope::Function(FunctionScope::new(
|
||||
debug_name,
|
||||
self.current_scope_id.unwrap(),
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn push_block_scope(&mut self, debug_name: &str) -> usize {
|
||||
self.push_scope(Scope::Block(BlockScope::new(
|
||||
debug_name,
|
||||
self.current_scope_id.unwrap(),
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn pop_scope(&mut self) {
|
||||
self.current_scope_id = self.scopes[self.current_scope_id.unwrap()].parent_id();
|
||||
}
|
||||
|
||||
pub fn current_scope_id(&self) -> usize {
|
||||
self.current_scope_id.unwrap()
|
||||
}
|
||||
|
||||
pub fn change_scope(&mut self, scope_id: usize) {
|
||||
self.current_scope_id = Some(scope_id);
|
||||
}
|
||||
|
||||
fn scope(&self, scope_id: usize) -> &Scope {
|
||||
&self.scopes[scope_id]
|
||||
}
|
||||
|
||||
fn scope_mut(&mut self, scope_id: usize) -> &mut Scope {
|
||||
&mut self.scopes[scope_id]
|
||||
}
|
||||
|
||||
pub fn get_symbol(&self, scope_id: usize, name: &str) -> Option<Symbol> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::Module(module_scope) => find_in_module_by_name(module_scope, name),
|
||||
Scope::Class(class_scope) => find_in_class_by_name(class_scope, name),
|
||||
Scope::ClassBody(class_body_scope) => {
|
||||
find_in_class_body_by_name(class_body_scope, name)
|
||||
}
|
||||
Scope::Function(function_scope) => find_in_function_by_name(function_scope, name),
|
||||
Scope::Block(block_scope) => find_in_block_by_name(block_scope, name),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_symbol(&mut self, symbol: Symbol) {
|
||||
match symbol {
|
||||
Symbol::Class(class_symbol) => {
|
||||
self.insert_class_symbol(class_symbol);
|
||||
}
|
||||
Symbol::GenericParameter(generic_parameter_symbol) => {
|
||||
self.insert_generic_parameter_symbol(generic_parameter_symbol);
|
||||
}
|
||||
Symbol::Field(field_symbol) => {
|
||||
self.insert_field_symbol(field_symbol);
|
||||
}
|
||||
Symbol::Constructor(constructor_symbol) => {
|
||||
self.insert_constructor_symbol(constructor_symbol);
|
||||
}
|
||||
Symbol::Function(function_symbol) => {
|
||||
self.insert_function_symbol(function_symbol);
|
||||
}
|
||||
Symbol::Parameter(parameter_symbol) => {
|
||||
self.insert_parameter_symbol(parameter_symbol);
|
||||
}
|
||||
Symbol::Variable(variable_symbol) => {
|
||||
self.insert_variable_symbol(variable_symbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_class_symbol(&mut self, class_symbol: Rc<ClassSymbol>) {
|
||||
let name = class_symbol.declared_name_owned();
|
||||
match self.scope_mut(class_symbol.scope_id()) {
|
||||
Scope::Module(module_scope) => {
|
||||
module_scope.class_symbols_mut().insert(name, class_symbol);
|
||||
}
|
||||
Scope::ClassBody(class_scope) => {
|
||||
class_scope.class_symbols_mut().insert(name, class_symbol);
|
||||
}
|
||||
_ => panic!("Attempt to insert ClassSymbol in incompatible scope"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_generic_parameter_symbol(
|
||||
&mut self,
|
||||
generic_parameter_symbol: Rc<GenericParameterSymbol>,
|
||||
) {
|
||||
let name = generic_parameter_symbol.declared_name_owned();
|
||||
match self.scope_mut(generic_parameter_symbol.scope_id()) {
|
||||
Scope::Class(class_scope) => {
|
||||
class_scope
|
||||
.generic_parameter_symbols_mut()
|
||||
.insert(name, generic_parameter_symbol);
|
||||
}
|
||||
_ => panic!("Attempt to insert GenericParameterSymbol in incompatible scope"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_constructor_symbol(&mut self, constructor_symbol: Rc<ConstructorSymbol>) {
|
||||
match self.scope_mut(constructor_symbol.scope_id()) {
|
||||
Scope::ClassBody(class_body_scope) => {
|
||||
class_body_scope
|
||||
.constructor_symbol_mut()
|
||||
.replace(constructor_symbol);
|
||||
}
|
||||
_ => panic!(
|
||||
"Attempt to insert ConstructorSymbol in incompatible scope: {:?}",
|
||||
self.scope(constructor_symbol.scope_id())
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_field_symbol(&mut self, field_symbol: Rc<FieldSymbol>) {
|
||||
let name = field_symbol.declared_name_owned();
|
||||
match self.scope_mut(field_symbol.scope_id()) {
|
||||
Scope::ClassBody(class_scope) => {
|
||||
class_scope.field_symbols_mut().insert(name, field_symbol);
|
||||
}
|
||||
_ => panic!("Attempt to insert FieldSymbol in incompatible scope"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_function_symbol(&mut self, function_symbol: Rc<FunctionSymbol>) {
|
||||
let name = function_symbol.declared_name_owned();
|
||||
match self.scope_mut(function_symbol.scope_id()) {
|
||||
Scope::Module(module_scope) => {
|
||||
module_scope
|
||||
.function_symbols_mut()
|
||||
.insert(name, function_symbol);
|
||||
}
|
||||
Scope::ClassBody(class_scope) => {
|
||||
class_scope
|
||||
.function_symbols_mut()
|
||||
.insert(name, function_symbol);
|
||||
}
|
||||
_ => panic!("Attempt to insert FunctionSymbol in incompatible scope"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_parameter_symbol(&mut self, parameter_symbol: Rc<ParameterSymbol>) {
|
||||
let name = parameter_symbol.declared_name_owned();
|
||||
match self.scope_mut(parameter_symbol.scope_id()) {
|
||||
Scope::Function(function_scope) => {
|
||||
function_scope
|
||||
.parameter_symbols_mut()
|
||||
.insert(name, parameter_symbol);
|
||||
}
|
||||
_ => panic!("Attempt to insert ParameterSymbol in incompatible scope"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_variable_symbol(&mut self, variable_symbol: Rc<VariableSymbol>) {
|
||||
match self.scope_mut(variable_symbol.scope_id()) {
|
||||
Scope::Block(block_scope) => {
|
||||
block_scope
|
||||
.variable_symbols_mut()
|
||||
.insert(variable_symbol.declared_name_owned(), variable_symbol);
|
||||
}
|
||||
_ => panic!("Attempt to insert VariableSymbol in incompatible scope"),
|
||||
}
|
||||
}
|
||||
|
||||
fn find_symbol<S>(
|
||||
&self,
|
||||
scope_id: usize,
|
||||
name: &str,
|
||||
f: impl Fn(&Scope, &str) -> Option<S>,
|
||||
) -> Option<S> {
|
||||
let mut maybe_scope = self.scopes.get(scope_id);
|
||||
if maybe_scope.is_none() {
|
||||
panic!("Invalid scope_id: {}", scope_id);
|
||||
}
|
||||
while let Some(scope) = maybe_scope {
|
||||
let maybe_symbol = f(scope, name);
|
||||
if maybe_symbol.is_some() {
|
||||
return maybe_symbol;
|
||||
} else {
|
||||
maybe_scope = scope.parent_id().and_then(|id| self.scopes.get(id));
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn find_expressible_symbol(
|
||||
&self,
|
||||
scope_id: usize,
|
||||
name: &str,
|
||||
) -> Option<ExpressibleSymbol> {
|
||||
let mut maybe_scope = self.scopes.get(scope_id);
|
||||
if maybe_scope.is_none() {
|
||||
panic!("Invalid scope_id: {}", scope_id);
|
||||
}
|
||||
while let Some(scope) = maybe_scope {
|
||||
let maybe_expressible_symbol = find_expressible_symbol(scope, name);
|
||||
if maybe_expressible_symbol.is_some() {
|
||||
return maybe_expressible_symbol;
|
||||
} else {
|
||||
maybe_scope = scope.parent_id().map(|id| &self.scopes[id]);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn find_type_symbol(&self, scope_id: usize, name: &str) -> Option<TypeSymbol> {
|
||||
let mut maybe_scope = self.scopes.get(scope_id);
|
||||
if maybe_scope.is_none() {
|
||||
panic!("Invalid scope_id: {}", scope_id);
|
||||
}
|
||||
while let Some(scope) = maybe_scope {
|
||||
let maybe_type_symbol = find_type_symbol(scope, name);
|
||||
if maybe_type_symbol.is_some() {
|
||||
return maybe_type_symbol;
|
||||
} else {
|
||||
maybe_scope = scope.parent_id().map(|id| &self.scopes[id]);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_class_symbol(&self, scope_id: usize, name: &str) -> Option<&Rc<ClassSymbol>> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::Module(module_scope) => module_scope.class_symbols().get(name),
|
||||
Scope::ClassBody(class_body_scope) => class_body_scope.class_symbols().get(name),
|
||||
_ => panic!("scope_id {} cannot contain classes", scope_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_generic_parameter_symbol_owned(
|
||||
&self,
|
||||
scope_id: usize,
|
||||
name: &str,
|
||||
) -> Option<Rc<GenericParameterSymbol>> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::Class(class_scope) => class_scope.generic_parameter_symbols().get(name).cloned(),
|
||||
_ => panic!("scope_id {} cannot contain generic types", scope_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_field_symbol(&self, scope_id: usize, name: &str) -> Option<&FieldSymbol> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::ClassBody(class_body_scope) => {
|
||||
class_body_scope.field_symbols().get(name).map(Rc::as_ref)
|
||||
}
|
||||
_ => panic!("scope_id {} is not a ClassBodyScope", scope_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_field_symbol_owned(&self, scope_id: usize, name: &str) -> Option<Rc<FieldSymbol>> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::ClassBody(class_body_scope) => class_body_scope
|
||||
.field_symbols()
|
||||
.get(name)
|
||||
.map(|s| Rc::clone(s)),
|
||||
_ => panic!("scope_id {} is not a ClassBodyScope", scope_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_constructor_symbol(&self, scope_id: usize) -> Option<&ConstructorSymbol> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::ClassBody(class_body_scope) => {
|
||||
class_body_scope.constructor_symbol().map(Rc::as_ref)
|
||||
}
|
||||
_ => panic!("scope_id {} is not a ClassBodyScope", scope_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_constructor_symbol_owned(&self, scope_id: usize) -> Option<Rc<ConstructorSymbol>> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::ClassBody(class_body_scope) => class_body_scope.constructor_symbol().cloned(),
|
||||
_ => panic!(
|
||||
"scope_id {} is not a ClassBodyScope: {:?}",
|
||||
scope_id,
|
||||
self.scope(scope_id)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_function_symbol(&self, scope_id: usize, name: &str) -> Option<&FunctionSymbol> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::Module(module_scope) => {
|
||||
module_scope.function_symbols().get(name).map(Rc::as_ref)
|
||||
}
|
||||
Scope::ClassBody(class_body_scope) => class_body_scope
|
||||
.function_symbols()
|
||||
.get(name)
|
||||
.map(Rc::as_ref),
|
||||
_ => panic!("scope_id {} cannot contain Functions", scope_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_function_symbol_owned(
|
||||
&self,
|
||||
scope_id: usize,
|
||||
name: &str,
|
||||
) -> Option<Rc<FunctionSymbol>> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::Module(module_scope) => module_scope
|
||||
.function_symbols()
|
||||
.get(name)
|
||||
.map(|s| Rc::clone(s)),
|
||||
Scope::ClassBody(class_body_scope) => class_body_scope
|
||||
.function_symbols()
|
||||
.get(name)
|
||||
.map(|s| Rc::clone(s)),
|
||||
_ => panic!("scope_id {} cannot contain Functions", scope_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_parameter_symbol(&self, scope_id: usize, name: &str) -> Option<&ParameterSymbol> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::Function(function_scope) => {
|
||||
function_scope.parameter_symbols().get(name).map(Rc::as_ref)
|
||||
}
|
||||
_ => panic!("scope_id {} cannot contain Parameters", scope_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_parameter_symbol_owned(
|
||||
&self,
|
||||
scope_id: usize,
|
||||
name: &str,
|
||||
) -> Option<Rc<ParameterSymbol>> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::Function(function_scope) => {
|
||||
function_scope.parameter_symbols().get(name).cloned()
|
||||
}
|
||||
_ => panic!("scope_id {} cannot contain Parameters", scope_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_variable_symbol(&self, scope_id: usize, name: &str) -> Option<&VariableSymbol> {
|
||||
match &self.scopes[scope_id] {
|
||||
Scope::Block(block_scope) => block_scope.variable_symbols().get(name).map(Rc::as_ref),
|
||||
_ => panic!("scope_id {} is not a BlockScope", scope_id),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_variable_symbol_owned(
|
||||
&self,
|
||||
scope_id: usize,
|
||||
name: &str,
|
||||
) -> Option<Rc<VariableSymbol>> {
|
||||
match self.scope(scope_id) {
|
||||
Scope::Block(block_scope) => block_scope.variable_symbols().get(name).map(Rc::clone),
|
||||
_ => panic!("scope_id {} is not a BlockScope", scope_id),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
use crate::diagnostic::Diagnostic;
|
||||
use crate::diagnostic_factories::symbol_already_declared;
|
||||
use crate::diagnostics_result;
|
||||
use crate::symbol::Symbol;
|
||||
use crate::symbol_table::SymbolTable;
|
||||
|
||||
pub fn try_insert_symbol_into(
|
||||
symbol: Symbol,
|
||||
symbol_table: &mut SymbolTable,
|
||||
) -> Result<(), Diagnostic> {
|
||||
let maybe_already_inserted = symbol_table.get_symbol(symbol.scope_id(), symbol.declared_name());
|
||||
if let Some(already_inserted) = maybe_already_inserted {
|
||||
Err(symbol_already_declared(&already_inserted, &symbol))
|
||||
} else {
|
||||
symbol_table.insert_symbol(symbol);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_insert_symbols_into(
|
||||
symbols: Vec<Symbol>,
|
||||
symbol_table: &mut SymbolTable,
|
||||
) -> Result<(), Vec<Diagnostic>> {
|
||||
let diagnostics: Vec<Diagnostic> = symbols
|
||||
.into_iter()
|
||||
.map(|symbol| try_insert_symbol_into(symbol, symbol_table))
|
||||
.filter_map(Result::err)
|
||||
.collect();
|
||||
diagnostics_result!(diagnostics)
|
||||
}
|
||||
@ -1,265 +0,0 @@
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol::function_symbol::FunctionSymbol;
|
||||
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum TypeInfo {
|
||||
Any,
|
||||
Integer,
|
||||
Double,
|
||||
String,
|
||||
Function(Rc<FunctionSymbol>),
|
||||
|
||||
#[deprecated]
|
||||
Class(Rc<ClassSymbol>),
|
||||
|
||||
ParameterizedClass(Rc<ClassSymbol>, Vec<TypeInfo>),
|
||||
GenericType(Rc<GenericParameterSymbol>),
|
||||
Void,
|
||||
|
||||
PlaceholderError,
|
||||
}
|
||||
|
||||
impl Display for TypeInfo {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
TypeInfo::Any => write!(f, "Any"),
|
||||
TypeInfo::Integer => write!(f, "Int"),
|
||||
TypeInfo::Double => write!(f, "Double"),
|
||||
TypeInfo::String => write!(f, "String"),
|
||||
TypeInfo::Function(function_symbol) => {
|
||||
write!(f, "fn(")?;
|
||||
for (i, parameter) in function_symbol.parameters().iter().enumerate() {
|
||||
parameter.declared_name().fmt(f)?;
|
||||
if i < function_symbol.parameters().len() - 1 {
|
||||
f.write_str(", ")?;
|
||||
}
|
||||
}
|
||||
write!(f, ")")
|
||||
}
|
||||
TypeInfo::Class(class_symbol) => {
|
||||
write!(f, "Class({:?})", class_symbol)
|
||||
}
|
||||
TypeInfo::ParameterizedClass(class_symbol, arguments) => {
|
||||
write!(
|
||||
f,
|
||||
"ParameterizedClass({:?}<{}>)",
|
||||
class_symbol,
|
||||
arguments
|
||||
.iter()
|
||||
.map(|a| a.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
}
|
||||
TypeInfo::GenericType(generic_parameter_symbol) => {
|
||||
write!(f, "{}", generic_parameter_symbol.declared_name())
|
||||
}
|
||||
TypeInfo::Void => write!(f, "Void"),
|
||||
TypeInfo::PlaceholderError => write!(f, "<PlaceholderError>"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_number(type_info: &TypeInfo) -> bool {
|
||||
matches!(type_info, TypeInfo::Integer | TypeInfo::Double)
|
||||
}
|
||||
|
||||
fn are_numbers(left: &TypeInfo, right: &TypeInfo) -> bool {
|
||||
is_number(left) && is_number(right)
|
||||
}
|
||||
|
||||
impl TypeInfo {
|
||||
pub fn is_assignable_from(&self, other: &TypeInfo) -> bool {
|
||||
match self {
|
||||
TypeInfo::Any => true,
|
||||
TypeInfo::Integer => {
|
||||
matches!(other, TypeInfo::Integer)
|
||||
}
|
||||
TypeInfo::Double => {
|
||||
matches!(other, TypeInfo::Double)
|
||||
}
|
||||
TypeInfo::String => {
|
||||
matches!(other, TypeInfo::String)
|
||||
}
|
||||
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::ParameterizedClass(class_symbol, arguments) => match other {
|
||||
TypeInfo::ParameterizedClass(other_class_symbol, other_arguments) => {
|
||||
if arguments.is_empty() && other_arguments.is_empty() {
|
||||
class_symbol == other_class_symbol
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
TypeInfo::GenericType(generic_parameter_symbol) => {
|
||||
// if generic_parameter_symbol.extends().len() > 0 {
|
||||
// unimplemented!(
|
||||
// "Assigning to generic parameter type with extends type uses not yet supported."
|
||||
// );
|
||||
// }
|
||||
true
|
||||
}
|
||||
TypeInfo::Void => {
|
||||
matches!(other, TypeInfo::Void)
|
||||
}
|
||||
TypeInfo::PlaceholderError => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_negate(&self) -> bool {
|
||||
is_number(self)
|
||||
}
|
||||
|
||||
pub fn negate_result(&self) -> TypeInfo {
|
||||
match self {
|
||||
TypeInfo::Integer => TypeInfo::Integer,
|
||||
TypeInfo::Double => TypeInfo::Double,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_multiply(&self, rhs: &Self) -> bool {
|
||||
are_numbers(self, rhs)
|
||||
}
|
||||
|
||||
pub fn multiply_result(&self, rhs: &Self) -> TypeInfo {
|
||||
match self {
|
||||
TypeInfo::Integer => match rhs {
|
||||
TypeInfo::Integer => TypeInfo::Integer,
|
||||
TypeInfo::Double => TypeInfo::Double,
|
||||
_ => panic!(),
|
||||
},
|
||||
TypeInfo::Double => TypeInfo::Double,
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_divide(&self, rhs: &Self) -> bool {
|
||||
are_numbers(self, rhs)
|
||||
}
|
||||
|
||||
pub fn divide_result(&self, _rhs: &Self) -> TypeInfo {
|
||||
TypeInfo::Double // ok for now
|
||||
}
|
||||
|
||||
pub fn can_modulo(&self, rhs: &Self) -> bool {
|
||||
are_numbers(self, rhs)
|
||||
}
|
||||
|
||||
pub fn modulo_result(&self, rhs: &Self) -> TypeInfo {
|
||||
match self {
|
||||
TypeInfo::Integer => match rhs {
|
||||
TypeInfo::Integer => TypeInfo::Integer,
|
||||
TypeInfo::Double => TypeInfo::Double,
|
||||
_ => panic!(),
|
||||
},
|
||||
TypeInfo::Double => match rhs {
|
||||
TypeInfo::Integer | TypeInfo::Double => TypeInfo::Double,
|
||||
_ => panic!(),
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_add(&self, rhs: &Self) -> bool {
|
||||
match self {
|
||||
TypeInfo::Integer => {
|
||||
matches!(rhs, TypeInfo::Integer | TypeInfo::Double | TypeInfo::String)
|
||||
}
|
||||
TypeInfo::Double => {
|
||||
matches!(rhs, TypeInfo::Integer | TypeInfo::Double | TypeInfo::String)
|
||||
}
|
||||
TypeInfo::String => {
|
||||
matches!(rhs, TypeInfo::Integer | TypeInfo::Double | TypeInfo::String)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_result(&self, rhs: &Self) -> TypeInfo {
|
||||
match self {
|
||||
TypeInfo::Integer => match rhs {
|
||||
TypeInfo::Integer => TypeInfo::Integer,
|
||||
TypeInfo::Double => TypeInfo::Double,
|
||||
TypeInfo::String => TypeInfo::String,
|
||||
_ => panic!("Unsupported add: {} + {}.", self, rhs),
|
||||
},
|
||||
TypeInfo::Double => match rhs {
|
||||
TypeInfo::Integer | TypeInfo::Double => TypeInfo::Double,
|
||||
TypeInfo::String => TypeInfo::String,
|
||||
_ => panic!("Unsupported add: {} + {}.", self, rhs),
|
||||
},
|
||||
TypeInfo::String => TypeInfo::String,
|
||||
_ => panic!("Unsupported add: {} + {}.", self, rhs),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_subtract(&self, rhs: &Self) -> bool {
|
||||
are_numbers(self, rhs)
|
||||
}
|
||||
|
||||
pub fn subtract_result(&self, rhs: &Self) -> TypeInfo {
|
||||
match self {
|
||||
TypeInfo::Integer => match rhs {
|
||||
TypeInfo::Integer => TypeInfo::Integer,
|
||||
TypeInfo::Double => TypeInfo::Double,
|
||||
_ => panic!(),
|
||||
},
|
||||
TypeInfo::Double => match rhs {
|
||||
TypeInfo::Integer | TypeInfo::Double => TypeInfo::Double,
|
||||
_ => panic!(),
|
||||
},
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_left_shift(&self, rhs: &Self) -> bool {
|
||||
matches!(self, TypeInfo::Integer) && matches!(rhs, TypeInfo::Integer)
|
||||
}
|
||||
|
||||
pub fn left_shift_result(&self, _rhs: &Self) -> TypeInfo {
|
||||
TypeInfo::Integer
|
||||
}
|
||||
|
||||
pub fn can_right_shift(&self, rhs: &Self) -> bool {
|
||||
matches!(self, TypeInfo::Integer) && matches!(rhs, TypeInfo::Integer)
|
||||
}
|
||||
|
||||
pub fn right_shift_result(&self, _rhs: &Self) -> TypeInfo {
|
||||
TypeInfo::Integer
|
||||
}
|
||||
|
||||
pub fn can_bitwise_and(&self, rhs: &Self) -> bool {
|
||||
matches!(self, TypeInfo::Integer) && matches!(rhs, TypeInfo::Integer)
|
||||
}
|
||||
|
||||
pub fn bitwise_and_result(&self, _rhs: &Self) -> TypeInfo {
|
||||
TypeInfo::Integer
|
||||
}
|
||||
|
||||
pub fn can_bitwise_xor(&self, rhs: &Self) -> bool {
|
||||
matches!(self, TypeInfo::Integer) && matches!(rhs, TypeInfo::Integer)
|
||||
}
|
||||
|
||||
pub fn bitwise_xor_result(&self, _rhs: &Self) -> TypeInfo {
|
||||
TypeInfo::Integer
|
||||
}
|
||||
|
||||
pub fn can_bitwise_or(&self, rhs: &Self) -> bool {
|
||||
matches!(self, TypeInfo::Integer) && matches!(rhs, TypeInfo::Integer)
|
||||
}
|
||||
|
||||
pub fn bitwise_or_result(&self, _rhs: &Self) -> TypeInfo {
|
||||
TypeInfo::Integer
|
||||
}
|
||||
}
|
||||
@ -1,118 +0,0 @@
|
||||
use crate::symbol::class_symbol::ClassSymbol;
|
||||
use crate::symbol::constructor_symbol::ConstructorSymbol;
|
||||
use crate::symbol::field_symbol::FieldSymbol;
|
||||
use crate::symbol::function_symbol::FunctionSymbol;
|
||||
use crate::symbol::generic_parameter_symbol::GenericParameterSymbol;
|
||||
use crate::symbol::parameter_symbol::ParameterSymbol;
|
||||
use crate::symbol::variable_symbol::VariableSymbol;
|
||||
use crate::type_info::TypeInfo;
|
||||
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>,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
pub fn class_instance_types_mut(&mut self) -> &mut HashMap<Rc<ClassSymbol>, TypeInfo> {
|
||||
&mut self.class_instance_types
|
||||
}
|
||||
|
||||
pub fn generic_parameter_types(&self) -> &HashMap<Rc<GenericParameterSymbol>, TypeInfo> {
|
||||
&self.generic_parameter_types
|
||||
}
|
||||
|
||||
pub fn generic_parameter_types_mut(
|
||||
&mut self,
|
||||
) -> &mut HashMap<Rc<GenericParameterSymbol>, TypeInfo> {
|
||||
&mut self.generic_parameter_types
|
||||
}
|
||||
|
||||
pub fn field_types(&self) -> &HashMap<Rc<FieldSymbol>, TypeInfo> {
|
||||
&self.field_types
|
||||
}
|
||||
|
||||
pub fn field_types_mut(&mut self) -> &mut HashMap<Rc<FieldSymbol>, TypeInfo> {
|
||||
&mut self.field_types
|
||||
}
|
||||
|
||||
pub fn parameter_types(&self) -> &HashMap<Rc<ParameterSymbol>, TypeInfo> {
|
||||
&self.parameter_types
|
||||
}
|
||||
|
||||
pub fn parameter_types_mut(&mut self) -> &mut HashMap<Rc<ParameterSymbol>, TypeInfo> {
|
||||
&mut self.parameter_types
|
||||
}
|
||||
|
||||
pub fn variable_types(&self) -> &HashMap<Rc<VariableSymbol>, TypeInfo> {
|
||||
&self.variable_types
|
||||
}
|
||||
|
||||
pub fn variable_types_mut(&mut self) -> &mut HashMap<Rc<VariableSymbol>, TypeInfo> {
|
||||
&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> {
|
||||
&mut self.constructor_return_types
|
||||
}
|
||||
}
|
||||
@ -1,85 +0,0 @@
|
||||
#[macro_export]
|
||||
macro_rules! handle_diagnostic {
|
||||
( $result: expr, $diagnostics: expr ) => {
|
||||
match $result {
|
||||
Ok(_) => {}
|
||||
Err(diagnostic) => {
|
||||
$diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! handle_diagnostics {
|
||||
( $result: expr, $diagnostics: expr ) => {
|
||||
match $result {
|
||||
Ok(_) => {}
|
||||
Err(mut result_diagnostics) => {
|
||||
$diagnostics.append(&mut result_diagnostics);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! ok_or_return {
|
||||
( $result: expr, $diagnostics: expr ) => {
|
||||
match $result {
|
||||
Ok(inner) => inner,
|
||||
Err(mut diagnostics) => {
|
||||
$diagnostics.append(&mut diagnostics);
|
||||
return Err($diagnostics);
|
||||
}
|
||||
}
|
||||
};
|
||||
( $result: expr ) => {
|
||||
match $result {
|
||||
Ok(inner) => inner,
|
||||
Err(diagnostics) => {
|
||||
return Err(diagnostics);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! maybe_return_diagnostics {
|
||||
( $diagnostics: expr ) => {
|
||||
if !$diagnostics.is_empty() {
|
||||
return Err($diagnostics);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! diagnostics_result {
|
||||
( $diagnostics: expr ) => {
|
||||
if $diagnostics.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err($diagnostics)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! ok_or_err_diagnostics {
|
||||
( $to_return: expr, $diagnostics: expr ) => {
|
||||
if $diagnostics.is_empty() {
|
||||
Ok($to_return)
|
||||
} else {
|
||||
Err($diagnostics)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! push_ok_or_push_errs {
|
||||
( $result: expr, $oks: expr, $errs: expr ) => {
|
||||
match $result {
|
||||
Ok(inner) => $oks.push(inner),
|
||||
Err(mut errs) => $errs.append(&mut errs),
|
||||
}
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user