forked from M-Labs/nac3
Compare commits
10 Commits
42a2f243b5
...
689935b12a
Author | SHA1 | Date |
---|---|---|
occheung | 689935b12a | |
David Mak | b6e2644391 | |
David Mak | 45cd01556b | |
David Mak | b6cd2a6993 | |
David Mak | a98f33e6d1 | |
David Mak | 5839badadd | |
David Mak | 56c845aac4 | |
David Mak | 65a12d9ab3 | |
David Mak | 9c6685fa8f | |
David Mak | 2bb788e4bb |
|
@ -126,9 +126,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.1.24"
|
version = "1.1.30"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938"
|
checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"shlex",
|
"shlex",
|
||||||
]
|
]
|
||||||
|
@ -141,9 +141,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.19"
|
version = "4.5.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7be5744db7978a28d9df86a214130d106a89ce49644cbc4e3f0c22c3fba30615"
|
checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
|
@ -151,9 +151,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.19"
|
version = "4.5.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a5fbc17d3ef8278f55b282b2a2e75ae6f6c7d4bb70ed3d0382375104bfafdb4b"
|
checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
|
@ -547,9 +547,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.159"
|
version = "0.2.161"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libloading"
|
name = "libloading"
|
||||||
|
@ -698,12 +698,9 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.20.1"
|
version = "1.20.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1"
|
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||||
dependencies = [
|
|
||||||
"portable-atomic",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
|
@ -828,9 +825,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.86"
|
version = "1.0.88"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
@ -1017,9 +1014,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.17"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
|
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
|
@ -1070,9 +1067,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.128"
|
version = "1.0.129"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
|
checksum = "6dbcf9b78a125ee667ae19388837dd12294b858d101fdd393cb9d5501ef09eb2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
|
|
@ -37,7 +37,7 @@ use nac3core::{
|
||||||
typecheck::typedef::{iter_type_vars, FunSignature, FuncArg, Type, TypeEnum, VarMap},
|
typecheck::typedef::{iter_type_vars, FunSignature, FuncArg, Type, TypeEnum, VarMap},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{symbol_resolver::InnerResolver, timeline::TimeFns};
|
use super::{symbol_resolver::InnerResolver, timeline::TimeFns};
|
||||||
|
|
||||||
/// The parallelism mode within a block.
|
/// The parallelism mode within a block.
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
|
|
|
@ -65,13 +65,11 @@ use nac3core::{
|
||||||
};
|
};
|
||||||
use nac3ld::Linker;
|
use nac3ld::Linker;
|
||||||
|
|
||||||
use crate::{
|
use codegen::{
|
||||||
codegen::{
|
attributes_writeback, gen_core_log, gen_rtio_log, rpc_codegen_callback, ArtiqCodeGenerator,
|
||||||
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 codegen;
|
||||||
mod symbol_resolver;
|
mod symbol_resolver;
|
||||||
|
|
|
@ -37,7 +37,7 @@ use nac3core::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::PrimitivePythonId;
|
use super::PrimitivePythonId;
|
||||||
|
|
||||||
pub enum PrimitiveValue {
|
pub enum PrimitiveValue {
|
||||||
I32(i32),
|
I32(i32),
|
||||||
|
|
|
@ -5,24 +5,23 @@ use inkwell::{
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::{
|
use super::{
|
||||||
codegen::{
|
classes::{
|
||||||
classes::{
|
ArrayLikeValue, NDArrayValue, ProxyValue, RangeValue, TypedArrayLikeAccessor,
|
||||||
ArrayLikeValue, NDArrayValue, ProxyValue, RangeValue, TypedArrayLikeAccessor,
|
UntypedArrayLikeAccessor, UntypedArrayLikeMutator,
|
||||||
UntypedArrayLikeAccessor, UntypedArrayLikeMutator,
|
|
||||||
},
|
|
||||||
expr::destructure_range,
|
|
||||||
extern_fns, irrt,
|
|
||||||
irrt::calculate_len_for_slice_range,
|
|
||||||
llvm_intrinsics,
|
|
||||||
macros::codegen_unreachable,
|
|
||||||
numpy,
|
|
||||||
numpy::ndarray_elementwise_unaryop_impl,
|
|
||||||
stmt::gen_for_callback_incrementing,
|
|
||||||
CodeGenContext, CodeGenerator,
|
|
||||||
},
|
},
|
||||||
toplevel::helper::PrimDef,
|
expr::destructure_range,
|
||||||
toplevel::numpy::unpack_ndarray_var_tys,
|
extern_fns, irrt,
|
||||||
|
irrt::calculate_len_for_slice_range,
|
||||||
|
llvm_intrinsics,
|
||||||
|
macros::codegen_unreachable,
|
||||||
|
numpy,
|
||||||
|
numpy::ndarray_elementwise_unaryop_impl,
|
||||||
|
stmt::gen_for_callback_incrementing,
|
||||||
|
CodeGenContext, CodeGenerator,
|
||||||
|
};
|
||||||
|
use crate::{
|
||||||
|
toplevel::{helper::PrimDef, numpy::unpack_ndarray_var_tys},
|
||||||
typecheck::typedef::{Type, TypeEnum},
|
typecheck::typedef::{Type, TypeEnum},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use inkwell::{
|
||||||
AddressSpace, IntPredicate,
|
AddressSpace, IntPredicate,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::codegen::{
|
use super::{
|
||||||
irrt::{call_ndarray_calc_size, call_ndarray_flatten_index},
|
irrt::{call_ndarray_calc_size, call_ndarray_flatten_index},
|
||||||
llvm_intrinsics::call_int_umin,
|
llvm_intrinsics::call_int_umin,
|
||||||
stmt::gen_for_callback_incrementing,
|
stmt::gen_for_callback_incrementing,
|
||||||
|
|
|
@ -18,27 +18,27 @@ use nac3parser::ast::{
|
||||||
Unaryop,
|
Unaryop,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use super::{
|
||||||
codegen::{
|
classes::{
|
||||||
classes::{
|
ArrayLikeIndexer, ArrayLikeValue, ListType, ListValue, NDArrayValue, ProxyType, ProxyValue,
|
||||||
ArrayLikeIndexer, ArrayLikeValue, ListType, ListValue, NDArrayValue, ProxyType,
|
RangeValue, TypedArrayLikeAccessor, UntypedArrayLikeAccessor,
|
||||||
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,
|
|
||||||
irrt::*,
|
|
||||||
llvm_intrinsics::{
|
|
||||||
call_expect, call_float_floor, call_float_pow, call_float_powi, call_int_smax,
|
|
||||||
call_int_umin, call_memcpy_generic,
|
|
||||||
},
|
|
||||||
macros::codegen_unreachable,
|
|
||||||
need_sret, numpy,
|
|
||||||
stmt::{
|
|
||||||
gen_for_callback_incrementing, gen_if_callback, gen_if_else_expr_callback, gen_raise,
|
|
||||||
gen_var,
|
|
||||||
},
|
|
||||||
CodeGenContext, CodeGenTask, CodeGenerator,
|
|
||||||
},
|
},
|
||||||
|
concrete_type::{ConcreteFuncArg, ConcreteTypeEnum, ConcreteTypeStore},
|
||||||
|
gen_in_range_check, get_llvm_abi_type, get_llvm_type, get_va_count_arg_name,
|
||||||
|
irrt::*,
|
||||||
|
llvm_intrinsics::{
|
||||||
|
call_expect, call_float_floor, call_float_pow, call_float_powi, call_int_smax,
|
||||||
|
call_int_umin, call_memcpy_generic,
|
||||||
|
},
|
||||||
|
macros::codegen_unreachable,
|
||||||
|
need_sret, numpy,
|
||||||
|
stmt::{
|
||||||
|
gen_for_callback_incrementing, gen_if_callback, gen_if_else_expr_callback, gen_raise,
|
||||||
|
gen_var,
|
||||||
|
},
|
||||||
|
CodeGenContext, CodeGenTask, CodeGenerator,
|
||||||
|
};
|
||||||
|
use crate::{
|
||||||
symbol_resolver::{SymbolValue, ValueEnum},
|
symbol_resolver::{SymbolValue, ValueEnum},
|
||||||
toplevel::{
|
toplevel::{
|
||||||
helper::PrimDef,
|
helper::PrimDef,
|
||||||
|
@ -1777,7 +1777,12 @@ 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::Invert => ctx.builder.build_not(val, "not").map(Into::into).unwrap(),
|
||||||
ast::Unaryop::Not => ctx
|
ast::Unaryop::Not => ctx
|
||||||
.builder
|
.builder
|
||||||
.build_xor(val, val.get_type().const_all_ones(), "not")
|
.build_int_compare(
|
||||||
|
inkwell::IntPredicate::EQ,
|
||||||
|
val,
|
||||||
|
val.get_type().const_zero(),
|
||||||
|
"not",
|
||||||
|
)
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
ast::Unaryop::UAdd => val.into(),
|
ast::Unaryop::UAdd => val.into(),
|
||||||
|
@ -2886,7 +2891,31 @@ pub fn gen_expr<'ctx, G: CodeGenerator>(
|
||||||
Some((_, Some(static_value), _)) => ValueEnum::Static(static_value.clone()),
|
Some((_, Some(static_value), _)) => ValueEnum::Static(static_value.clone()),
|
||||||
None => {
|
None => {
|
||||||
let resolver = ctx.resolver.clone();
|
let resolver = ctx.resolver.clone();
|
||||||
resolver.get_symbol_value(*id, ctx, generator).unwrap()
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ExprKind::List { elts, .. } => {
|
ExprKind::List { elts, .. } => {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use inkwell::{
|
||||||
};
|
};
|
||||||
use itertools::Either;
|
use itertools::Either;
|
||||||
|
|
||||||
use crate::codegen::CodeGenContext;
|
use super::CodeGenContext;
|
||||||
|
|
||||||
/// Macro to generate extern function
|
/// Macro to generate extern function
|
||||||
/// Both function return type and function parameter type are `FloatValue`
|
/// Both function return type and function parameter type are `FloatValue`
|
||||||
|
|
|
@ -6,8 +6,8 @@ use inkwell::{
|
||||||
|
|
||||||
use nac3parser::ast::{Expr, Stmt, StrRef};
|
use nac3parser::ast::{Expr, Stmt, StrRef};
|
||||||
|
|
||||||
|
use super::{bool_to_i1, bool_to_i8, classes::ArraySliceValue, expr::*, stmt::*, CodeGenContext};
|
||||||
use crate::{
|
use crate::{
|
||||||
codegen::{bool_to_i1, bool_to_i8, classes::ArraySliceValue, expr::*, stmt::*, CodeGenContext},
|
|
||||||
symbol_resolver::ValueEnum,
|
symbol_resolver::ValueEnum,
|
||||||
toplevel::{DefinitionId, TopLevelDef},
|
toplevel::{DefinitionId, TopLevelDef},
|
||||||
typecheck::typedef::{FunSignature, Type},
|
typecheck::typedef::{FunSignature, Type},
|
||||||
|
|
|
@ -7,7 +7,7 @@ use inkwell::{
|
||||||
};
|
};
|
||||||
use itertools::Either;
|
use itertools::Either;
|
||||||
|
|
||||||
use crate::codegen::CodeGenContext;
|
use super::CodeGenContext;
|
||||||
|
|
||||||
/// Returns the string representation for the floating-point type `ft` when used in intrinsic
|
/// Returns the string representation for the floating-point type `ft` when used in intrinsic
|
||||||
/// functions.
|
/// functions.
|
||||||
|
|
|
@ -29,7 +29,6 @@ use parking_lot::{Condvar, Mutex};
|
||||||
use nac3parser::ast::{Location, Stmt, StrRef};
|
use nac3parser::ast::{Location, Stmt, StrRef};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
codegen::classes::{ListType, NDArrayType, ProxyType, RangeType},
|
|
||||||
symbol_resolver::{StaticValue, SymbolResolver},
|
symbol_resolver::{StaticValue, SymbolResolver},
|
||||||
toplevel::{helper::PrimDef, numpy::unpack_ndarray_var_tys, TopLevelContext, TopLevelDef},
|
toplevel::{helper::PrimDef, numpy::unpack_ndarray_var_tys, TopLevelContext, TopLevelDef},
|
||||||
typecheck::{
|
typecheck::{
|
||||||
|
@ -37,6 +36,9 @@ use crate::{
|
||||||
typedef::{CallId, FuncArg, Type, TypeEnum, Unifier},
|
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 builtin_fns;
|
||||||
pub mod classes;
|
pub mod classes;
|
||||||
|
@ -52,9 +54,6 @@ pub mod stmt;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
use concrete_type::{ConcreteType, ConcreteTypeEnum, ConcreteTypeStore};
|
|
||||||
pub use generator::{CodeGenerator, DefaultCodeGenerator};
|
|
||||||
|
|
||||||
mod macros {
|
mod macros {
|
||||||
/// Codegen-variant of [`std::unreachable`] which accepts an instance of [`CodeGenContext`] as
|
/// 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
|
/// its first argument to provide Python source information to indicate the codegen location
|
||||||
|
|
|
@ -6,24 +6,23 @@ use inkwell::{
|
||||||
|
|
||||||
use nac3parser::ast::{Operator, StrRef};
|
use nac3parser::ast::{Operator, StrRef};
|
||||||
|
|
||||||
use crate::{
|
use super::{
|
||||||
codegen::{
|
classes::{
|
||||||
classes::{
|
ArrayLikeIndexer, ArrayLikeValue, ListType, ListValue, NDArrayType, NDArrayValue,
|
||||||
ArrayLikeIndexer, ArrayLikeValue, ListType, ListValue, NDArrayType, NDArrayValue,
|
ProxyType, ProxyValue, TypedArrayLikeAccessor, TypedArrayLikeAdapter,
|
||||||
ProxyType, ProxyValue, TypedArrayLikeAccessor, TypedArrayLikeAdapter,
|
TypedArrayLikeMutator, UntypedArrayLikeAccessor, UntypedArrayLikeMutator,
|
||||||
TypedArrayLikeMutator, UntypedArrayLikeAccessor, UntypedArrayLikeMutator,
|
|
||||||
},
|
|
||||||
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,
|
|
||||||
},
|
|
||||||
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,
|
|
||||||
},
|
},
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
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,
|
symbol_resolver::ValueEnum,
|
||||||
toplevel::{
|
toplevel::{
|
||||||
helper::PrimDef,
|
helper::PrimDef,
|
||||||
|
|
|
@ -15,13 +15,13 @@ use nac3parser::{
|
||||||
};
|
};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
classes::{ListType, NDArrayType, ProxyType, RangeType},
|
||||||
|
concrete_type::ConcreteTypeStore,
|
||||||
|
CodeGenContext, CodeGenLLVMOptions, CodeGenTargetMachineOptions, CodeGenTask, CodeGenerator,
|
||||||
|
DefaultCodeGenerator, WithCall, WorkerRegistry,
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
codegen::{
|
|
||||||
classes::{ListType, NDArrayType, ProxyType, RangeType},
|
|
||||||
concrete_type::ConcreteTypeStore,
|
|
||||||
CodeGenContext, CodeGenLLVMOptions, CodeGenTargetMachineOptions, CodeGenTask,
|
|
||||||
CodeGenerator, DefaultCodeGenerator, WithCall, WorkerRegistry,
|
|
||||||
},
|
|
||||||
symbol_resolver::{SymbolResolver, ValueEnum},
|
symbol_resolver::{SymbolResolver, ValueEnum},
|
||||||
toplevel::{
|
toplevel::{
|
||||||
composer::{ComposerConfig, TopLevelComposer},
|
composer::{ComposerConfig, TopLevelComposer},
|
||||||
|
|
|
@ -11,7 +11,8 @@ use itertools::Either;
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
helper::{debug_assert_prim_is_allowed, make_exception_fields, PrimDefDetails},
|
helper::{debug_assert_prim_is_allowed, make_exception_fields, PrimDef, PrimDefDetails},
|
||||||
|
numpy::make_ndarray_ty,
|
||||||
*,
|
*,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -22,7 +23,6 @@ use crate::{
|
||||||
stmt::exn_constructor,
|
stmt::exn_constructor,
|
||||||
},
|
},
|
||||||
symbol_resolver::SymbolValue,
|
symbol_resolver::SymbolValue,
|
||||||
toplevel::{helper::PrimDef, numpy::make_ndarray_ty},
|
|
||||||
typecheck::typedef::{into_var_map, iter_type_vars, TypeVar, VarMap},
|
typecheck::typedef::{into_var_map, iter_type_vars, TypeVar, VarMap},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use nac3parser::ast::{fold::Fold, ExprKind};
|
use nac3parser::ast::{fold::Fold, ExprKind, Ident};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -382,54 +382,34 @@ 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, .. } => {
|
ast::StmtKind::AnnAssign { target, annotation, .. } => {
|
||||||
let ExprKind::Name { id: name, .. } = target.node else {
|
let ExprKind::Name { id: name, .. } = target.node else {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"global variable declaration must be an identifier (at {})",
|
"global variable declaration must be an identifier (at {})",
|
||||||
ast.location
|
target.location
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.keyword_list.contains(&name) {
|
self.register_top_level_var(
|
||||||
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 !defined_names.insert(global_var_name.clone()) {
|
|
||||||
return Err(format!(
|
|
||||||
"global variable `{}` defined twice (at {})",
|
|
||||||
global_var_name,
|
|
||||||
ast.location
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let ty_to_be_unified = self.unifier.get_dummy_var().ty;
|
|
||||||
self.definition_ast_list.push((
|
|
||||||
RwLock::new(Self::make_top_level_variable_def(
|
|
||||||
global_var_name,
|
|
||||||
name,
|
|
||||||
// dummy here, unify with correct type later,
|
|
||||||
ty_to_be_unified,
|
|
||||||
*(annotation.clone()),
|
|
||||||
resolver,
|
|
||||||
Some(ast.location),
|
|
||||||
)).into(),
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
|
|
||||||
Ok((
|
|
||||||
name,
|
name,
|
||||||
DefinitionId(self.definition_ast_list.len() - 1),
|
Some(annotation.as_ref().clone()),
|
||||||
Some(ty_to_be_unified),
|
resolver,
|
||||||
))
|
mod_path,
|
||||||
|
target.location,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => Err(format!(
|
_ => Err(format!(
|
||||||
|
@ -439,6 +419,50 @@ impl TopLevelComposer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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})"));
|
||||||
|
}
|
||||||
|
|
||||||
|
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()) {
|
||||||
|
return Err(format!(
|
||||||
|
"global variable `{global_var_name}` defined twice (at {location})"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let ty_to_be_unified = self.unifier.get_dummy_var().ty;
|
||||||
|
self.definition_ast_list.push((
|
||||||
|
RwLock::new(Self::make_top_level_variable_def(
|
||||||
|
global_var_name,
|
||||||
|
name,
|
||||||
|
// dummy here, unify with correct type later,
|
||||||
|
ty_to_be_unified,
|
||||||
|
annotation,
|
||||||
|
resolver,
|
||||||
|
Some(location),
|
||||||
|
))
|
||||||
|
.into(),
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
|
||||||
|
Ok((name, DefinitionId(self.definition_ast_list.len() - 1), Some(ty_to_be_unified)))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn start_analysis(&mut self, inference: bool) -> Result<(), HashSet<String>> {
|
pub fn start_analysis(&mut self, inference: bool) -> Result<(), HashSet<String>> {
|
||||||
self.analyze_top_level_class_type_var()?;
|
self.analyze_top_level_class_type_var()?;
|
||||||
self.analyze_top_level_class_bases()?;
|
self.analyze_top_level_class_bases()?;
|
||||||
|
@ -2249,9 +2273,8 @@ impl TopLevelComposer {
|
||||||
let primitives_store = &self.primitives_ty;
|
let primitives_store = &self.primitives_ty;
|
||||||
|
|
||||||
let mut analyze = |variable_def: &Arc<RwLock<TopLevelDef>>| -> Result<_, HashSet<String>> {
|
let mut analyze = |variable_def: &Arc<RwLock<TopLevelDef>>| -> Result<_, HashSet<String>> {
|
||||||
let variable_def = &mut *variable_def.write();
|
let TopLevelDef::Variable { ty: dummy_ty, ty_decl, resolver, loc, .. } =
|
||||||
|
&*variable_def.read()
|
||||||
let TopLevelDef::Variable { ty: dummy_ty, ty_decl, resolver, loc, .. } = variable_def
|
|
||||||
else {
|
else {
|
||||||
// not top level variable def, skip
|
// not top level variable def, skip
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -2259,25 +2282,28 @@ impl TopLevelComposer {
|
||||||
|
|
||||||
let resolver = &**resolver.as_ref().unwrap();
|
let resolver = &**resolver.as_ref().unwrap();
|
||||||
|
|
||||||
let ty_annotation = parse_ast_to_type_annotation_kinds(
|
if let Some(ty_decl) = ty_decl {
|
||||||
resolver,
|
let ty_annotation = parse_ast_to_type_annotation_kinds(
|
||||||
&temp_def_list,
|
resolver,
|
||||||
unifier,
|
&temp_def_list,
|
||||||
primitives_store,
|
unifier,
|
||||||
ty_decl,
|
primitives_store,
|
||||||
HashMap::new(),
|
ty_decl,
|
||||||
)?;
|
HashMap::new(),
|
||||||
let ty_from_ty_annotation = get_type_from_type_annotation_kinds(
|
)?;
|
||||||
&temp_def_list,
|
let ty_from_ty_annotation = get_type_from_type_annotation_kinds(
|
||||||
unifier,
|
&temp_def_list,
|
||||||
primitives_store,
|
unifier,
|
||||||
&ty_annotation,
|
primitives_store,
|
||||||
&mut None,
|
&ty_annotation,
|
||||||
)?;
|
&mut None,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
unifier.unify(*dummy_ty, ty_from_ty_annotation).map_err(|e| {
|
||||||
|
HashSet::from([e.at(Some(loc.unwrap())).to_display(unifier).to_string()])
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
unifier.unify(*dummy_ty, ty_from_ty_annotation).map_err(|e| {
|
|
||||||
HashSet::from([e.at(Some(loc.unwrap())).to_display(unifier).to_string()])
|
|
||||||
})?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,11 @@ use std::convert::TryInto;
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
use strum_macros::EnumIter;
|
use strum_macros::EnumIter;
|
||||||
|
|
||||||
use ast::ExprKind;
|
use nac3parser::ast::{Constant, ExprKind, Location};
|
||||||
use nac3parser::ast::{Constant, Location};
|
|
||||||
|
|
||||||
use super::*;
|
use super::{numpy::unpack_ndarray_var_tys, *};
|
||||||
use crate::{
|
use crate::{
|
||||||
symbol_resolver::SymbolValue,
|
symbol_resolver::SymbolValue,
|
||||||
toplevel::numpy::unpack_ndarray_var_tys,
|
|
||||||
typecheck::typedef::{into_var_map, iter_type_vars, Mapping, TypeVarId, VarMap},
|
typecheck::typedef::{into_var_map, iter_type_vars, Mapping, TypeVarId, VarMap},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -600,7 +598,7 @@ impl TopLevelComposer {
|
||||||
name: String,
|
name: String,
|
||||||
simple_name: StrRef,
|
simple_name: StrRef,
|
||||||
ty: Type,
|
ty: Type,
|
||||||
ty_decl: Expr,
|
ty_decl: Option<Expr>,
|
||||||
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
|
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
|
||||||
loc: Option<Location>,
|
loc: Option<Location>,
|
||||||
) -> TopLevelDef {
|
) -> TopLevelDef {
|
||||||
|
|
|
@ -23,19 +23,19 @@ use crate::{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use composer::*;
|
||||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Hash, Debug)]
|
use type_annotation::*;
|
||||||
pub struct DefinitionId(pub usize);
|
|
||||||
|
|
||||||
pub mod builtins;
|
pub mod builtins;
|
||||||
pub mod composer;
|
pub mod composer;
|
||||||
pub mod helper;
|
pub mod helper;
|
||||||
pub mod numpy;
|
pub mod numpy;
|
||||||
pub mod type_annotation;
|
|
||||||
use composer::*;
|
|
||||||
use type_annotation::*;
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod 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(
|
type GenCallCallback = dyn for<'ctx, 'a> Fn(
|
||||||
&mut CodeGenContext<'ctx, 'a>,
|
&mut CodeGenContext<'ctx, 'a>,
|
||||||
|
@ -158,8 +158,8 @@ pub enum TopLevelDef {
|
||||||
/// Type of the global variable.
|
/// Type of the global variable.
|
||||||
ty: Type,
|
ty: Type,
|
||||||
|
|
||||||
/// The declared type of the global variable.
|
/// The declared type of the global variable, or [`None`] if no type annotation is provided.
|
||||||
ty_decl: Expr,
|
ty_decl: Option<Expr>,
|
||||||
|
|
||||||
/// Symbol resolver of the module defined the class.
|
/// Symbol resolver of the module defined the class.
|
||||||
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
|
resolver: Option<Arc<dyn SymbolResolver + Send + Sync>>,
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
use crate::{
|
use super::helper::PrimDef;
|
||||||
toplevel::helper::PrimDef,
|
use crate::typecheck::{
|
||||||
typecheck::{
|
type_inferencer::PrimitiveStore,
|
||||||
type_inferencer::PrimitiveStore,
|
typedef::{Type, TypeEnum, TypeVarId, Unifier, VarMap},
|
||||||
typedef::{Type, TypeEnum, TypeVarId, Unifier, VarMap},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Creates a `ndarray` [`Type`] with the given type arguments.
|
/// Creates a `ndarray` [`Type`] with the given type arguments.
|
||||||
|
|
|
@ -9,11 +9,10 @@ use nac3parser::{
|
||||||
parser::parse_program,
|
parser::parse_program,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::*;
|
use super::{helper::PrimDef, DefinitionId, *};
|
||||||
use crate::{
|
use crate::{
|
||||||
codegen::CodeGenContext,
|
codegen::CodeGenContext,
|
||||||
symbol_resolver::{SymbolResolver, ValueEnum},
|
symbol_resolver::{SymbolResolver, ValueEnum},
|
||||||
toplevel::{helper::PrimDef, DefinitionId},
|
|
||||||
typecheck::{
|
typecheck::{
|
||||||
type_inferencer::PrimitiveStore,
|
type_inferencer::PrimitiveStore,
|
||||||
typedef::{into_var_map, Type, Unifier},
|
typedef::{into_var_map, Type, Unifier},
|
||||||
|
|
|
@ -2,12 +2,11 @@ use strum::IntoEnumIterator;
|
||||||
|
|
||||||
use nac3parser::ast::Constant;
|
use nac3parser::ast::Constant;
|
||||||
|
|
||||||
use super::*;
|
use super::{
|
||||||
use crate::{
|
helper::{PrimDef, PrimDefDetails},
|
||||||
symbol_resolver::SymbolValue,
|
*,
|
||||||
toplevel::helper::{PrimDef, PrimDefDetails},
|
|
||||||
typecheck::typedef::VarMap,
|
|
||||||
};
|
};
|
||||||
|
use crate::{symbol_resolver::SymbolValue, typecheck::typedef::VarMap};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum TypeAnnotation {
|
pub enum TypeAnnotation {
|
||||||
|
|
|
@ -36,7 +36,7 @@ impl<'a> Inferencer<'a> {
|
||||||
ExprKind::Name { id, .. } => {
|
ExprKind::Name { id, .. } => {
|
||||||
// If `id` refers to a declared symbol, reject this assignment if it is used in the
|
// If `id` refers to a declared symbol, reject this assignment if it is used in the
|
||||||
// context of an (implicit) global variable
|
// context of an (implicit) global variable
|
||||||
if let Some(id_info) = self.defined_identifiers.get(id) {
|
if let Some(id_info) = defined_identifiers.get(id) {
|
||||||
if matches!(
|
if matches!(
|
||||||
id_info.source,
|
id_info.source,
|
||||||
DeclarationSource::Global { is_explicit: Some(false) }
|
DeclarationSource::Global { is_explicit: Some(false) }
|
||||||
|
|
|
@ -5,16 +5,16 @@ use strum::IntoEnumIterator;
|
||||||
|
|
||||||
use nac3parser::ast::{Cmpop, Operator, StrRef, Unaryop};
|
use nac3parser::ast::{Cmpop, Operator, StrRef, Unaryop};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
type_inferencer::*,
|
||||||
|
typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier, VarMap},
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
symbol_resolver::SymbolValue,
|
symbol_resolver::SymbolValue,
|
||||||
toplevel::{
|
toplevel::{
|
||||||
helper::PrimDef,
|
helper::PrimDef,
|
||||||
numpy::{make_ndarray_ty, unpack_ndarray_var_tys},
|
numpy::{make_ndarray_ty, unpack_ndarray_var_tys},
|
||||||
},
|
},
|
||||||
typecheck::{
|
|
||||||
type_inferencer::*,
|
|
||||||
typedef::{FunSignature, FuncArg, Type, TypeEnum, Unifier, VarMap},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The variant of a binary operator.
|
/// The variant of a binary operator.
|
||||||
|
|
|
@ -5,10 +5,9 @@ use itertools::Itertools;
|
||||||
use nac3parser::ast::{Cmpop, Location, StrRef};
|
use nac3parser::ast::{Cmpop, Location, StrRef};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
magic_methods::Binop,
|
magic_methods::{Binop, HasOpInfo},
|
||||||
typedef::{RecordKey, Type, Unifier},
|
typedef::{RecordKey, Type, TypeEnum, Unifier},
|
||||||
};
|
};
|
||||||
use crate::typecheck::{magic_methods::HasOpInfo, typedef::TypeEnum};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum TypeErrorKind {
|
pub enum TypeErrorKind {
|
||||||
|
|
|
@ -14,14 +14,14 @@ use itertools::{repeat_n, Itertools};
|
||||||
use nac3parser::ast::{Cmpop, Location, StrRef, Unaryop};
|
use nac3parser::ast::{Cmpop, Location, StrRef, Unaryop};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
magic_methods::{Binop, HasOpInfo},
|
magic_methods::{Binop, HasOpInfo, OpInfo},
|
||||||
type_error::{TypeError, TypeErrorKind},
|
type_error::{TypeError, TypeErrorKind},
|
||||||
|
type_inferencer::PrimitiveStore,
|
||||||
unification_table::{UnificationKey, UnificationTable},
|
unification_table::{UnificationKey, UnificationTable},
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
symbol_resolver::SymbolValue,
|
symbol_resolver::SymbolValue,
|
||||||
toplevel::{helper::PrimDef, DefinitionId, TopLevelContext, TopLevelDef},
|
toplevel::{helper::PrimDef, DefinitionId, TopLevelContext, TopLevelDef},
|
||||||
typecheck::{magic_methods::OpInfo, type_inferencer::PrimitiveStore},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -7,7 +7,7 @@ def output_int64(x: int64):
|
||||||
...
|
...
|
||||||
|
|
||||||
X: int32 = 0
|
X: int32 = 0
|
||||||
Y: int64 = int64(1)
|
Y = int64(1)
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
global X, Y
|
global X, Y
|
||||||
|
|
|
@ -45,9 +45,10 @@ use nac3core::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod basic_symbol_resolver;
|
|
||||||
use basic_symbol_resolver::*;
|
use basic_symbol_resolver::*;
|
||||||
|
|
||||||
|
mod basic_symbol_resolver;
|
||||||
|
|
||||||
/// Command-line argument parser definition.
|
/// Command-line argument parser definition.
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(author, version, about, long_about = None)]
|
#[command(author, version, about, long_about = None)]
|
||||||
|
@ -174,46 +175,49 @@ fn handle_typevar_definition(
|
||||||
fn handle_assignment_pattern(
|
fn handle_assignment_pattern(
|
||||||
targets: &[Expr],
|
targets: &[Expr],
|
||||||
value: &Expr,
|
value: &Expr,
|
||||||
resolver: &(dyn SymbolResolver + Send + Sync),
|
resolver: Arc<dyn SymbolResolver + Send + Sync>,
|
||||||
internal_resolver: &ResolverInternal,
|
internal_resolver: &ResolverInternal,
|
||||||
def_list: &[Arc<RwLock<TopLevelDef>>],
|
composer: &mut TopLevelComposer,
|
||||||
unifier: &mut Unifier,
|
|
||||||
primitives: &PrimitiveStore,
|
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
if targets.len() == 1 {
|
if targets.len() == 1 {
|
||||||
match &targets[0].node {
|
let target = &targets[0];
|
||||||
|
|
||||||
|
match &target.node {
|
||||||
ExprKind::Name { id, .. } => {
|
ExprKind::Name { id, .. } => {
|
||||||
|
let def_list = composer.extract_def_list();
|
||||||
|
let unifier = &mut composer.unifier;
|
||||||
|
let primitives = &composer.primitives_ty;
|
||||||
|
|
||||||
if let Ok(var) =
|
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);
|
internal_resolver.add_id_type(*id, var);
|
||||||
Ok(())
|
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);
|
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(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(format!("fails to evaluate this expression `{:?}` as a constant or generic parameter at {}",
|
Err(format!("fails to evaluate this expression `{:?}` as a constant or generic parameter at {}",
|
||||||
targets[0].node,
|
target.node,
|
||||||
targets[0].location,
|
target.location,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => {
|
ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => {
|
||||||
handle_assignment_pattern(
|
handle_assignment_pattern(elts, value, resolver, internal_resolver, composer)?;
|
||||||
elts,
|
|
||||||
value,
|
|
||||||
resolver,
|
|
||||||
internal_resolver,
|
|
||||||
def_list,
|
|
||||||
unifier,
|
|
||||||
primitives,
|
|
||||||
)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => Err(format!(
|
_ => Err(format!("assignment to {target:?} is not supported at {}", target.location)),
|
||||||
"assignment to {:?} is not supported at {}",
|
|
||||||
targets[0], targets[0].location
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match &value.node {
|
match &value.node {
|
||||||
|
@ -223,11 +227,9 @@ fn handle_assignment_pattern(
|
||||||
handle_assignment_pattern(
|
handle_assignment_pattern(
|
||||||
std::slice::from_ref(tar),
|
std::slice::from_ref(tar),
|
||||||
val,
|
val,
|
||||||
resolver,
|
resolver.clone(),
|
||||||
internal_resolver,
|
internal_resolver,
|
||||||
def_list,
|
composer,
|
||||||
unifier,
|
|
||||||
primitives,
|
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -248,8 +250,9 @@ fn handle_assignment_pattern(
|
||||||
fn handle_global_var(
|
fn handle_global_var(
|
||||||
target: &Expr,
|
target: &Expr,
|
||||||
value: Option<&Expr>,
|
value: Option<&Expr>,
|
||||||
resolver: &(dyn SymbolResolver + Send + Sync),
|
resolver: &Arc<dyn SymbolResolver + Send + Sync>,
|
||||||
internal_resolver: &ResolverInternal,
|
internal_resolver: &ResolverInternal,
|
||||||
|
composer: &mut TopLevelComposer,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let ExprKind::Name { id, .. } = target.node else {
|
let ExprKind::Name { id, .. } = target.node else {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
|
@ -262,8 +265,12 @@ fn handle_global_var(
|
||||||
return Err(format!("global variable `{id}` must be initialized in its definition"));
|
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);
|
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(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(format!(
|
Err(format!(
|
||||||
|
@ -355,17 +362,12 @@ fn main() {
|
||||||
for stmt in parser_result {
|
for stmt in parser_result {
|
||||||
match &stmt.node {
|
match &stmt.node {
|
||||||
StmtKind::Assign { targets, value, .. } => {
|
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(
|
if let Err(err) = handle_assignment_pattern(
|
||||||
targets,
|
targets,
|
||||||
value,
|
value,
|
||||||
resolver.as_ref(),
|
resolver.clone(),
|
||||||
internal_resolver.as_ref(),
|
internal_resolver.as_ref(),
|
||||||
&def_list,
|
&mut composer,
|
||||||
unifier,
|
|
||||||
primitives,
|
|
||||||
) {
|
) {
|
||||||
panic!("{err}");
|
panic!("{err}");
|
||||||
}
|
}
|
||||||
|
@ -375,16 +377,12 @@ fn main() {
|
||||||
if let Err(err) = handle_global_var(
|
if let Err(err) = handle_global_var(
|
||||||
target,
|
target,
|
||||||
value.as_ref().map(Box::as_ref),
|
value.as_ref().map(Box::as_ref),
|
||||||
resolver.as_ref(),
|
&resolver,
|
||||||
internal_resolver.as_ref(),
|
internal_resolver.as_ref(),
|
||||||
|
&mut composer,
|
||||||
) {
|
) {
|
||||||
panic!("{err}");
|
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"
|
// allow (and ignore) "from __future__ import annotations"
|
||||||
|
|
Loading…
Reference in New Issue