nac3/nac3core/src/toplevel/mod.rs

158 lines
4.9 KiB
Rust
Raw Normal View History

2021-09-08 19:45:36 +08:00
use std::{
borrow::BorrowMut,
collections::{HashMap, HashSet},
fmt::Debug,
iter::FromIterator,
sync::Arc,
};
2021-08-03 13:38:27 +08:00
use inkwell::values::BasicValueEnum;
use itertools::Itertools;
use parking_lot::RwLock;
use nac3parser::ast::{self, Location, Stmt, StrRef};
use crate::{
codegen::{CodeGenContext, CodeGenerator},
symbol_resolver::{SymbolResolver, ValueEnum},
typecheck::{
type_inferencer::{CodeLocation, PrimitiveStore},
typedef::{
CallId, FunSignature, FuncArg, SharedUnifier, Type, TypeEnum, TypeVarId, Unifier,
VarMap,
},
},
};
2021-08-03 13:38:27 +08:00
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)]
pub struct DefinitionId(pub usize);
2021-08-23 02:52:54 +08:00
pub mod builtins;
pub mod composer;
pub mod helper;
pub mod numpy;
pub mod type_annotation;
use composer::*;
use type_annotation::*;
#[cfg(test)]
mod test;
2021-08-23 02:52:54 +08:00
2024-06-12 14:45:03 +08:00
type GenCallCallback = dyn for<'ctx, 'a> Fn(
&mut CodeGenContext<'ctx, 'a>,
Option<(Type, ValueEnum<'ctx>)>,
(&FunSignature, DefinitionId),
Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
&mut dyn CodeGenerator,
) -> Result<Option<BasicValueEnum<'ctx>>, String>
+ Send
+ Sync;
2021-09-30 17:07:48 +08:00
pub struct GenCall {
fp: Box<GenCallCallback>,
2021-09-30 17:07:48 +08:00
}
impl GenCall {
2023-12-08 17:43:32 +08:00
#[must_use]
pub fn new(fp: Box<GenCallCallback>) -> GenCall {
2021-09-30 17:07:48 +08:00
GenCall { fp }
}
2024-06-12 14:45:03 +08:00
/// Creates a dummy instance of [`GenCall`], which invokes [`unreachable!()`] with the given
/// `reason`.
#[must_use]
pub fn create_dummy(reason: String) -> GenCall {
Self::new(Box::new(move |_, _, _, _, _| unreachable!("{reason}")))
}
2023-12-06 11:49:02 +08:00
pub fn run<'ctx>(
2021-09-30 17:07:48 +08:00
&self,
2023-12-06 11:49:02 +08:00
ctx: &mut CodeGenContext<'ctx, '_>,
obj: Option<(Type, ValueEnum<'ctx>)>,
2021-09-30 17:07:48 +08:00
fun: (&FunSignature, DefinitionId),
args: Vec<(Option<StrRef>, ValueEnum<'ctx>)>,
generator: &mut dyn CodeGenerator,
) -> Result<Option<BasicValueEnum<'ctx>>, String> {
(self.fp)(ctx, obj, fun, args, generator)
2021-09-30 17:07:48 +08:00
}
}
impl Debug for GenCall {
fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
Ok(())
}
}
#[derive(Clone, Debug)]
pub struct FunInstance {
2021-09-22 16:04:25 +08:00
pub body: Arc<Vec<Stmt<Option<Type>>>>,
pub calls: Arc<HashMap<CodeLocation, CallId>>,
pub subst: VarMap,
pub unifier_id: usize,
}
#[derive(Debug, Clone)]
2021-08-03 13:38:27 +08:00
pub enum TopLevelDef {
Class {
/// Name for error messages and symbols.
2021-09-22 17:19:27 +08:00
name: StrRef,
2024-06-21 14:14:01 +08:00
/// Object ID used for [`TypeEnum`].
object_id: DefinitionId,
2021-08-27 01:39:15 +08:00
/// type variables bounded to the class.
type_vars: Vec<Type>,
/// Class fields.
///
/// Name and type is mutable.
fields: Vec<(StrRef, Type, bool)>,
/// Class Attributes.
///
/// Name, type, value.
attributes: Vec<(StrRef, Type, ast::Constant)>,
/// Class methods, pointing to the corresponding function definition.
2021-09-22 17:19:27 +08:00
methods: Vec<(StrRef, Type, DefinitionId)>,
/// Ancestor classes, including itself.
2021-08-23 02:52:54 +08:00
ancestors: Vec<TypeAnnotation>,
/// Symbol resolver of the module defined the class; [None] if it is built-in type.
2021-10-16 18:08:13 +08:00
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
/// Constructor type.
2021-09-19 22:54:06 +08:00
constructor: Option<Type>,
/// Definition location.
loc: Option<Location>,
2021-08-03 13:38:27 +08:00
},
Function {
/// Prefix for symbol, should be unique globally.
2021-08-07 15:06:39 +08:00
name: String,
/// Simple name, the same as in method/function definition.
2021-09-22 17:19:27 +08:00
simple_name: StrRef,
/// Function signature.
2021-08-03 13:38:27 +08:00
signature: Type,
/// Instantiated type variable IDs.
var_id: Vec<TypeVarId>,
2021-08-03 13:38:27 +08:00
/// Function instance to symbol mapping
///
/// * Key: String representation of type variable values, sorted by variable ID in ascending
2024-08-21 11:10:52 +08:00
/// order, including type variables associated with the class.
/// * Value: Function symbol name.
2021-08-03 13:38:27 +08:00
instance_to_symbol: HashMap<String, String>,
/// Function instances to annotated AST mapping
///
/// * Key: String representation of type variable values, sorted by variable ID in ascending
2024-08-21 11:10:52 +08:00
/// order, including type variables associated with the class. Excluding rigid type
/// variables.
///
/// Rigid type variables that would be substituted when the function is instantiated.
instance_to_stmt: HashMap<String, FunInstance>,
/// Symbol resolver of the module defined the class.
2021-10-16 18:08:13 +08:00
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
/// Custom code generation callback.
codegen_callback: Option<Arc<GenCall>>,
/// Definition location.
loc: Option<Location>,
2021-08-03 13:38:27 +08:00
},
}
pub struct TopLevelContext {
pub definitions: Arc<RwLock<Vec<Arc<RwLock<TopLevelDef>>>>>,
2021-08-11 14:37:26 +08:00
pub unifiers: Arc<RwLock<Vec<(SharedUnifier, PrimitiveStore)>>>,
pub personality_symbol: Option<String>,
}