Delete more old unused code.

This commit is contained in:
Jesse Brault 2026-08-13 17:54:43 -05:00
parent e7145de68e
commit dbbcda638f
32 changed files with 4 additions and 2623 deletions

View File

@ -1,22 +1,18 @@
use crate::ast::NodeId;
use crate::source_range::SourceRange;
use crate::type_info::TypeInfo;
pub struct DoubleLiteral {
node_id: NodeId,
value: f64,
source_range: SourceRange,
type_info: &'static TypeInfo,
}
impl DoubleLiteral {
pub fn new(node_id: NodeId, value: f64, source_range: SourceRange) -> Self {
const TYPE_INFO: TypeInfo = TypeInfo::Double;
Self {
node_id,
value,
source_range,
type_info: &TYPE_INFO,
}
}
@ -28,10 +24,6 @@ impl DoubleLiteral {
self.value
}
pub fn type_info(&self) -> &TypeInfo {
&self.type_info
}
pub fn source_range(&self) -> &SourceRange {
&self.source_range
}

View File

@ -1,22 +1,18 @@
use crate::ast::NodeId;
use crate::source_range::SourceRange;
use crate::type_info::TypeInfo;
pub struct IntegerLiteral {
node_id: NodeId,
value: i32,
source_range: SourceRange,
type_info: &'static TypeInfo,
}
impl IntegerLiteral {
pub fn new(node_id: NodeId, value: i32, source_range: SourceRange) -> Self {
const TYPE_INFO: TypeInfo = TypeInfo::Integer;
Self {
node_id,
value,
source_range,
type_info: &TYPE_INFO,
}
}
@ -28,10 +24,6 @@ impl IntegerLiteral {
self.node_id
}
pub fn type_info(&self) -> &TypeInfo {
&self.type_info
}
pub fn source_range(&self) -> &SourceRange {
&self.source_range
}

View File

@ -1,22 +1,18 @@
use crate::ast::NodeId;
use crate::source_range::SourceRange;
use crate::type_info::TypeInfo;
pub struct StringLiteral {
node_id: NodeId,
content: String,
source_range: SourceRange,
type_info: &'static TypeInfo,
}
impl StringLiteral {
pub fn new(node_id: NodeId, content: &str, source_range: SourceRange) -> Self {
const TYPE_INFO: TypeInfo = TypeInfo::String;
Self {
node_id,
content: content.into(),
source_range,
type_info: &TYPE_INFO,
}
}
@ -28,10 +24,6 @@ impl StringLiteral {
&self.content
}
pub fn type_info(&self) -> &TypeInfo {
&self.type_info
}
pub fn source_range(&self) -> &SourceRange {
&self.source_range
}

View File

@ -1,15 +1,6 @@
use crate::diagnostic::{Diagnostic, SecondaryLabel};
use crate::error_codes::{
ASSIGN_LHS_IMMUTABLE, ASSIGN_MISMATCHED_TYPES, ASSIGN_NO_L_VALUE,
CANNOT_PROVIDE_GENERIC_ARGS_GENERIC_TYPE, CLASS_NO_CONSTRUCTOR, FIELD_NO_TYPE_OR_INIT,
MISMATCHED_TYPES, NOT_ASSIGNABLE, OUTER_CLASS_FIELD_USED_IN_INIT,
OUTER_CLASS_METHOD_USED_IN_INIT, RECEIVER_NOT_CALLABLE, SELF_CONSTRUCTOR_USED_IN_INIT,
SELF_FIELD_USED_IN_INIT, SELF_METHOD_USED_IN_INIT, SYMBOL_ALREADY_DECLARED, SYMBOL_NOT_FOUND,
UNARY_INCOMPATIBLE_TYPE, WRONG_NUMBER_OF_ARGUMENTS,
};
use crate::diagnostic::Diagnostic;
use crate::error_codes::SYMBOL_NOT_FOUND;
use crate::source_range::SourceRange;
use crate::symbol::Symbol;
use crate::type_info::TypeInfo;
pub fn symbol_not_found(name: &str, source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
@ -19,255 +10,3 @@ pub fn symbol_not_found(name: &str, source_range: &SourceRange) -> Diagnostic {
)
.with_error_code(SYMBOL_NOT_FOUND)
}
pub fn field_has_no_type_or_init(name: &str, source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
&format!("Field {} has no declared type nor initializer.", name),
source_range.start(),
source_range.end(),
)
.with_error_code(FIELD_NO_TYPE_OR_INIT)
.with_primary_label_message("Declare a type and/or an initializer.")
}
pub fn cannot_reference_field_in_init(name: &str, source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
&format!("Cannot reference field {} during initialization.", name),
source_range.start(),
source_range.end(),
)
.with_error_code(SELF_FIELD_USED_IN_INIT)
}
pub fn symbol_already_declared(already_inserted: &Symbol, would_insert: &Symbol) -> Diagnostic {
let secondary_label = if let Some(source_range) = already_inserted.declared_name_source_range()
{
Some(SecondaryLabel::new(
source_range.start(),
source_range.end(),
Some("Symbol already declared here.".to_string()),
))
} else {
None
};
let diagnostic = Diagnostic::new(
&format!(
"Symbol {} already declared in current scope.",
would_insert.declared_name()
),
would_insert.declared_name_source_range().unwrap().start(), // unwrap should be okay, since this is user code
would_insert.declared_name_source_range().unwrap().end(),
)
.with_error_code(SYMBOL_ALREADY_DECLARED);
if let Some(secondary_label) = secondary_label {
diagnostic.with_secondary_labels(&[secondary_label])
} else {
diagnostic
}
}
pub fn self_constructor_used_in_init(source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
"Cannot call Self constructor during initialization.",
source_range.start(),
source_range.end(),
)
.with_error_code(SELF_CONSTRUCTOR_USED_IN_INIT)
}
pub fn self_field_used_in_init(source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
"Cannot reference Self field during initialization.",
source_range.start(),
source_range.end(),
)
.with_error_code(SELF_FIELD_USED_IN_INIT)
}
pub fn self_method_used_in_init(source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
"Cannot call Self method during initialization.",
source_range.start(),
source_range.end(),
)
.with_error_code(SELF_METHOD_USED_IN_INIT)
}
pub fn outer_class_field_usage(source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
"Cannot reference an outer class member.",
source_range.start(),
source_range.end(),
)
.with_error_code(OUTER_CLASS_FIELD_USED_IN_INIT)
}
pub fn outer_class_method_usage(source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
"Cannot call an outer class method.",
source_range.start(),
source_range.end(),
)
.with_error_code(OUTER_CLASS_METHOD_USED_IN_INIT)
}
pub fn class_has_no_constructor(name: &str, source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
&format!("Class {} has no constructor.", name),
source_range.start(),
source_range.end(),
)
.with_error_code(CLASS_NO_CONSTRUCTOR)
}
pub fn not_assignable(name: &str, source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
&format!("Symbol {} is not assignable.", name),
source_range.start(),
source_range.end(),
)
.with_error_code(NOT_ASSIGNABLE)
}
pub fn cannot_reassign_immutable_field(source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
"Cannot reassign an immutable field.",
source_range.start(),
source_range.end(),
)
.with_error_code(ASSIGN_LHS_IMMUTABLE)
}
pub fn cannot_provide_generic_args_generic_type(source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
"Cannot provide generic arguments to an already generic type.",
source_range.start(),
source_range.end(),
)
.with_error_code(CANNOT_PROVIDE_GENERIC_ARGS_GENERIC_TYPE)
}
pub fn must_be_l_value(source_range: &SourceRange) -> Diagnostic {
Diagnostic::new(
"Left-hand side of assign mut be an L value",
source_range.start(),
source_range.end(),
)
.with_error_code(ASSIGN_NO_L_VALUE)
}
pub fn destination_must_be_mutable(
source_range: &SourceRange,
secondary_source_range: Option<&SourceRange>,
) -> Diagnostic {
let secondary_label = secondary_source_range.map(|sr| {
SecondaryLabel::new(
sr.start(),
sr.end(),
Some("Destination declared here is immutable".to_string()),
)
});
let mut diagnostic = Diagnostic::new(
"Destination is immutable and cannot be reassigned.",
source_range.start(),
source_range.end(),
)
.with_error_code(ASSIGN_LHS_IMMUTABLE);
if let Some(secondary_label) = secondary_label {
diagnostic = diagnostic.with_secondary_labels(&[secondary_label])
}
diagnostic
}
pub fn mismatched_assign_types(
rhs_type: &TypeInfo,
lhs_type: &TypeInfo,
source_range: &SourceRange,
secondary_source_range: Option<&SourceRange>,
) -> Diagnostic {
let secondary_label = secondary_source_range.map(|sr| {
SecondaryLabel::new(
sr.start(),
sr.end(),
Some(format!(
"Destination declared here is of type {}.",
lhs_type
)),
)
});
let mut diagnostic = Diagnostic::new(
&format!("Mismatched types: right-hand side of type {} is not assignable to left-hand side of type {}", rhs_type, lhs_type),
source_range.start(),
source_range.end(),
)
.with_error_code(ASSIGN_MISMATCHED_TYPES);
if let Some(secondary_label) = secondary_label {
diagnostic = diagnostic.with_secondary_labels(&[secondary_label])
}
diagnostic
}
pub fn receiver_not_callable(
receiver_type_info: &TypeInfo,
source_range: &SourceRange,
) -> Diagnostic {
Diagnostic::new(
&format!("Receiver of type {} is not callable.", receiver_type_info),
source_range.start(),
source_range.end(),
)
.with_error_code(RECEIVER_NOT_CALLABLE)
}
pub fn wrong_number_of_arguments(
source_range: &SourceRange,
found: usize,
expected: usize,
) -> Diagnostic {
Diagnostic::new(
&format!(
"Wrong number of arguments: expected {} but found {}",
expected, found
),
source_range.start(),
source_range.end(),
)
.with_error_code(WRONG_NUMBER_OF_ARGUMENTS)
}
pub fn mismatched_types(
expected_type_info: &TypeInfo,
found_type_info: &TypeInfo,
source_range: &SourceRange,
) -> Diagnostic {
Diagnostic::new(
&format!(
"Mismatched types; expected {} but found {}",
expected_type_info, found_type_info
),
source_range.start(),
source_range.end(),
)
.with_error_code(MISMATCHED_TYPES)
}
pub fn unary_incompatible_type(
source_range: &SourceRange,
operator_name: &str,
type_info: &TypeInfo,
) -> Diagnostic {
Diagnostic::new(
&format!("Cannot apply {} to {}", operator_name, type_info),
source_range.start(),
source_range.end(),
)
.with_error_code(UNARY_INCOMPATIBLE_TYPE)
}

View File

@ -1,6 +0,0 @@
use std::rc::Rc;
#[inline]
pub fn fqn_parts_to_string(parts: &[Rc<str>]) -> Rc<str> {
parts.join("::").into()
}

View File

@ -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);
}
}

View File

@ -1,7 +1,3 @@
use crate::fqn_util::fqn_parts_to_string;
use crate::type_info::TypeInfo;
use dvm_lib::vm::class::{Class, Field};
use dvm_lib::vm::type_info::TypeInfo as VmTypeInfo;
use std::rc::Rc;
pub struct IrClass {
@ -18,45 +14,18 @@ impl IrClass {
fields,
}
}
pub fn to_vm_class(&self) -> Class {
Class::new(
self.declared_name.clone(),
self.fqn.clone(),
self.fields.iter().map(IrField::to_vm_field).collect(),
)
}
}
pub struct IrField {
debug_name: Rc<str>,
field_index: usize,
type_info: TypeInfo,
}
impl IrField {
pub fn new(debug_name: Rc<str>, field_index: usize, type_info: TypeInfo) -> Self {
pub fn new(debug_name: Rc<str>, field_index: usize) -> Self {
Self {
debug_name,
field_index,
type_info,
}
}
pub fn to_vm_field(&self) -> Field {
Field::new(
self.debug_name.clone(),
self.field_index,
match &self.type_info {
TypeInfo::Integer => VmTypeInfo::Int,
TypeInfo::Double => VmTypeInfo::Double,
TypeInfo::String => VmTypeInfo::String,
TypeInfo::Class(class_symbol) => {
VmTypeInfo::ClassInstance(fqn_parts_to_string(class_symbol.fqn_parts()).into())
}
TypeInfo::GenericType(_) => VmTypeInfo::Any,
_ => panic!(),
},
)
}
}

View File

@ -17,23 +17,14 @@ pub mod ast;
pub mod constants_table;
pub mod diagnostic;
mod diagnostic_factories;
pub mod error_codes;
pub mod fqn_util;
pub mod intrinsics;
mod error_codes;
pub mod ir;
pub mod lexer;
pub mod lowering;
pub mod offset_counter;
pub mod parser;
pub mod scope;
pub mod semantic_analysis;
pub mod source_range;
pub mod symbol;
pub mod symbol_table;
pub mod token;
pub mod type_info;
pub mod types_table;
mod util;
pub type Filename = Rc<str>;
pub type FileId = usize;

View File

@ -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
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}
}
}

View File

@ -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)
}
}

View File

@ -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(),
}
}
}

View File

@ -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))
}
}

View File

@ -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);
}
}

View File

@ -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())
}
}
}
}

View File

@ -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);
}
}

View File

@ -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)
)
}
}

View File

@ -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);
}
}

View File

@ -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!(),
}
}
}

View File

@ -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);
}
}

View File

@ -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)
}
}
}
}

View File

@ -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
)
}
}

View File

@ -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,
}
}

View File

@ -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),
}
}
}

View File

@ -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)
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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),
}
};
}