ptx_parser/unparser/
variable.rs

1use super::PtxUnparser;
2use crate::{
3    lexer::PtxToken,
4    r#type::{
5        common::AttributeDirective,
6        variable::{
7            GlobalInitializer, InitializerValue, ModuleVariableDirective, VariableDirective,
8            VariableModifier,
9        },
10    },
11    unparser::{push_decimal, push_directive, push_identifier},
12};
13
14impl PtxUnparser for InitializerValue {
15    fn unparse_tokens(&self, tokens: &mut Vec<PtxToken>) {
16        match self {
17            InitializerValue::NumericLiteral {
18                value: immediate, ..
19            } => immediate.unparse_tokens(tokens),
20            InitializerValue::FunctionSymbol { name: symbol, .. } => {
21                push_identifier(tokens, &symbol.val)
22            }
23            InitializerValue::StringLiteral { value, .. } => {
24                tokens.push(PtxToken::StringLiteral(value.clone()));
25            }
26        }
27    }
28}
29
30impl PtxUnparser for GlobalInitializer {
31    fn unparse_tokens(&self, tokens: &mut Vec<PtxToken>) {
32        match self {
33            GlobalInitializer::Scalar { value, .. } => value.unparse_tokens(tokens),
34            GlobalInitializer::Aggregate {
35                values: elements, ..
36            } => {
37                tokens.push(PtxToken::LBrace);
38                for (index, element) in elements.iter().enumerate() {
39                    if index > 0 {
40                        tokens.push(PtxToken::Comma);
41                    }
42                    element.unparse_tokens(tokens);
43                }
44                tokens.push(PtxToken::RBrace);
45            }
46        }
47    }
48}
49
50impl PtxUnparser for VariableModifier {
51    fn unparse_tokens(&self, tokens: &mut Vec<PtxToken>) {
52        match self {
53            VariableModifier::Vector { value: width, .. } => {
54                push_directive(tokens, &format!("v{width}"));
55            }
56            VariableModifier::Alignment { value, .. } => {
57                push_directive(tokens, "align");
58                push_decimal(tokens, value.to_string());
59            }
60            VariableModifier::Ptr { .. } => push_directive(tokens, "ptr"),
61        }
62    }
63}
64
65fn unparse_array_dimensions(tokens: &mut Vec<PtxToken>, extents: &[Option<u64>]) {
66    for extent in extents {
67        tokens.push(PtxToken::LBracket);
68        if let Some(value) = extent {
69            push_decimal(tokens, value.to_string());
70        }
71        tokens.push(PtxToken::RBracket);
72    }
73}
74
75fn unparse_initializer(tokens: &mut Vec<PtxToken>, initializer: &Option<GlobalInitializer>) {
76    if let Some(initializer) = initializer {
77        tokens.push(PtxToken::Equals);
78        initializer.unparse_tokens(tokens);
79    }
80}
81
82fn unparse_prefix(
83    tokens: &mut Vec<PtxToken>,
84    linkage_modifiers: &[VariableModifier],
85    other_modifiers: &[VariableModifier],
86    attributes: &[AttributeDirective],
87) {
88    for attribute in attributes {
89        attribute.unparse_tokens(tokens);
90    }
91    for modifier in linkage_modifiers {
92        modifier.unparse_tokens(tokens);
93    }
94    for modifier in other_modifiers {
95        modifier.unparse_tokens(tokens);
96    }
97}
98
99fn split_modifiers(
100    modifiers: &[VariableModifier],
101) -> (Vec<VariableModifier>, Vec<VariableModifier>) {
102    // Linkage is now handled at module level, not in modifiers
103    // All modifiers go to "other" category
104    (Vec::new(), modifiers.to_vec())
105}
106
107impl PtxUnparser for VariableDirective {
108    fn unparse_tokens(&self, tokens: &mut Vec<PtxToken>) {
109        let (linkage_modifiers, other_modifiers) = split_modifiers(&self.modifiers);
110        unparse_prefix(
111            tokens,
112            &linkage_modifiers,
113            &other_modifiers,
114            &self.attributes,
115        );
116
117        self.ty.unparse_tokens(tokens);
118
119        push_identifier(tokens, &self.name.val);
120        unparse_array_dimensions(tokens, &self.array_dims);
121        unparse_initializer(tokens, &self.initializer);
122        tokens.push(PtxToken::Semicolon);
123    }
124}
125
126impl PtxUnparser for ModuleVariableDirective {
127    fn unparse_tokens(&self, tokens: &mut Vec<PtxToken>) {
128        match self {
129            ModuleVariableDirective::Tex { directive, .. } => {
130                push_directive(tokens, "tex");
131                directive.unparse_tokens(tokens);
132            }
133            ModuleVariableDirective::Shared { directive, .. } => {
134                push_directive(tokens, "shared");
135                directive.unparse_tokens(tokens);
136            }
137            ModuleVariableDirective::Global { directive, .. } => {
138                push_directive(tokens, "global");
139                directive.unparse_tokens(tokens);
140            }
141            ModuleVariableDirective::Const { directive, .. } => {
142                push_directive(tokens, "const");
143                directive.unparse_tokens(tokens);
144            }
145        }
146    }
147}