core: Add primitive definition-id list

So that we have a single ground truth for the definition IDs of
primitive types.
pull/383/head
David Mak 2024-02-26 15:11:00 +08:00
parent 82fdb02d13
commit c3db6297d9
6 changed files with 119 additions and 55 deletions

View File

@ -6,7 +6,7 @@ use nac3core::{
CodeGenContext, CodeGenerator,
},
symbol_resolver::ValueEnum,
toplevel::{DefinitionId, GenCall},
toplevel::{DefinitionId, GenCall, helper::PRIMITIVE_DEF_IDS},
typecheck::typedef::{FunSignature, FuncArg, Type, TypeEnum}
};
@ -681,7 +681,7 @@ pub fn attributes_writeback(
vars: HashMap::default()
};
let args: Vec<_> = values.into_iter().map(|(_, val)| (None, ValueEnum::Dynamic(val))).collect();
if let Err(e) = rpc_codegen_callback_fn(ctx, None, (&fun, DefinitionId(0)), args, generator) {
if let Err(e) = rpc_codegen_callback_fn(ctx, None, (&fun, PRIMITIVE_DEF_IDS.int32), args, generator) {
return Ok(Err(e));
}
Ok(Ok(()))

View File

@ -8,6 +8,7 @@ use crate::{
stmt::exn_constructor,
},
symbol_resolver::SymbolValue,
toplevel::helper::PRIMITIVE_DEF_IDS,
toplevel::numpy::*,
};
use inkwell::{
@ -81,7 +82,7 @@ pub fn get_exn_constructor(
methods: vec![("__init__".into(), signature, DefinitionId(cons_id))],
ancestors: vec![
TypeAnnotation::CustomClass { id: DefinitionId(class_id), params: Vec::default() },
TypeAnnotation::CustomClass { id: DefinitionId(7), params: Vec::default() },
TypeAnnotation::CustomClass { id: PRIMITIVE_DEF_IDS.exception, params: Vec::default() },
],
constructor: Some(signature),
resolver: None,
@ -332,49 +333,49 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
};
let top_level_def_list = vec![
Arc::new(RwLock::new(TopLevelComposer::make_top_level_class_def(
0,
PRIMITIVE_DEF_IDS.int32,
None,
"int32".into(),
None,
None,
))),
Arc::new(RwLock::new(TopLevelComposer::make_top_level_class_def(
1,
PRIMITIVE_DEF_IDS.int64,
None,
"int64".into(),
None,
None,
))),
Arc::new(RwLock::new(TopLevelComposer::make_top_level_class_def(
2,
PRIMITIVE_DEF_IDS.float,
None,
"float".into(),
None,
None,
))),
Arc::new(RwLock::new(TopLevelComposer::make_top_level_class_def(
3,
PRIMITIVE_DEF_IDS.bool,
None,
"bool".into(),
None,
None,
))),
Arc::new(RwLock::new(TopLevelComposer::make_top_level_class_def(
4,
PRIMITIVE_DEF_IDS.none,
None,
"none".into(),
None,
None,
))),
Arc::new(RwLock::new(TopLevelComposer::make_top_level_class_def(
5,
PRIMITIVE_DEF_IDS.range,
None,
"range".into(),
None,
None,
))),
Arc::new(RwLock::new(TopLevelComposer::make_top_level_class_def(
6,
PRIMITIVE_DEF_IDS.str,
None,
"str".into(),
None,
@ -382,7 +383,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
))),
Arc::new(RwLock::new(TopLevelDef::Class {
name: "Exception".into(),
object_id: DefinitionId(7),
object_id: PRIMITIVE_DEF_IDS.exception,
type_vars: Vec::default(),
fields: exception_fields,
methods: Vec::default(),
@ -392,14 +393,14 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
loc: None,
})),
Arc::new(RwLock::new(TopLevelComposer::make_top_level_class_def(
8,
PRIMITIVE_DEF_IDS.uint32,
None,
"uint32".into(),
None,
None,
))),
Arc::new(RwLock::new(TopLevelComposer::make_top_level_class_def(
9,
PRIMITIVE_DEF_IDS.uint64,
None,
"uint64".into(),
None,
@ -408,7 +409,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
Arc::new(RwLock::new({
TopLevelDef::Class {
name: "Option".into(),
object_id: DefinitionId(10),
object_id: PRIMITIVE_DEF_IDS.option,
type_vars: vec![option_ty_var],
fields: vec![],
methods: vec![
@ -417,7 +418,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
("unwrap".into(), unwrap_ty.0, DefinitionId(13)),
],
ancestors: vec![TypeAnnotation::CustomClass {
id: DefinitionId(10),
id: PRIMITIVE_DEF_IDS.option,
params: Vec::default(),
}],
constructor: None,
@ -504,7 +505,7 @@ pub fn get_builtins(primitives: &mut (PrimitiveStore, Unifier)) -> BuiltinInfo {
Arc::new(RwLock::new(TopLevelDef::Class {
name: "ndarray".into(),
object_id: DefinitionId(14),
object_id: PRIMITIVE_DEF_IDS.ndarray,
type_vars: vec![tvar.0, ndims.0],
fields: Vec::default(),
methods: Vec::default(),

View File

@ -221,7 +221,7 @@ impl TopLevelComposer {
let constructor_ty = self.unifier.get_dummy_var().0;
let mut class_def_ast = (
Arc::new(RwLock::new(Self::make_top_level_class_def(
class_def_id,
DefinitionId(class_def_id),
resolver.clone(),
fully_qualified_class_name,
Some(constructor_ty),

View File

@ -5,6 +5,68 @@ use nac3parser::ast::{Constant, Location};
use super::*;
/// Structure storing [`DefinitionId`] for primitive types.
#[derive(Clone, Copy)]
pub struct PrimitiveDefinitionIds {
pub int32: DefinitionId,
pub int64: DefinitionId,
pub uint32: DefinitionId,
pub uint64: DefinitionId,
pub float: DefinitionId,
pub bool: DefinitionId,
pub none: DefinitionId,
pub range: DefinitionId,
pub str: DefinitionId,
pub exception: DefinitionId,
pub option: DefinitionId,
pub ndarray: DefinitionId,
}
impl PrimitiveDefinitionIds {
/// Returns all [`DefinitionId`] of primitives as a [`Vec`].
///
/// There are no guarantees on ordering of the IDs.
#[must_use]
fn as_vec(&self) -> Vec<DefinitionId> {
vec![
self.int32,
self.int64,
self.uint32,
self.uint64,
self.float,
self.bool,
self.none,
self.range,
self.str,
self.exception,
self.option,
self.ndarray,
]
}
/// Returns the primitive with the largest [`DefinitionId`].
#[must_use]
pub fn max_id(&self) -> DefinitionId {
self.as_vec().into_iter().max().unwrap()
}
}
/// The [definition IDs][DefinitionId] for primitive types.
pub const PRIMITIVE_DEF_IDS: PrimitiveDefinitionIds = PrimitiveDefinitionIds {
int32: DefinitionId(0),
int64: DefinitionId(1),
uint32: DefinitionId(8),
uint64: DefinitionId(9),
float: DefinitionId(2),
bool: DefinitionId(3),
none: DefinitionId(4),
range: DefinitionId(5),
str: DefinitionId(6),
exception: DefinitionId(7),
option: DefinitionId(10),
ndarray: DefinitionId(14),
};
impl TopLevelDef {
pub fn to_string(&self, unifier: &mut Unifier) -> String {
match self {
@ -47,42 +109,42 @@ impl TopLevelComposer {
pub fn make_primitives(size_t: u32) -> (PrimitiveStore, Unifier) {
let mut unifier = Unifier::new();
let int32 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(0),
obj_id: PRIMITIVE_DEF_IDS.int32,
fields: HashMap::new(),
params: HashMap::new(),
});
let int64 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(1),
obj_id: PRIMITIVE_DEF_IDS.int64,
fields: HashMap::new(),
params: HashMap::new(),
});
let float = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(2),
obj_id: PRIMITIVE_DEF_IDS.float,
fields: HashMap::new(),
params: HashMap::new(),
});
let bool = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(3),
obj_id: PRIMITIVE_DEF_IDS.bool,
fields: HashMap::new(),
params: HashMap::new(),
});
let none = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(4),
obj_id: PRIMITIVE_DEF_IDS.none,
fields: HashMap::new(),
params: HashMap::new(),
});
let range = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(5),
obj_id: PRIMITIVE_DEF_IDS.range,
fields: HashMap::new(),
params: HashMap::new(),
});
let str = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(6),
obj_id: PRIMITIVE_DEF_IDS.str,
fields: HashMap::new(),
params: HashMap::new(),
});
let exception = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(7),
obj_id: PRIMITIVE_DEF_IDS.exception,
fields: vec![
("__name__".into(), (int32, true)),
("__file__".into(), (str, true)),
@ -99,12 +161,12 @@ impl TopLevelComposer {
params: HashMap::new(),
});
let uint32 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(8),
obj_id: PRIMITIVE_DEF_IDS.uint32,
fields: HashMap::new(),
params: HashMap::new(),
});
let uint64 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(9),
obj_id: PRIMITIVE_DEF_IDS.uint64,
fields: HashMap::new(),
params: HashMap::new(),
});
@ -121,7 +183,7 @@ impl TopLevelComposer {
vars: HashMap::from([(option_type_var.1, option_type_var.0)]),
}));
let option = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(10),
obj_id: PRIMITIVE_DEF_IDS.option,
fields: vec![
("is_some".into(), (is_some_type_fun_ty, true)),
("is_none".into(), (is_some_type_fun_ty, true)),
@ -155,7 +217,7 @@ impl TopLevelComposer {
/// when first registering, the `type_vars`, fields, methods, ancestors are invalid
#[must_use]
pub fn make_top_level_class_def(
index: usize,
obj_id: DefinitionId,
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
name: StrRef,
constructor: Option<Type>,
@ -163,7 +225,7 @@ impl TopLevelComposer {
) -> TopLevelDef {
TopLevelDef::Class {
name,
object_id: DefinitionId(index),
object_id: obj_id,
type_vars: Vec::default(),
fields: Vec::default(),
methods: Vec::default(),

View File

@ -1,4 +1,5 @@
use crate::symbol_resolver::SymbolValue;
use crate::toplevel::helper::PRIMITIVE_DEF_IDS;
use super::*;
use nac3parser::ast::Constant;
@ -93,7 +94,7 @@ pub fn parse_ast_to_type_annotation_kinds<T>(
} else if id == &"str".into() {
Ok(TypeAnnotation::Primitive(primitives.str))
} else if id == &"Exception".into() {
Ok(TypeAnnotation::CustomClass { id: DefinitionId(7), params: Vec::default() })
Ok(TypeAnnotation::CustomClass { id: PRIMITIVE_DEF_IDS.exception, params: Vec::default() })
} else if let Ok(obj_id) = resolver.get_identifier_def(*id) {
let type_vars = {
let def_read = top_level_defs[obj_id.0].try_read();
@ -491,7 +492,7 @@ pub fn get_type_from_type_annotation_kinds(
(*name, (subst_ty, *mutability))
}));
let need_subst = !subst.is_empty();
let ty = if obj_id == &DefinitionId(14) {
let ty = if obj_id == &PRIMITIVE_DEF_IDS.ndarray {
assert_eq!(subst.len(), 2);
let tv_tys = subst.iter()
.sorted_by_key(|(k, _)| *k)

View File

@ -3,7 +3,7 @@ use super::*;
use crate::{
codegen::CodeGenContext,
symbol_resolver::ValueEnum,
toplevel::{DefinitionId, TopLevelDef},
toplevel::{DefinitionId, helper::PRIMITIVE_DEF_IDS, TopLevelDef},
};
use indoc::indoc;
use std::iter::zip;
@ -73,7 +73,7 @@ impl TestEnvironment {
let mut unifier = Unifier::new();
let int32 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(0),
obj_id: PRIMITIVE_DEF_IDS.int32,
fields: HashMap::new(),
params: HashMap::new(),
});
@ -86,52 +86,52 @@ impl TestEnvironment {
fields.insert("__add__".into(), (add_ty, false));
});
let int64 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(1),
obj_id: PRIMITIVE_DEF_IDS.int64,
fields: HashMap::new(),
params: HashMap::new(),
});
let float = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(2),
obj_id: PRIMITIVE_DEF_IDS.float,
fields: HashMap::new(),
params: HashMap::new(),
});
let bool = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(3),
obj_id: PRIMITIVE_DEF_IDS.bool,
fields: HashMap::new(),
params: HashMap::new(),
});
let none = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(4),
obj_id: PRIMITIVE_DEF_IDS.none,
fields: HashMap::new(),
params: HashMap::new(),
});
let range = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(5),
obj_id: PRIMITIVE_DEF_IDS.range,
fields: HashMap::new(),
params: HashMap::new(),
});
let str = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(6),
obj_id: PRIMITIVE_DEF_IDS.str,
fields: HashMap::new(),
params: HashMap::new(),
});
let exception = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(7),
obj_id: PRIMITIVE_DEF_IDS.exception,
fields: HashMap::new(),
params: HashMap::new(),
});
let uint32 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(8),
obj_id: PRIMITIVE_DEF_IDS.uint32,
fields: HashMap::new(),
params: HashMap::new(),
});
let uint64 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(9),
obj_id: PRIMITIVE_DEF_IDS.uint64,
fields: HashMap::new(),
params: HashMap::new(),
});
let option = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(10),
obj_id: PRIMITIVE_DEF_IDS.option,
fields: HashMap::new(),
params: HashMap::new(),
});
@ -200,7 +200,7 @@ impl TestEnvironment {
let mut identifier_mapping = HashMap::new();
let mut top_level_defs: Vec<Arc<RwLock<TopLevelDef>>> = Vec::new();
let int32 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(0),
obj_id: PRIMITIVE_DEF_IDS.int32,
fields: HashMap::new(),
params: HashMap::new(),
});
@ -213,52 +213,52 @@ impl TestEnvironment {
fields.insert("__add__".into(), (add_ty, false));
});
let int64 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(1),
obj_id: PRIMITIVE_DEF_IDS.int64,
fields: HashMap::new(),
params: HashMap::new(),
});
let float = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(2),
obj_id: PRIMITIVE_DEF_IDS.float,
fields: HashMap::new(),
params: HashMap::new(),
});
let bool = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(3),
obj_id: PRIMITIVE_DEF_IDS.bool,
fields: HashMap::new(),
params: HashMap::new(),
});
let none = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(4),
obj_id: PRIMITIVE_DEF_IDS.none,
fields: HashMap::new(),
params: HashMap::new(),
});
let range = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(5),
obj_id: PRIMITIVE_DEF_IDS.range,
fields: HashMap::new(),
params: HashMap::new(),
});
let str = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(6),
obj_id: PRIMITIVE_DEF_IDS.str,
fields: HashMap::new(),
params: HashMap::new(),
});
let exception = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(7),
obj_id: PRIMITIVE_DEF_IDS.exception,
fields: HashMap::new(),
params: HashMap::new(),
});
let uint32 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(8),
obj_id: PRIMITIVE_DEF_IDS.uint32,
fields: HashMap::new(),
params: HashMap::new(),
});
let uint64 = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(9),
obj_id: PRIMITIVE_DEF_IDS.uint64,
fields: HashMap::new(),
params: HashMap::new(),
});
let option = unifier.add_ty(TypeEnum::TObj {
obj_id: DefinitionId(10),
obj_id: PRIMITIVE_DEF_IDS.option,
fields: HashMap::new(),
params: HashMap::new(),
});