@@ -7,11 +7,14 @@ use alloc::{
77} ;
88use core:: num:: NonZeroU32 ;
99
10- use crate :: front:: wgsl:: error:: { Error , ExpectedToken , InvalidAssignmentType } ;
1110use crate :: front:: wgsl:: index:: Index ;
1211use crate :: front:: wgsl:: parse:: number:: Number ;
1312use crate :: front:: wgsl:: parse:: { ast, conv} ;
1413use crate :: front:: wgsl:: Result ;
14+ use crate :: front:: wgsl:: {
15+ error:: { Error , ExpectedToken , InvalidAssignmentType } ,
16+ parse:: directive:: enable_extension:: EnableExtensions ,
17+ } ;
1518use crate :: front:: Typifier ;
1619use crate :: {
1720 common:: wgsl:: { TryToWgsl , TypeContext } ,
@@ -1266,10 +1269,16 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
12661269 None
12671270 } ;
12681271
1272+ let space = Self :: var_address_space (
1273+ & v. template_list ,
1274+ & ctx. as_const ( ) ,
1275+ & tu. enable_extensions ,
1276+ ) ?;
1277+
12691278 let handle = ctx. module . global_variables . append (
12701279 ir:: GlobalVariable {
12711280 name : Some ( v. name . name . to_string ( ) ) ,
1272- space : v . space ,
1281+ space,
12731282 binding,
12741283 ty,
12751284 init : initializer,
@@ -2576,6 +2585,66 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
25762585 }
25772586 }
25782587
2588+ fn enumerant (
2589+ expr : Handle < ast:: Expression < ' source > > ,
2590+ ctx : & ExpressionContext < ' source , ' _ , ' _ > ,
2591+ ) -> Result < ' source , ( & ' source str , Span ) > {
2592+ let span = ctx. ast_expressions . get_span ( expr) ;
2593+ let expr = & ctx. ast_expressions [ expr] ;
2594+
2595+ match * expr {
2596+ ast:: Expression :: Ident ( ast:: IdentExpr :: Local ( _) ) => {
2597+ Err ( Box :: new ( Error :: UnexpectedIdentForEnumerant ( span) ) )
2598+ }
2599+ ast:: Expression :: Ident ( ast:: IdentExpr :: Unresolved ( name) ) => {
2600+ if ctx. globals . get ( name) . is_some ( ) {
2601+ Err ( Box :: new ( Error :: UnexpectedIdentForEnumerant ( span) ) )
2602+ } else {
2603+ Ok ( ( name, span) )
2604+ }
2605+ }
2606+ _ => Err ( Box :: new ( Error :: UnexpectedExprForEnumerant ( span) ) ) ,
2607+ }
2608+ }
2609+
2610+ fn var_address_space (
2611+ template_list : & Option < Vec < Handle < ast:: Expression < ' source > > > > ,
2612+ ctx : & ExpressionContext < ' source , ' _ , ' _ > ,
2613+ enable_extensions : & EnableExtensions ,
2614+ ) -> Result < ' source , ir:: AddressSpace > {
2615+ let mut address_space = ir:: AddressSpace :: Handle ;
2616+
2617+ if let & Some ( ref template_list) = template_list {
2618+ let mut template_list_args = template_list. iter ( ) ;
2619+ let address_space_expr = template_list_args. next ( ) . unwrap ( ) ;
2620+
2621+ let ( enumerant, span) = Self :: enumerant ( * address_space_expr, ctx) ?;
2622+ address_space = conv:: map_address_space ( enumerant, span, enable_extensions) ?;
2623+
2624+ match address_space {
2625+ ir:: AddressSpace :: Storage { ref mut access } => {
2626+ if let Some ( access_mode_expr) = template_list_args. next ( ) {
2627+ let ( enumerant, span) = Self :: enumerant ( * access_mode_expr, ctx) ?;
2628+ let access_mode = conv:: map_access_mode ( enumerant, span) ?;
2629+ * access = access_mode;
2630+ } else {
2631+ // defaulting to `read`
2632+ * access = ir:: StorageAccess :: LOAD
2633+ }
2634+ }
2635+ _ => { }
2636+ }
2637+
2638+ let unused_args: Vec < Span > = template_list_args
2639+ . map ( |expr| ctx. ast_expressions . get_span ( * expr) )
2640+ . collect ( ) ;
2641+ if !unused_args. is_empty ( ) {
2642+ return Err ( Box :: new ( Error :: UnusedArgsForTemplate ( unused_args) ) ) ;
2643+ }
2644+ }
2645+ Ok ( address_space)
2646+ }
2647+
25792648 fn binary (
25802649 & mut self ,
25812650 op : ir:: BinaryOperator ,
0 commit comments