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, push_space},
12};
13
14impl PtxUnparser for InitializerValue {
15 fn unparse_tokens(&self, tokens: &mut Vec<PtxToken>) {
16 self.unparse_tokens_mode(tokens, false);
17 }
18
19 fn unparse_tokens_mode(&self, tokens: &mut Vec<PtxToken>, spaced: bool) {
20 match self {
21 InitializerValue::NumericLiteral {
22 value: immediate, ..
23 } => immediate.unparse_tokens_mode(tokens, spaced),
24 InitializerValue::FunctionSymbol { name: symbol, .. } => {
25 push_identifier(tokens, &symbol.val)
26 }
27 InitializerValue::StringLiteral { value, .. } => {
28 tokens.push(PtxToken::StringLiteral(value.clone()));
29 }
30 }
31 }
32}
33
34impl PtxUnparser for GlobalInitializer {
35 fn unparse_tokens(&self, tokens: &mut Vec<PtxToken>) {
36 self.unparse_tokens_mode(tokens, false);
37 }
38
39 fn unparse_tokens_mode(&self, tokens: &mut Vec<PtxToken>, spaced: bool) {
40 match self {
41 GlobalInitializer::Scalar { value, .. } => value.unparse_tokens_mode(tokens, spaced),
42 GlobalInitializer::Aggregate {
43 values: elements, ..
44 } => {
45 tokens.push(PtxToken::LBrace);
46 for (index, element) in elements.iter().enumerate() {
47 if index > 0 {
48 tokens.push(PtxToken::Comma);
49 push_space(tokens, spaced);
50 }
51 element.unparse_tokens_mode(tokens, spaced);
52 }
53 tokens.push(PtxToken::RBrace);
54 }
55 }
56 }
57}
58
59impl PtxUnparser for VariableModifier {
60 fn unparse_tokens(&self, tokens: &mut Vec<PtxToken>) {
61 self.unparse_tokens_mode(tokens, false);
62 }
63
64 fn unparse_tokens_mode(&self, tokens: &mut Vec<PtxToken>, spaced: bool) {
65 match self {
66 VariableModifier::Vector { value: width, .. } => {
67 push_directive(tokens, &format!("v{width}"));
68 }
69 VariableModifier::Alignment { value, .. } => {
70 push_directive(tokens, "align");
71 push_space(tokens, spaced);
72 push_decimal(tokens, value.to_string());
73 }
74 VariableModifier::Ptr { .. } => push_directive(tokens, "ptr"),
75 }
76 }
77}
78
79fn unparse_array_dimensions(tokens: &mut Vec<PtxToken>, extents: &[Option<u64>], spaced: bool) {
80 let _ = spaced;
81 for extent in extents {
82 tokens.push(PtxToken::LBracket);
83 if let Some(value) = extent {
84 push_decimal(tokens, value.to_string());
85 }
86 tokens.push(PtxToken::RBracket);
87 }
88}
89
90fn unparse_initializer(
91 tokens: &mut Vec<PtxToken>,
92 initializer: &Option<GlobalInitializer>,
93 spaced: bool,
94) {
95 if let Some(initializer) = initializer {
96 tokens.push(PtxToken::Equals);
97 push_space(tokens, spaced);
98 initializer.unparse_tokens_mode(tokens, spaced);
99 }
100}
101
102fn unparse_prefix(
103 tokens: &mut Vec<PtxToken>,
104 linkage_modifiers: &[VariableModifier],
105 other_modifiers: &[VariableModifier],
106 attributes: &[AttributeDirective],
107 spaced: bool,
108) {
109 for attribute in attributes {
110 attribute.unparse_tokens_mode(tokens, spaced);
111 push_space(tokens, spaced);
112 }
113 for modifier in linkage_modifiers {
114 modifier.unparse_tokens_mode(tokens, spaced);
115 push_space(tokens, spaced);
116 }
117 for modifier in other_modifiers {
118 modifier.unparse_tokens_mode(tokens, spaced);
119 push_space(tokens, spaced);
120 }
121}
122
123fn split_modifiers(
124 modifiers: &[VariableModifier],
125) -> (Vec<VariableModifier>, Vec<VariableModifier>) {
126 (Vec::new(), modifiers.to_vec())
129}
130
131impl PtxUnparser for VariableDirective {
132 fn unparse_tokens(&self, tokens: &mut Vec<PtxToken>) {
133 self.unparse_tokens_mode(tokens, false);
134 }
135
136 fn unparse_tokens_mode(&self, tokens: &mut Vec<PtxToken>, spaced: bool) {
137 let (linkage_modifiers, other_modifiers) = split_modifiers(&self.modifiers);
138 unparse_prefix(
139 tokens,
140 &linkage_modifiers,
141 &other_modifiers,
142 &self.attributes,
143 spaced,
144 );
145 self.ty.unparse_tokens_mode(tokens, spaced);
149 push_space(tokens, spaced);
150 push_identifier(tokens, &self.name.val);
151 unparse_array_dimensions(tokens, &self.array_dims, spaced);
152 unparse_initializer(tokens, &self.initializer, spaced);
153 tokens.push(PtxToken::Semicolon);
154 }
155}
156
157impl PtxUnparser for ModuleVariableDirective {
158 fn unparse_tokens(&self, tokens: &mut Vec<PtxToken>) {
159 self.unparse_tokens_mode(tokens, false);
160 }
161
162 fn unparse_tokens_mode(&self, tokens: &mut Vec<PtxToken>, spaced: bool) {
163 match self {
164 ModuleVariableDirective::Tex { directive, .. } => {
165 push_directive(tokens, "tex");
166 push_space(tokens, spaced);
167 directive.unparse_tokens_mode(tokens, spaced);
168 }
169 ModuleVariableDirective::Shared { directive, .. } => {
170 push_directive(tokens, "shared");
171 push_space(tokens, spaced);
172 directive.unparse_tokens_mode(tokens, spaced);
173 }
174 ModuleVariableDirective::Global { directive, .. } => {
175 push_directive(tokens, "global");
176 push_space(tokens, spaced);
177 directive.unparse_tokens_mode(tokens, spaced);
178 }
179 ModuleVariableDirective::Const { directive, .. } => {
180 push_directive(tokens, "const");
181 push_space(tokens, spaced);
182 directive.unparse_tokens_mode(tokens, spaced);
183 }
184 }
185 }
186}