Compare commits

..

No commits in common. "689935b12add6ddcf6a399014850b0448ff58e8e" and "42a2f243b5c8d6336151ff7d9f8243664bdf2d01" have entirely different histories.

26 changed files with 240 additions and 278 deletions

35
Cargo.lock generated
View File

@ -126,9 +126,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.1.30"
version = "1.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945"
checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938"
dependencies = [
"shlex",
]
@ -141,9 +141,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "4.5.20"
version = "4.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615"
dependencies = [
"clap_builder",
"clap_derive",
@ -151,9 +151,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.20"
version = "4.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b"
dependencies = [
"anstream",
"anstyle",
@ -547,9 +547,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.161"
version = "0.2.159"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
[[package]]
name = "libloading"
@ -698,9 +698,12 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
[[package]]
name = "once_cell"
version = "1.20.2"
version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1"
dependencies = [
"portable-atomic",
]
[[package]]
name = "parking_lot"
@ -825,9 +828,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "proc-macro2"
version = "1.0.88"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9"
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
@ -1014,9 +1017,9 @@ dependencies = [
[[package]]
name = "rustversion"
version = "1.0.18"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
[[package]]
name = "ryu"
@ -1067,9 +1070,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.129"
version = "1.0.128"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dbcf9b78a125ee667ae19388837dd12294b858d101fdd393cb9d5501ef09eb2"
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
dependencies = [
"itoa",
"memchr",

View File

@ -37,7 +37,7 @@ use nac3core::{
typecheck::typedef::{iter_type_vars, FunSignature, FuncArg, Type, TypeEnum, VarMap},
};
use super::{symbol_resolver::InnerResolver, timeline::TimeFns};
use crate::{symbol_resolver::InnerResolver, timeline::TimeFns};
/// The parallelism mode within a block.
#[derive(Copy, Clone, Eq, PartialEq)]

View File

@ -65,11 +65,13 @@ use nac3core::{
};
use nac3ld::Linker;
use codegen::{
use crate::{
codegen::{
attributes_writeback, gen_core_log, gen_rtio_log, rpc_codegen_callback, ArtiqCodeGenerator,
},
symbol_resolver::{DeferredEvaluationStore, InnerResolver, PythonHelper, Resolver},
timeline::TimeFns,
};
use symbol_resolver::{DeferredEvaluationStore, InnerResolver, PythonHelper, Resolver};
use timeline::TimeFns;
mod codegen;
mod symbol_resolver;

View File

@ -37,7 +37,7 @@ use nac3core::{
},
};
use super::PrimitivePythonId;
use crate::PrimitivePythonId;
pub enum PrimitiveValue {
I32(i32),

View File

@ -5,7 +5,8 @@ use inkwell::{
};
use itertools::Itertools;
use super::{
use crate::{
codegen::{
classes::{
ArrayLikeValue, NDArrayValue, ProxyValue, RangeValue, TypedArrayLikeAccessor,
UntypedArrayLikeAccessor, UntypedArrayLikeMutator,
@ -19,9 +20,9 @@ use super::{
numpy::ndarray_elementwise_unaryop_impl,
stmt::gen_for_callback_incrementing,
CodeGenContext, CodeGenerator,
};
use crate::{
toplevel::{helper::PrimDef, numpy::unpack_ndarray_var_tys},
},
toplevel::helper::PrimDef,
toplevel::numpy::unpack_ndarray_var_tys,
typecheck::typedef::{Type, TypeEnum},
};

View File

@ -5,7 +5,7 @@ use inkwell::{
AddressSpace, IntPredicate,
};
use super::{
use crate::codegen::{
irrt::{call_ndarray_calc_size, call_ndarray_flatten_index},
llvm_intrinsics::call_int_umin,
stmt::gen_for_callback_incrementing,

View File

@ -18,10 +18,11 @@ use nac3parser::ast::{
Unaryop,
};
use super::{
use crate::{
codegen::{
classes::{
ArrayLikeIndexer, ArrayLikeValue, ListType, ListValue, NDArrayValue, ProxyType, ProxyValue,
RangeValue, TypedArrayLikeAccessor, UntypedArrayLikeAccessor,
ArrayLikeIndexer, ArrayLikeValue, ListType, ListValue, NDArrayValue, ProxyType,
ProxyValue, RangeValue, TypedArrayLikeAccessor, UntypedArrayLikeAccessor,
},
concrete_type::{ConcreteFuncArg, ConcreteTypeEnum, ConcreteTypeStore},
gen_in_range_check, get_llvm_abi_type, get_llvm_type, get_va_count_arg_name,
@ -37,8 +38,7 @@ use super::{
gen_var,
},
CodeGenContext, CodeGenTask, CodeGenerator,
};
use crate::{
},
symbol_resolver::{SymbolValue, ValueEnum},
toplevel::{
helper::PrimDef,
@ -1777,12 +1777,7 @@ pub fn gen_unaryop_expr_with_values<'ctx, G: CodeGenerator>(
ast::Unaryop::Invert => ctx.builder.build_not(val, "not").map(Into::into).unwrap(),
ast::Unaryop::Not => ctx
.builder
.build_int_compare(
inkwell::IntPredicate::EQ,
val,
val.get_type().const_zero(),
"not",
)
.build_xor(val, val.get_type().const_all_ones(), "not")
.map(Into::into)
.unwrap(),
ast::Unaryop::UAdd => val.into(),
@ -2891,31 +2886,7 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
Some((_, Some(static_value), _)) => ValueEnum::Static(static_value.clone()),
None => {
let resolver = ctx.resolver.clone();
let value = resolver.get_symbol_value(*id, ctx, generator).unwrap();
let globals = ctx
.top_level
.definitions
.read()
.iter()
.filter_map(|def| {
if let TopLevelDef::Variable { simple_name, ty, .. } = &*def.read() {
Some((*simple_name, *ty))
} else {
None
}
})
.collect_vec();
if let Some((_, ty)) = globals.iter().find(|(name, _)| name == id) {
let ptr = value
.to_basic_value_enum(ctx, generator, *ty)
.map(BasicValueEnum::into_pointer_value)?;
ctx.builder.build_load(ptr, id.to_string().as_str()).map(Into::into).unwrap()
} else {
value
}
resolver.get_symbol_value(*id, ctx, generator).unwrap()
}
},
ExprKind::List { elts, .. } => {

View File

@ -4,7 +4,7 @@ use inkwell::{
};
use itertools::Either;
use super::CodeGenContext;
use crate::codegen::CodeGenContext;
/// Macro to generate extern function
/// Both function return type and function parameter type are `FloatValue`

View File

@ -6,8 +6,8 @@ use inkwell::{
use nac3parser::ast::{Expr, Stmt, StrRef};
use super::{bool_to_i1, bool_to_i8, classes::ArraySliceValue, expr::*, stmt::*, CodeGenContext};
use crate::{
codegen::{bool_to_i1, bool_to_i8, classes::ArraySliceValue, expr::*, stmt::*, CodeGenContext},
symbol_resolver::ValueEnum,
toplevel::{DefinitionId, TopLevelDef},
typecheck::typedef::{FunSignature, Type},

View File

@ -7,7 +7,7 @@ use inkwell::{
};
use itertools::Either;
use super::CodeGenContext;
use crate::codegen::CodeGenContext;
/// Returns the string representation for the floating-point type `ft` when used in intrinsic
/// functions.

View File

@ -29,6 +29,7 @@ use parking_lot::{Condvar, Mutex};
use nac3parser::ast::{Location, Stmt, StrRef};
use crate::{
codegen::classes::{ListType, NDArrayType, ProxyType, RangeType},
symbol_resolver::{StaticValue, SymbolResolver},
toplevel::{helper::PrimDef, numpy::unpack_ndarray_var_tys, TopLevelContext, TopLevelDef},
typecheck::{
@ -36,9 +37,6 @@ use crate::{
typedef::{CallId, FuncArg, Type, TypeEnum, Unifier},
},
};
use classes::{ListType, NDArrayType, ProxyType, RangeType};
use concrete_type::{ConcreteType, ConcreteTypeEnum, ConcreteTypeStore};
pub use generator::{CodeGenerator, DefaultCodeGenerator};
pub mod builtin_fns;
pub mod classes;
@ -54,6 +52,9 @@ pub mod stmt;
#[cfg(test)]
mod test;
use concrete_type::{ConcreteType, ConcreteTypeEnum, ConcreteTypeStore};
pub use generator::{CodeGenerator, DefaultCodeGenerator};
mod macros {
/// Codegen-variant of [`std::unreachable`] which accepts an instance of [`CodeGenContext`] as
/// its first argument to provide Python source information to indicate the codegen location

View File

@ -6,7 +6,8 @@ use inkwell::{
use nac3parser::ast::{Operator, StrRef};
use super::{
use crate::{
codegen::{
classes::{
ArrayLikeIndexer, ArrayLikeValue, ListType, ListValue, NDArrayType, NDArrayValue,
ProxyType, ProxyValue, TypedArrayLikeAccessor, TypedArrayLikeAdapter,
@ -15,14 +16,14 @@ use super::{
expr::gen_binop_expr_with_values,
irrt::{
calculate_len_for_slice_range, call_ndarray_calc_broadcast,
call_ndarray_calc_broadcast_index, call_ndarray_calc_nd_indices, call_ndarray_calc_size,
call_ndarray_calc_broadcast_index, call_ndarray_calc_nd_indices,
call_ndarray_calc_size,
},
llvm_intrinsics::{self, call_memcpy_generic},
macros::codegen_unreachable,
stmt::{gen_for_callback_incrementing, gen_for_range_callback, gen_if_else_expr_callback},
CodeGenContext, CodeGenerator,
};
use crate::{
},
symbol_resolver::ValueEnum,
toplevel::{
helper::PrimDef,

View File

@ -15,13 +15,13 @@ use nac3parser::{
};
use parking_lot::RwLock;
use super::{
use crate::{
codegen::{
classes::{ListType, NDArrayType, ProxyType, RangeType},
concrete_type::ConcreteTypeStore,
CodeGenContext, CodeGenLLVMOptions, CodeGenTargetMachineOptions, CodeGenTask, CodeGenerator,
DefaultCodeGenerator, WithCall, WorkerRegistry,
};
use crate::{
CodeGenContext, CodeGenLLVMOptions, CodeGenTargetMachineOptions, CodeGenTask,
CodeGenerator, DefaultCodeGenerator, WithCall, WorkerRegistry,
},
symbol_resolver::{SymbolResolver, ValueEnum},
toplevel::{
composer::{ComposerConfig, TopLevelComposer},

View File

@ -11,8 +11,7 @@ use itertools::Either;
use strum::IntoEnumIterator;
use super::{
helper::{debug_assert_prim_is_allowed, make_exception_fields, PrimDef, PrimDefDetails},
numpy::make_ndarray_ty,
helper::{debug_assert_prim_is_allowed, make_exception_fields, PrimDefDetails},
*,
};
use crate::{
@ -23,6 +22,7 @@ use crate::{
stmt::exn_constructor,
},
symbol_resolver::SymbolValue,
toplevel::{helper::PrimDef, numpy::make_ndarray_ty},
typecheck::typedef::{into_var_map, iter_type_vars, TypeVar, VarMap},
};

View File

@ -1,6 +1,6 @@
use std::rc::Rc;
use nac3parser::ast::{fold::Fold, ExprKind, Ident};
use nac3parser::ast::{fold::Fold, ExprKind};
use super::*;
use crate::{
@ -382,66 +382,32 @@ impl TopLevelComposer {
))
}
ast::StmtKind::Assign { .. } => {
// Assignment statements can assign to (and therefore create) more than one
// variable, but this function only allows returning one set of symbol information.
// We want to avoid changing this to return a `Vec` of symbol info, as this would
// require `iter().next().unwrap()` on every variable created from a non-Assign
// statement.
//
// Make callers use `register_top_level_var` instead, as it provides more
// fine-grained control over which symbols to register, while also simplifying the
// usage of this function.
panic!("Registration of top-level Assign statements must use TopLevelComposer::register_top_level_var (at {})", ast.location);
}
ast::StmtKind::AnnAssign { target, annotation, .. } => {
let ExprKind::Name { id: name, .. } = target.node else {
return Err(format!(
"global variable declaration must be an identifier (at {})",
target.location
ast.location
));
};
self.register_top_level_var(
name,
Some(annotation.as_ref().clone()),
resolver,
mod_path,
target.location,
)
}
_ => Err(format!(
"registrations of constructs other than top level classes/functions/variables are not supported (at {})",
ast.location
)),
}
}
/// Registers a top-level variable with the given `name` into the composer.
///
/// `annotation` - The type annotation of the top-level variable, or [`None`] if no type
/// annotation is provided.
/// `location` - The location of the top-level variable.
pub fn register_top_level_var(
&mut self,
name: Ident,
annotation: Option<Expr>,
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
mod_path: &str,
location: Location,
) -> Result<(StrRef, DefinitionId, Option<Type>), String> {
if self.keyword_list.contains(&name) {
return Err(format!("cannot use keyword `{name}` as a class name (at {location})"));
return Err(format!(
"cannot use keyword `{}` as a class name (at {})",
name,
ast.location
));
}
let global_var_name =
if mod_path.is_empty() { name.to_string() } else { format!("{mod_path}.{name}") };
if !self.defined_names.insert(global_var_name.clone()) {
let global_var_name = if mod_path.is_empty() {
name.to_string()
} else {
format!("{mod_path}.{name}")
};
if !defined_names.insert(global_var_name.clone()) {
return Err(format!(
"global variable `{global_var_name}` defined twice (at {location})"
"global variable `{}` defined twice (at {})",
global_var_name,
ast.location
));
}
@ -452,15 +418,25 @@ impl TopLevelComposer {
name,
// dummy here, unify with correct type later,
ty_to_be_unified,
annotation,
*(annotation.clone()),
resolver,
Some(location),
))
.into(),
Some(ast.location),
)).into(),
None,
));
Ok((name, DefinitionId(self.definition_ast_list.len() - 1), Some(ty_to_be_unified)))
Ok((
name,
DefinitionId(self.definition_ast_list.len() - 1),
Some(ty_to_be_unified),
))
}
_ => Err(format!(
"registrations of constructs other than top level classes/functions/variables are not supported (at {})",
ast.location
)),
}
}
pub fn start_analysis(&mut self, inference: bool) -> Result<(), HashSet<String>> {
@ -2273,8 +2249,9 @@ impl TopLevelComposer {
let primitives_store = &self.primitives_ty;
let mut analyze = |variable_def: &Arc<RwLock<TopLevelDef>>| -> Result<_, HashSet<String>> {
let TopLevelDef::Variable { ty: dummy_ty, ty_decl, resolver, loc, .. } =
&*variable_def.read()
let variable_def = &mut *variable_def.write();
let TopLevelDef::Variable { ty: dummy_ty, ty_decl, resolver, loc, .. } = variable_def
else {
// not top level variable def, skip
return Ok(());
@ -2282,7 +2259,6 @@ impl TopLevelComposer {
let resolver = &**resolver.as_ref().unwrap();
if let Some(ty_decl) = ty_decl {
let ty_annotation = parse_ast_to_type_annotation_kinds(
resolver,
&temp_def_list,
@ -2302,8 +2278,6 @@ impl TopLevelComposer {
unifier.unify(*dummy_ty, ty_from_ty_annotation).map_err(|e| {
HashSet::from([e.at(Some(loc.unwrap())).to_display(unifier).to_string()])
})?;
}
Ok(())
};

View File

@ -3,11 +3,13 @@ use std::convert::TryInto;
use strum::IntoEnumIterator;
use strum_macros::EnumIter;
use nac3parser::ast::{Constant, ExprKind, Location};
use ast::ExprKind;
use nac3parser::ast::{Constant, Location};
use super::{numpy::unpack_ndarray_var_tys, *};
use super::*;
use crate::{
symbol_resolver::SymbolValue,
toplevel::numpy::unpack_ndarray_var_tys,
typecheck::typedef::{into_var_map, iter_type_vars, Mapping, TypeVarId, VarMap},
};
@ -598,7 +600,7 @@ impl TopLevelComposer {
name: String,
simple_name: StrRef,
ty: Type,
ty_decl: Option<Expr>,
ty_decl: Expr,
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
loc: Option<Location>,
) -> TopLevelDef {

View File

@ -23,19 +23,19 @@ use crate::{
},
},
};
use composer::*;
use type_annotation::*;
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)]
pub struct DefinitionId(pub usize);
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;
pub mod type_annotation;
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)]
pub struct DefinitionId(pub usize);
type GenCallCallback = dyn for<'ctx, 'a> Fn(
&mut CodeGenContext<'ctx, 'a>,
@ -158,8 +158,8 @@ pub enum TopLevelDef {
/// Type of the global variable.
ty: Type,
/// The declared type of the global variable, or [`None`] if no type annotation is provided.
ty_decl: Option<Expr>,
/// The declared type of the global variable.
ty_decl: Expr,
/// Symbol resolver of the module defined the class.
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,

View File

@ -1,9 +1,11 @@
use itertools::Itertools;
use super::helper::PrimDef;
use crate::typecheck::{
use crate::{
toplevel::helper::PrimDef,
typecheck::{
type_inferencer::PrimitiveStore,
typedef::{Type, TypeEnum, TypeVarId, Unifier, VarMap},
},
};
/// Creates a `ndarray` [`Type`] with the given type arguments.

View File

@ -9,10 +9,11 @@ use nac3parser::{
parser::parse_program,
};
use super::{helper::PrimDef, DefinitionId, *};
use super::*;
use crate::{
codegen::CodeGenContext,
symbol_resolver::{SymbolResolver, ValueEnum},
toplevel::{helper::PrimDef, DefinitionId},
typecheck::{
type_inferencer::PrimitiveStore,
typedef::{into_var_map, Type, Unifier},

View File

@ -2,11 +2,12 @@ use strum::IntoEnumIterator;
use nac3parser::ast::Constant;
use super::{
helper::{PrimDef, PrimDefDetails},
*,
use super::*;
use crate::{
symbol_resolver::SymbolValue,
toplevel::helper::{PrimDef, PrimDefDetails},
typecheck::typedef::VarMap,
};
use crate::{symbol_resolver::SymbolValue, typecheck::typedef::VarMap};
#[derive(Clone, Debug)]
pub enum TypeAnnotation {

View File

@ -36,7 +36,7 @@ impl<'a> Inferencer<'a> {
ExprKind::Name { id, .. } => {
// If `id` refers to a declared symbol, reject this assignment if it is used in the
// context of an (implicit) global variable
if let Some(id_info) = defined_identifiers.get(id) {
if let Some(id_info) = self.defined_identifiers.get(id) {
if matches!(
id_info.source,
DeclarationSource::Global { is_explicit: Some(false) }

View File

@ -5,16 +5,16 @@ use strum::IntoEnumIterator;
use nac3parser::ast::{Cmpop, Operator, StrRef, Unaryop};
use super::{
type_inferencer::*,
typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier, VarMap},
};
use crate::{
symbol_resolver::SymbolValue,
toplevel::{
helper::PrimDef,
numpy::{make_ndarray_ty, unpack_ndarray_var_tys},
},
typecheck::{
type_inferencer::*,
typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier, VarMap},
},
};
/// The variant of a binary operator.

View File

@ -5,9 +5,10 @@ use itertools::Itertools;
use nac3parser::ast::{Cmpop, Location, StrRef};
use super::{
magic_methods::{Binop, HasOpInfo},
typedef::{RecordKey, Type, TypeEnum, Unifier},
magic_methods::Binop,
typedef::{RecordKey, Type, Unifier},
};
use crate::typecheck::{magic_methods::HasOpInfo, typedef::TypeEnum};
#[derive(Debug, Clone)]
pub enum TypeErrorKind {

View File

@ -14,14 +14,14 @@ use itertools::{repeat_n, Itertools};
use nac3parser::ast::{Cmpop, Location, StrRef, Unaryop};
use super::{
magic_methods::{Binop, HasOpInfo, OpInfo},
magic_methods::{Binop, HasOpInfo},
type_error::{TypeError, TypeErrorKind},
type_inferencer::PrimitiveStore,
unification_table::{UnificationKey, UnificationTable},
};
use crate::{
symbol_resolver::SymbolValue,
toplevel::{helper::PrimDef, DefinitionId, TopLevelContext, TopLevelDef},
typecheck::{magic_methods::OpInfo, type_inferencer::PrimitiveStore},
};
#[cfg(test)]

View File

@ -7,7 +7,7 @@ def output_int64(x: int64):
...
X: int32 = 0
Y = int64(1)
Y: int64 = int64(1)
def f():
global X, Y

View File

@ -45,9 +45,8 @@ use nac3core::{
},
};
use basic_symbol_resolver::*;
mod basic_symbol_resolver;
use basic_symbol_resolver::*;
/// Command-line argument parser definition.
#[derive(Parser)]
@ -175,49 +174,46 @@ fn handle_typevar_definition(
fn handle_assignment_pattern(
targets: &[Expr],
value: &Expr,
resolver: Arc<dyn SymbolResolver + Send + Sync>,
resolver: &(dyn SymbolResolver + Send + Sync),
internal_resolver: &ResolverInternal,
composer: &mut TopLevelComposer,
def_list: &[Arc<RwLock<TopLevelDef>>],
unifier: &mut Unifier,
primitives: &PrimitiveStore,
) -> Result<(), String> {
if targets.len() == 1 {
let target = &targets[0];
match &target.node {
match &targets[0].node {
ExprKind::Name { id, .. } => {
let def_list = composer.extract_def_list();
let unifier = &mut composer.unifier;
let primitives = &composer.primitives_ty;
if let Ok(var) =
handle_typevar_definition(value, &*resolver, &def_list, unifier, primitives)
handle_typevar_definition(value, resolver, def_list, unifier, primitives)
{
internal_resolver.add_id_type(*id, var);
Ok(())
} else if let Ok(val) = parse_parameter_default_value(value, &*resolver) {
} else if let Ok(val) = parse_parameter_default_value(value, resolver) {
internal_resolver.add_module_global(*id, val);
let (name, def_id, _) = composer
.register_top_level_var(
*id,
None,
Some(resolver.clone()),
"__main__",
target.location,
)
.unwrap();
internal_resolver.add_id_def(name, def_id);
Ok(())
} else {
Err(format!("fails to evaluate this expression `{:?}` as a constant or generic parameter at {}",
target.node,
target.location,
targets[0].node,
targets[0].location,
))
}
}
ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => {
handle_assignment_pattern(elts, value, resolver, internal_resolver, composer)?;
handle_assignment_pattern(
elts,
value,
resolver,
internal_resolver,
def_list,
unifier,
primitives,
)?;
Ok(())
}
_ => Err(format!("assignment to {target:?} is not supported at {}", target.location)),
_ => Err(format!(
"assignment to {:?} is not supported at {}",
targets[0], targets[0].location
)),
}
} else {
match &value.node {
@ -227,9 +223,11 @@ fn handle_assignment_pattern(
handle_assignment_pattern(
std::slice::from_ref(tar),
val,
resolver.clone(),
resolver,
internal_resolver,
composer,
def_list,
unifier,
primitives,
)?;
}
Ok(())
@ -250,9 +248,8 @@ fn handle_assignment_pattern(
fn handle_global_var(
target: &Expr,
value: Option<&Expr>,
resolver: &Arc<dyn SymbolResolver + Send + Sync>,
resolver: &(dyn SymbolResolver + Send + Sync),
internal_resolver: &ResolverInternal,
composer: &mut TopLevelComposer,
) -> Result<(), String> {
let ExprKind::Name { id, .. } = target.node else {
return Err(format!(
@ -265,12 +262,8 @@ fn handle_global_var(
return Err(format!("global variable `{id}` must be initialized in its definition"));
};
if let Ok(val) = parse_parameter_default_value(value, &**resolver) {
if let Ok(val) = parse_parameter_default_value(value, resolver) {
internal_resolver.add_module_global(id, val);
let (name, def_id, _) = composer
.register_top_level_var(id, None, Some(resolver.clone()), "__main__", target.location)
.unwrap();
internal_resolver.add_id_def(name, def_id);
Ok(())
} else {
Err(format!(
@ -362,12 +355,17 @@ fn main() {
for stmt in parser_result {
match &stmt.node {
StmtKind::Assign { targets, value, .. } => {
let def_list = composer.extract_def_list();
let unifier = &mut composer.unifier;
let primitives = &composer.primitives_ty;
if let Err(err) = handle_assignment_pattern(
targets,
value,
resolver.clone(),
resolver.as_ref(),
internal_resolver.as_ref(),
&mut composer,
&def_list,
unifier,
primitives,
) {
panic!("{err}");
}
@ -377,12 +375,16 @@ fn main() {
if let Err(err) = handle_global_var(
target,
value.as_ref().map(Box::as_ref),
&resolver,
resolver.as_ref(),
internal_resolver.as_ref(),
&mut composer,
) {
panic!("{err}");
}
let (name, def_id, _) = composer
.register_top_level(stmt, Some(resolver.clone()), "__main__", true)
.unwrap();
internal_resolver.add_id_def(name, def_id);
}
// allow (and ignore) "from __future__ import annotations"