From dfe23f207f2c96f19a1b3c3a11356e18be48e2a6 Mon Sep 17 00:00:00 2001 From: Lee Dogeon Date: Fri, 7 Feb 2025 04:22:23 +0900 Subject: [PATCH] Implement vm logics related with ParamSpec, TypeVarTuple --- compiler/codegen/src/compile.rs | 23 +++++++++++++++++++++-- compiler/codegen/src/symboltable.rs | 14 ++++++++++++-- compiler/core/src/bytecode.rs | 8 +++++++- vm/src/frame.rs | 17 +++++++++++++++++ vm/src/stdlib/typing.rs | 17 +++++++++++++++-- 5 files changed, 72 insertions(+), 7 deletions(-) diff --git a/compiler/codegen/src/compile.rs b/compiler/codegen/src/compile.rs index b75e977b5d..bcb67ca0f5 100644 --- a/compiler/codegen/src/compile.rs +++ b/compiler/codegen/src/compile.rs @@ -1095,8 +1095,27 @@ impl Compiler { self.store_name(name.as_ref())?; } } - located_ast::TypeParam::ParamSpec(_) => todo!(), - located_ast::TypeParam::TypeVarTuple(_) => todo!(), + located_ast::TypeParam::ParamSpec(located_ast::TypeParamParamSpec { + name, .. + }) => { + self.emit_load_const(ConstantData::Str { + value: name.to_string(), + }); + emit!(self, Instruction::ParamSpec); + emit!(self, Instruction::Duplicate); + self.store_name(name.as_ref())?; + } + located_ast::TypeParam::TypeVarTuple(located_ast::TypeParamTypeVarTuple { + name, + .. + }) => { + self.emit_load_const(ConstantData::Str { + value: name.to_string(), + }); + emit!(self, Instruction::TypeVarTuple); + emit!(self, Instruction::Duplicate); + self.store_name(name.as_ref())?; + } }; } emit!( diff --git a/compiler/codegen/src/symboltable.rs b/compiler/codegen/src/symboltable.rs index bbb134facf..80c6e389fc 100644 --- a/compiler/codegen/src/symboltable.rs +++ b/compiler/codegen/src/symboltable.rs @@ -1257,8 +1257,18 @@ impl SymbolTableBuilder { self.scan_expression(binding, ExpressionContext::Load)?; } } - ast::located::TypeParam::ParamSpec(_) => todo!(), - ast::located::TypeParam::TypeVarTuple(_) => todo!(), + ast::located::TypeParam::ParamSpec(ast::TypeParamParamSpec { + name, + range: param_spec_range, + }) => { + self.register_name(name, SymbolUsage::Assigned, param_spec_range.start)?; + } + ast::located::TypeParam::TypeVarTuple(ast::TypeParamTypeVarTuple { + name, + range: type_var_tuple_range, + }) => { + self.register_name(name, SymbolUsage::Assigned, type_var_tuple_range.start)?; + } } } Ok(()) diff --git a/compiler/core/src/bytecode.rs b/compiler/core/src/bytecode.rs index c8dbc63744..46839c2695 100644 --- a/compiler/core/src/bytecode.rs +++ b/compiler/core/src/bytecode.rs @@ -595,10 +595,12 @@ pub enum Instruction { TypeVarWithBound, TypeVarWithConstraint, TypeAlias, + TypeVarTuple, + ParamSpec, // If you add a new instruction here, be sure to keep LAST_INSTRUCTION updated } // This must be kept up to date to avoid marshaling errors -const LAST_INSTRUCTION: Instruction = Instruction::TypeAlias; +const LAST_INSTRUCTION: Instruction = Instruction::ParamSpec; const _: () = assert!(mem::size_of::() == 1); impl From for u8 { @@ -1291,6 +1293,8 @@ impl Instruction { TypeVarWithBound => -1, TypeVarWithConstraint => -1, TypeAlias => -2, + ParamSpec => 0, + TypeVarTuple => 0, } } @@ -1460,6 +1464,8 @@ impl Instruction { TypeVarWithBound => w!(TypeVarWithBound), TypeVarWithConstraint => w!(TypeVarWithConstraint), TypeAlias => w!(TypeAlias), + ParamSpec => w!(ParamSpec), + TypeVarTuple => w!(TypeVarTuple), } } } diff --git a/vm/src/frame.rs b/vm/src/frame.rs index 8fc7e171b3..fac6da8df5 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -1202,6 +1202,23 @@ impl ExecutingFrame<'_> { self.push_value(type_alias.into_ref(&vm.ctx).into()); Ok(None) } + bytecode::Instruction::ParamSpec => { + let param_spec_name = self.pop_value(); + let param_spec: PyObjectRef = _typing::make_paramspec(param_spec_name.clone()) + .into_ref(&vm.ctx) + .into(); + self.push_value(param_spec); + Ok(None) + } + bytecode::Instruction::TypeVarTuple => { + let type_var_tuple_name = self.pop_value(); + let type_var_tuple: PyObjectRef = + _typing::make_typevartuple(type_var_tuple_name.clone()) + .into_ref(&vm.ctx) + .into(); + self.push_value(type_var_tuple); + Ok(None) + } } } diff --git a/vm/src/stdlib/typing.rs b/vm/src/stdlib/typing.rs index daa0180325..29ce516b14 100644 --- a/vm/src/stdlib/typing.rs +++ b/vm/src/stdlib/typing.rs @@ -75,18 +75,31 @@ pub(crate) mod _typing { #[pyclass(name = "ParamSpec")] #[derive(Debug, PyPayload)] #[allow(dead_code)] - struct ParamSpec {} + pub(crate) struct ParamSpec { + name: PyObjectRef, + } + #[pyclass(flags(BASETYPE))] impl ParamSpec {} + pub(crate) fn make_paramspec(name: PyObjectRef) -> ParamSpec { + ParamSpec { name } + } + #[pyattr] #[pyclass(name = "TypeVarTuple")] #[derive(Debug, PyPayload)] #[allow(dead_code)] - pub(crate) struct TypeVarTuple {} + pub(crate) struct TypeVarTuple { + name: PyObjectRef, + } #[pyclass(flags(BASETYPE))] impl TypeVarTuple {} + pub(crate) fn make_typevartuple(name: PyObjectRef) -> TypeVarTuple { + TypeVarTuple { name } + } + #[pyattr] #[pyclass(name = "ParamSpecArgs")] #[derive(Debug, PyPayload)]