ptx_parser/unparser/
variable.rs1use 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 (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}