Delete more old unused code.
This commit is contained in:
parent
e7145de68e
commit
dbbcda638f
@ -1,22 +1,18 @@
|
|||||||
use crate::ast::NodeId;
|
use crate::ast::NodeId;
|
||||||
use crate::source_range::SourceRange;
|
use crate::source_range::SourceRange;
|
||||||
use crate::type_info::TypeInfo;
|
|
||||||
|
|
||||||
pub struct DoubleLiteral {
|
pub struct DoubleLiteral {
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
value: f64,
|
value: f64,
|
||||||
source_range: SourceRange,
|
source_range: SourceRange,
|
||||||
type_info: &'static TypeInfo,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DoubleLiteral {
|
impl DoubleLiteral {
|
||||||
pub fn new(node_id: NodeId, value: f64, source_range: SourceRange) -> Self {
|
pub fn new(node_id: NodeId, value: f64, source_range: SourceRange) -> Self {
|
||||||
const TYPE_INFO: TypeInfo = TypeInfo::Double;
|
|
||||||
Self {
|
Self {
|
||||||
node_id,
|
node_id,
|
||||||
value,
|
value,
|
||||||
source_range,
|
source_range,
|
||||||
type_info: &TYPE_INFO,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,10 +24,6 @@ impl DoubleLiteral {
|
|||||||
self.value
|
self.value
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_info(&self) -> &TypeInfo {
|
|
||||||
&self.type_info
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn source_range(&self) -> &SourceRange {
|
pub fn source_range(&self) -> &SourceRange {
|
||||||
&self.source_range
|
&self.source_range
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +1,18 @@
|
|||||||
use crate::ast::NodeId;
|
use crate::ast::NodeId;
|
||||||
use crate::source_range::SourceRange;
|
use crate::source_range::SourceRange;
|
||||||
use crate::type_info::TypeInfo;
|
|
||||||
|
|
||||||
pub struct IntegerLiteral {
|
pub struct IntegerLiteral {
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
value: i32,
|
value: i32,
|
||||||
source_range: SourceRange,
|
source_range: SourceRange,
|
||||||
type_info: &'static TypeInfo,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntegerLiteral {
|
impl IntegerLiteral {
|
||||||
pub fn new(node_id: NodeId, value: i32, source_range: SourceRange) -> Self {
|
pub fn new(node_id: NodeId, value: i32, source_range: SourceRange) -> Self {
|
||||||
const TYPE_INFO: TypeInfo = TypeInfo::Integer;
|
|
||||||
Self {
|
Self {
|
||||||
node_id,
|
node_id,
|
||||||
value,
|
value,
|
||||||
source_range,
|
source_range,
|
||||||
type_info: &TYPE_INFO,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,10 +24,6 @@ impl IntegerLiteral {
|
|||||||
self.node_id
|
self.node_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_info(&self) -> &TypeInfo {
|
|
||||||
&self.type_info
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn source_range(&self) -> &SourceRange {
|
pub fn source_range(&self) -> &SourceRange {
|
||||||
&self.source_range
|
&self.source_range
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +1,18 @@
|
|||||||
use crate::ast::NodeId;
|
use crate::ast::NodeId;
|
||||||
use crate::source_range::SourceRange;
|
use crate::source_range::SourceRange;
|
||||||
use crate::type_info::TypeInfo;
|
|
||||||
|
|
||||||
pub struct StringLiteral {
|
pub struct StringLiteral {
|
||||||
node_id: NodeId,
|
node_id: NodeId,
|
||||||
content: String,
|
content: String,
|
||||||
source_range: SourceRange,
|
source_range: SourceRange,
|
||||||
type_info: &'static TypeInfo,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StringLiteral {
|
impl StringLiteral {
|
||||||
pub fn new(node_id: NodeId, content: &str, source_range: SourceRange) -> Self {
|
pub fn new(node_id: NodeId, content: &str, source_range: SourceRange) -> Self {
|
||||||
const TYPE_INFO: TypeInfo = TypeInfo::String;
|
|
||||||
Self {
|
Self {
|
||||||
node_id,
|
node_id,
|
||||||
content: content.into(),
|
content: content.into(),
|
||||||
source_range,
|
source_range,
|
||||||
type_info: &TYPE_INFO,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,10 +24,6 @@ impl StringLiteral {
|
|||||||
&self.content
|
&self.content
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn type_info(&self) -> &TypeInfo {
|
|
||||||
&self.type_info
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn source_range(&self) -> &SourceRange {
|
pub fn source_range(&self) -> &SourceRange {
|
||||||
&self.source_range
|
&self.source_range
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,6 @@
|
|||||||
use crate::diagnostic::{Diagnostic, SecondaryLabel};
|
use crate::diagnostic::Diagnostic;
|
||||||
use crate::error_codes::{
|
use crate::error_codes::SYMBOL_NOT_FOUND;
|
||||||
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::source_range::SourceRange;
|
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 {
|
pub fn symbol_not_found(name: &str, source_range: &SourceRange) -> Diagnostic {
|
||||||
Diagnostic::new(
|
Diagnostic::new(
|
||||||
@ -19,255 +10,3 @@ pub fn symbol_not_found(name: &str, source_range: &SourceRange) -> Diagnostic {
|
|||||||
)
|
)
|
||||||
.with_error_code(SYMBOL_NOT_FOUND)
|
.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;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub struct IrClass {
|
pub struct IrClass {
|
||||||
@ -18,45 +14,18 @@ impl IrClass {
|
|||||||
fields,
|
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 {
|
pub struct IrField {
|
||||||
debug_name: Rc<str>,
|
debug_name: Rc<str>,
|
||||||
field_index: usize,
|
field_index: usize,
|
||||||
type_info: TypeInfo,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IrField {
|
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 {
|
Self {
|
||||||
debug_name,
|
debug_name,
|
||||||
field_index,
|
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 constants_table;
|
||||||
pub mod diagnostic;
|
pub mod diagnostic;
|
||||||
mod diagnostic_factories;
|
mod diagnostic_factories;
|
||||||
pub mod error_codes;
|
mod error_codes;
|
||||||
pub mod fqn_util;
|
|
||||||
pub mod intrinsics;
|
|
||||||
pub mod ir;
|
pub mod ir;
|
||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
pub mod lowering;
|
pub mod lowering;
|
||||||
pub mod offset_counter;
|
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
pub mod scope;
|
|
||||||
pub mod semantic_analysis;
|
pub mod semantic_analysis;
|
||||||
pub mod source_range;
|
pub mod source_range;
|
||||||
pub mod symbol;
|
|
||||||
pub mod symbol_table;
|
|
||||||
pub mod token;
|
pub mod token;
|
||||||
pub mod type_info;
|
|
||||||
pub mod types_table;
|
|
||||||
mod util;
|
|
||||||
|
|
||||||
pub type Filename = Rc<str>;
|
pub type Filename = Rc<str>;
|
||||||
pub type FileId = usize;
|
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