Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
HlslGrammar.Ast.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Collections.Generic;
5 using System.Text;
6 
7 using GoldParser;
8 using Irony.Parsing;
9 using SiliconStudio.Shaders.Ast;
10 using SiliconStudio.Shaders.Ast.Hlsl;
11 using SiliconStudio.Shaders.Utility;
14 
15 namespace SiliconStudio.Shaders.Grammar.Hlsl
16 {
17  /// <summary>
18  /// Methods used to create the Abstract Syntax Tree..
19  /// </summary>
20  public partial class HlslGrammar
21  {
22  /// <summary>
23  /// The create annotations ast.
24  /// </summary>
25  /// <param name="context">
26  /// </param>
27  /// <param name="node">
28  /// </param>
29  protected static void CreateAnnotationsAst(ParsingContext context, ParseTreeNode node)
30  {
31  var annotations = Ast<Annotations>(node);
32 
33  // [0] [1] [2]
34  // "<" + variable_declaration_raw.ListOpt() + ">";
35  FillListFromNodes(node.ChildNodes[1].ChildNodes, annotations.Variables);
36  }
37 
38  /// <summary>
39  /// The create annotations opt ast.
40  /// </summary>
41  /// <param name="context">
42  /// </param>
43  /// <param name="node">
44  /// </param>
45  protected static void CreateAnnotationsOptAst(ParsingContext context, ParseTreeNode node)
46  {
47  var values = GetOptional<Annotations>(node);
48  node.AstNode = values;
49  if (values == null)
50  {
51  Ast<Annotations>(node);
52  }
53  }
54 
55  /// <summary>
56  /// The create asm ast.
57  /// </summary>
58  /// <param name="context">
59  /// </param>
60  /// <param name="node">
61  /// </param>
62  protected static void CreateAsmAst(ParsingContext context, ParseTreeNode node)
63  {
64  var value = Ast<AsmExpression>(node);
65 
66  // [0]
67  // asm_block
68  value.Text = node.ChildNodes[0].Token.Text;
69  }
70 
71  /// <summary>
72  /// The create attribute ast.
73  /// </summary>
74  /// <param name="context">
75  /// </param>
76  /// <param name="node">
77  /// </param>
78  protected static void CreateAttributeAst(ParsingContext context, ParseTreeNode node)
79  {
80  var value = Ast<AttributeDeclaration>(node);
81 
82  //// [0] [1] [2] [3]
83  // "[" + identifier + "]"
84  // | "[" + identifier + "(" + literal_list.Q() + ")" + "]";
85  value.Name = (Identifier)node.ChildNodes[1].AstNode;
86 
87  if (node.ChildNodes.Count > 3)
88  {
89  if (node.ChildNodes[3].ChildNodes.Count > 0)
90  {
91  FillListFromNodes(node.ChildNodes[3].ChildNodes[0].ChildNodes, value.Parameters);
92  }
93  }
94  }
95 
96  /// <summary>
97  /// The create cast expression ast.
98  /// </summary>
99  /// <param name="parsingcontext">
100  /// </param>
101  /// <param name="node">
102  /// </param>
103  protected static void CreateCastExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
104  {
105  // [0] [1] [2] [3] [4]
106  // "(" + type_for_cast + rank_specifier.Star() + ")" + cast_expression;
107  var value = Ast<CastExpression>(node);
108 
109  var type = (TypeBase)node.ChildNodes[1].AstNode;
110 
111  if (node.ChildNodes[2].ChildNodes.Count > 0)
112  {
113  var arrayType = new ArrayType { Type = type, Span = SpanConverter.Convert(node.ChildNodes[2].Span) };
114  FillListFromNodes(node.ChildNodes[2].ChildNodes, arrayType.Dimensions);
115  type = arrayType;
116  }
117 
118  value.Target = type;
119  value.From = (Expression)node.ChildNodes[4].AstNode;
120  }
121 
122  /// <summary>
123  /// The create class base type ast.
124  /// </summary>
125  /// <param name="context">
126  /// </param>
127  /// <param name="node">
128  /// </param>
129  protected static void CreateClassBaseTypeAst(ParsingContext context, ParseTreeNode node)
130  {
131  //// [0]
132  //// (":" + type_name).Q();
133  if (node.ChildNodes[0].ChildNodes.Count == 1)
134  node.AstNode = node.ChildNodes[0].ChildNodes[0].AstNode;
135  else
136  node.AstNode = new List<TypeName>();
137  }
138 
139  /// <summary>
140  /// The create class declaration ast.
141  /// </summary>
142  /// <param name="context">
143  /// </param>
144  /// <param name="node">
145  /// </param>
146  protected static void CreateClassDeclarationAst(ParsingContext context, ParseTreeNode node)
147  {
148  // [0] [1] [2] [3] [4] [5]
149  // "class" + type_name + class_base_type.Star() + "{" + scope_declaration.Star() + "}";
150  var value = Ast<ClassType>(node);
151 
152  // Parse generics
153  ParseGenerics((Identifier)node.ChildNodes[1].AstNode, value);
154 
155  //FillListFromNodes(node.ChildNodes[2].ChildNodes, value.BaseClasses);
156  value.BaseClasses.AddRange((List<TypeName>)node.ChildNodes[2].AstNode);
157  FillListFromNodes(node.ChildNodes[4].ChildNodes, value.Members);
158  }
159 
160  protected static void ParseGenerics<T>(Identifier input, T dest) where T : TypeBase, IGenerics
161  {
162  // Parse generic identifier and convert it to simple identifier by adding contraint to the class type
163  var genericIdentifier = input as IdentifierGeneric;
164  if (genericIdentifier != null)
165  {
166  foreach (var genericIdentifierItem in genericIdentifier.Identifiers)
167  {
168  dest.GenericParameters.Add(new GenericParameterType(genericIdentifierItem));
169  }
170  input = new Identifier(input.Text) { Span = genericIdentifier.Span };
171  }
172  dest.Name = input;
173  }
174 
175  /// <summary>
176  /// The create compile expression ast.
177  /// </summary>
178  /// <param name="context">
179  /// </param>
180  /// <param name="node">
181  /// </param>
182  protected static void CreateCompileExpressionAst(ParsingContext context, ParseTreeNode node)
183  {
184  // [0] [1] [2]
185  // "compile" + identifier + simple_method_invoke_expression;
186  var value = Ast<CompileExpression>(node);
187 
188  value.Profile = (Identifier)node.ChildNodes[1].AstNode;
189  value.Function = (MethodInvocationExpression)node.ChildNodes[2].AstNode;
190  }
191 
192  /// <summary>
193  /// The create constant buffer ast.
194  /// </summary>
195  /// <param name="context">
196  /// </param>
197  /// <param name="node">
198  /// </param>
199  protected static void CreateConstantBufferAst(ParsingContext context, ParseTreeNode node)
200  {
201  // [0] [1] [2] [3] [4] [5] [6]
202  // attribute_list_opt + constant_buffer_resource_type + identifier.Q() + register.Q() + "{" + declaration.Star() + "}" + semi_opt;
203  var value = Ast<ConstantBuffer>(node);
204  value.Attributes = (List<AttributeBase>)node.ChildNodes[0].AstNode;
205 
206  value.Type = (ConstantBufferType)node.ChildNodes[1].AstNode;
207 
208  value.Name = GetOptional<Identifier>(node.ChildNodes[2]);
209  value.Register = GetOptional<RegisterLocation>(node.ChildNodes[3]);
210 
211  FillListFromNodes(node.ChildNodes[5].ChildNodes, value.Members);
212  }
213 
214  /// <summary>
215  /// The create generic type ast.
216  /// </summary>
217  /// <param name="parsingcontext">
218  /// </param>
219  /// <param name="node">
220  /// </param>
221  /// <typeparam name="T1">
222  /// </typeparam>
223  protected static void CreateGenericTypeAst<T1>(ParsingContext parsingcontext, ParseTreeNode node)
224  {
225  var value = Ast<GenericType<T1>>(node);
226 
227  // [0] [1] [2] [3]
228  // keyword + "<" + type_name + ">"
229  Identifier identifier = null;
230 
231  if (node.ChildNodes[0].AstNode is TypeBase)
232  {
233  identifier = ((TypeBase)node.ChildNodes[0].AstNode).Name;
234  }
235 
236  if (identifier == null)
237  {
238  CreateIdentifierAst(parsingcontext, node.ChildNodes[0]);
239  identifier = (Identifier)node.ChildNodes[0].AstNode;
240  }
241 
242  value.Name = identifier;
243  value.Parameters[0] = (Node)node.ChildNodes[2].AstNode;
244  }
245 
246  /// <summary>
247  /// The create generic type ast.
248  /// </summary>
249  /// <param name="parsingcontext">
250  /// </param>
251  /// <param name="node">
252  /// </param>
253  /// <typeparam name="T1">
254  /// </typeparam>
255  /// <typeparam name="T2">
256  /// </typeparam>
257  protected static void CreateGenericTypeAst<T1, T2>(ParsingContext parsingcontext, ParseTreeNode node)
258  {
259  var value = Ast<GenericType<T1, T2>>(node);
260 
261  // [0] [1] [2] [3]
262  // identifier + "<" + type_name + "," + value ">"
263  Identifier identifier = null;
264 
265  if (node.ChildNodes[0].AstNode is TypeBase)
266  {
267  identifier = ((TypeBase)node.ChildNodes[0].AstNode).Name;
268  }
269 
270  if (identifier == null)
271  {
272  CreateIdentifierAst(parsingcontext, node.ChildNodes[0]);
273  identifier = (Identifier)node.ChildNodes[0].AstNode;
274  }
275 
276  value.Name = identifier;
277 
278  value.Parameters[0] = (Node)node.ChildNodes[2].AstNode;
279  value.Parameters[1] = (Node)node.ChildNodes[3].AstNode;
280  }
281 
282  /// <summary>
283  /// The create identifier composite list.
284  /// </summary>
285  /// <param name="context">
286  /// </param>
287  /// <param name="node">
288  /// </param>
289  protected static void CreateIdentifierCompositeList(ParsingContext context, ParseTreeNode node)
290  {
291  var values = Ast<List<Identifier>>(node);
292  foreach (var subNode in node.ChildNodes)
293  {
294  values.Add(new Identifier(subNode.Token.Text) { Span = SpanConverter.Convert(subNode.Span) });
295  }
296  }
297 
298  /// <summary>
299  /// The create identifier ns ast.
300  /// </summary>
301  /// <param name="context">
302  /// </param>
303  /// <param name="node">
304  /// </param>
305  protected static void CreateIdentifierNsAst(ParsingContext context, ParseTreeNode node)
306  {
307  // identifier_ns.Rule =
308  // [0] [1] [2]
309  // identifier_raw + "::" + identifier_ns_list;
310  var value = Ast<IdentifierNs>(node);
311  value.Identifiers = new List<Identifier>();
312  value.Identifiers.Add((Identifier)node.ChildNodes[0].AstNode);
313  value.Identifiers.AddRange((List<Identifier>)node.ChildNodes[2].AstNode);
314  }
315 
316  /// <summary>
317  /// The create identifier special reference ast.
318  /// </summary>
319  /// <param name="context">
320  /// </param>
321  /// <param name="node">
322  /// </param>
324  {
325  // "<" + identifier + ">"
326  CreateIdentifierAst(context, node.ChildNodes[1]);
327  var value = (Identifier)node.ChildNodes[1].AstNode;
328  value.IsSpecialReference = true;
329  node.AstNode = value;
330  }
331 
332  /// <summary>
333  /// The create interface ast.
334  /// </summary>
335  /// <param name="context">
336  /// </param>
337  /// <param name="node">
338  /// </param>
339  protected static void CreateInterfaceAst(ParsingContext context, ParseTreeNode node)
340  {
341  var value = Ast<InterfaceType>(node);
342 
343  //// interface_specifier.Rule =
344  //// [0] [1] [2] [3]
345  //// "interface" + identifier + "{" + method_declaration.Star() + "}";
346 
347  // Parse generics
348  ParseGenerics((Identifier)node.ChildNodes[1].AstNode, value);
349 
350  FillListFromNodes(node.ChildNodes[3].ChildNodes, value.Methods);
351  }
352 
353  /// <summary>
354  /// Creates the matrix ast.
355  /// </summary>
356  /// <param name="parsingContext">
357  /// The parsing context.
358  /// </param>
359  /// <param name="node">
360  /// The node.
361  /// </param>
362  protected static void CreateMatrixAst(ParsingContext parsingContext, ParseTreeNode node)
363  {
364  var matrixType = Ast<MatrixType>(node);
365 
366  //// [0] [1] [2] [3] [4] [5]
367  // _("matrix") + "<" + scalars + "," + number + "," + number + ">"
368  matrixType.Type = (TypeBase)node.ChildNodes[2].AstNode;
369  matrixType.Parameters[1] = (Literal)node.ChildNodes[3].AstNode;
370  matrixType.Parameters[2] = (Literal)node.ChildNodes[4].AstNode;
371  }
372 
373  /// <summary>
374  /// The create pack offset ast.
375  /// </summary>
376  /// <param name="context">
377  /// </param>
378  /// <param name="node">
379  /// </param>
380  protected static void CreatePackOffsetAst(ParsingContext context, ParseTreeNode node)
381  {
382  //// [0] [1] [2] [3]
383  // _(":") + "packoffset" + "(" + identifier + ")";
384  node.AstNode = new PackOffset()
385  {
386  Value = (Identifier)node.ChildNodes[2].AstNode, Span = SpanConverter.Convert(node.Span)
387  };
388  }
389 
390  /// <summary>
391  /// The create pass ast.
392  /// </summary>
393  /// <param name="context">
394  /// </param>
395  /// <param name="node">
396  /// </param>
397  protected static void CreatePassAst(ParsingContext context, ParseTreeNode node)
398  {
399  var value = Ast<Pass>(node);
400 
401  //// pass_definition.Rule =
402  //// [0] [1] [2] [3] [4] [5] [6] [7]
403  //// attribute_list_opt + pass_keyword + identifier.Opt() + annotations.Opt() + "{" + pass_statement.ListOpt() + "}" + semi_opt;
404  value.Attributes = (List<AttributeBase>)node.ChildNodes[0].AstNode;
405  value.Name = GetOptional<Identifier>(node.ChildNodes[2]);
406 
407  // TODO HANDLE Annotations here
408  // value.Annotations = (List<Annotations>)node.ChildNodes[3].AstNode;
409  FillListFromNodes(node.ChildNodes[5].ChildNodes, value.Items);
410  }
411 
412  /// <summary>
413  /// The create pass statement ast.
414  /// </summary>
415  /// <param name="context">
416  /// </param>
417  /// <param name="node">
418  /// </param>
419  protected static void CreatePassStatementAst(ParsingContext context, ParseTreeNode node)
420  {
421  //// pass_statement.Rule =
422  //// method_invoke_expression_simple + ";"
423  ////| simple_assignment_expression_statement;
424  node.AstNode = node.ChildNodes[0].AstNode;
425  }
426 
427  /// <summary>
428  /// The create register location ast.
429  /// </summary>
430  /// <param name="context">
431  /// </param>
432  /// <param name="node">
433  /// </param>
434  protected static void CreateRegisterLocationAst(ParsingContext context, ParseTreeNode node)
435  {
436  var value = Ast<RegisterLocation>(node);
437 
438  //// [0] [1] [2] [3] [4]
439  // _(":") + "register" + "(" + indexable_identifier + ")"
440  // | _(":") + "register" + "(" + identifier + "," + indexable_identifier + ")";
441  int index = 2;
442  if (node.ChildNodes.Count == 5)
443  {
444  value.Profile = (Identifier)node.ChildNodes[index].AstNode;
445  index++;
446  }
447 
448  value.Register = (Identifier)node.ChildNodes[index].AstNode;
449  }
450 
451  /// <summary>
452  /// The create semantic ast.
453  /// </summary>
454  /// <param name="context">
455  /// </param>
456  /// <param name="node">
457  /// </param>
458  protected static void CreateSemanticAst(ParsingContext context, ParseTreeNode node)
459  {
460  //// [0]
461  // ":" + identifier
462  node.AstNode = new Semantic()
463  {
464  Name = (Identifier)node.ChildNodes[0].AstNode, Span = SpanConverter.Convert(node.Span)
465  };
466  }
467 
468  /// <summary>
469  /// The create state expression ast.
470  /// </summary>
471  /// <param name="context">
472  /// </param>
473  /// <param name="node">
474  /// </param>
475  protected static void CreateStateExpressionAst(ParsingContext context, ParseTreeNode node)
476  {
477  //// state_expression.Rule =
478  //// [0] [1]
479  //// state_type + state_initializer;
480  var value = Ast<StateExpression>(node);
481  value.StateType = (TypeBase)node.ChildNodes[0].AstNode;
482  value.Initializer = (StateInitializer)node.ChildNodes[1].AstNode;
483  }
484 
485  /// <summary>
486  /// The create state values ast.
487  /// </summary>
488  /// <param name="context">
489  /// </param>
490  /// <param name="node">
491  /// </param>
492  protected static void CreateStateValuesAst(ParsingContext context, ParseTreeNode node)
493  {
494  //// state_initializer.Rule = "{" + simple_assignment_expression_statement.Star() + "}";
495  var stateValues = Ast<StateInitializer>(node);
496  FillListFromNodes(node.ChildNodes[1].ChildNodes, stateValues.Items);
497  }
498 
499  /// <summary>
500  /// The create string literal ast.
501  /// </summary>
502  /// <param name="context">
503  /// </param>
504  /// <param name="node">
505  /// </param>
506  protected static void CreateStringLiteralAst(ParsingContext context, ParseTreeNode node)
507  {
508  var value = Ast<Literal>(node);
509 
510  value.SubLiterals = new List<Literal>();
511 
512  //// string_literal.Rule =
513  //// string_literal_raw.List();
514  var text = new StringBuilder();
515  var textValue = new StringBuilder();
516  foreach (var childNode in node.ChildNodes[0].ChildNodes)
517  {
518  var subLiteral = new Literal
519  {
520  Span = SpanConverter.Convert(childNode.Span),
521  Value = childNode.AstNode,
522  Text = childNode.Token.Text
523  };
524  value.SubLiterals.Add(subLiteral);
525  textValue.Append(subLiteral.Value);
526  }
527 
528  text.Append("\"").Append(textValue).Append("\"");
529 
530  value.Value = textValue.ToString();
531  value.Text = text.ToString();
532  }
533 
534  /// <summary>
535  /// The create technique ast.
536  /// </summary>
537  /// <param name="context">
538  /// </param>
539  /// <param name="node">
540  /// </param>
541  protected static void CreateTechniqueAst(ParsingContext context, ParseTreeNode node)
542  {
543  var value = Ast<Technique>(node);
544 
545  //// technique_definition.Rule =
546  //// [0] [1] [2] [3] [4] [5] [6] [7]
547  //// attribute_list_opt + technique_keyword + identifier.Opt() + annotations_opt + "{" + pass_definition.List() + "}" + semi_opt;
548  value.Type = (Identifier)node.ChildNodes[1].AstNode;
549  value.Attributes = (List<AttributeBase>)node.ChildNodes[0].AstNode;
550  value.Name = GetOptional<Identifier>(node.ChildNodes[2]);
551 
552  // TODO Handle annotations here
553  // value.Annotations = (List<Annotations>)node.ChildNodes[3].AstNode;
554  FillListFromNodes(node.ChildNodes[5].ChildNodes, value.Passes);
555  }
556 
557  /// <summary>
558  /// The create texture dms ast.
559  /// </summary>
560  /// <param name="context">
561  /// </param>
562  /// <param name="node">
563  /// </param>
564  protected static void CreateTextureDMSAst(ParsingContext context, ParseTreeNode node)
565  {
566  //// texture_generic_dms_type.Rule =
567  //// [0] [1] [2] [3] [3] [4]
568  //// texture_dms_type_profile_5 + "<" + scalars_and_vectors + ">"
569  ////| texture_dms_type_profile_5 + "<" + scalars_and_vectors + "," + number + ">";
570  if (node.ChildNodes.Count == 4)
571  {
572  CreateGenericTypeAst<TypeBase>(context, node);
573  }
574  else
575  {
576  CreateGenericTypeAst<TypeBase, Literal>(context, node);
577  }
578  }
579 
580  /// <summary>
581  /// The create typedef ast.
582  /// </summary>
583  /// <param name="parsingcontext">
584  /// </param>
585  /// <param name="node">
586  /// </param>
587  protected static void CreateTypedefAst(ParsingContext parsingcontext, ParseTreeNode node)
588  {
589  var value = Ast<Typedef>(node);
590 
591  // [0] [1] [2] [3]
592  // _("typedef") + typedefable_type + variable_declarator_list + ";"
593  // | _("typedef") + storage_class_specifier + typedefable_type + variable_declarator_list + ";";
594  int indexType = 1;
595  if (node.ChildNodes.Count == 4)
596  {
597  value.Qualifiers = CreateEnumFlags(Qualifier.None, node.ChildNodes[0].ChildNodes);
598  indexType++;
599  }
600 
601  value.Type = (TypeBase)node.ChildNodes[indexType].AstNode;
602  var identifierList = (List<Identifier>)node.ChildNodes[indexType + 1].AstNode;
603 
604  var declarators = new List<Typedef>(identifierList.Count);
605 
606  // Create declarators for typedefs
607  foreach (var identifier in identifierList)
608  {
609  var declarator = new Typedef(value.Type)
610  {
611  Span = identifier.Span,
612  Name = identifier
613  };
614 
615  if (identifier.HasIndices)
616  {
617  var arrayType = new ArrayType { Type = declarator.Type, Span = identifier.Span };
618  arrayType.Dimensions.AddRange(identifier.Indices);
619  declarator.Type = arrayType;
620  identifier.Indices.Clear();
621  }
622 
623  declarators.Add(declarator);
624  }
625 
626  if (declarators.Count == 1)
627  {
628  value.Type = declarators[0].Type;
629  value.Name = declarators[0].Name;
630  }
631  else
632  {
633  value.SubDeclarators = declarators;
634  }
635  }
636 
637  /// <summary>
638  /// The create variable declarator qualifier post ast.
639  /// </summary>
640  /// <param name="context">
641  /// </param>
642  /// <param name="node">
643  /// </param>
645  {
646  // Empty
647  // | semantic
648  // | semantic + packoffset + register.Star()
649  // | semantic + register.Plus()
650  // | packoffset + register.Star()
651  // | register.Plus();
652  var qualifiers = AstCompositeEnum<Qualifier>(node);
653 
654  foreach (var childNode in node.ChildNodes)
655  {
656  // semantic or packoffset
657  if (childNode.AstNode is Semantic)
658  {
659  qualifiers |= (Semantic)childNode.AstNode;
660  }
661  else if (childNode.AstNode is PackOffset)
662  {
663  qualifiers |= (PackOffset)childNode.AstNode;
664  }
665  else
666  {
667  qualifiers = CreateEnumFlags(qualifiers, childNode.ChildNodes);
668  }
669  }
670 
671  // Pass a local object to be used by the variable_declarator
672  node.AstNode = qualifiers;
673  }
674 
675  /// <summary>
676  /// Creates the vector ast.
677  /// </summary>
678  /// <param name="parsingContext">
679  /// The parsing context.
680  /// </param>
681  /// <param name="node">
682  /// The node.
683  /// </param>
684  protected static void CreateVectorAst(ParsingContext parsingContext, ParseTreeNode node)
685  {
686  var vectorType = Ast<VectorType>(node);
687 
688  //// [0] [1] [2] [3] [4]
689  // _("vector") + "<" + scalars + "," + number + ">"
690  vectorType.Type = (TypeBase)node.ChildNodes[2].AstNode;
691  vectorType.Parameters[1] = (Literal)node.ChildNodes[3].AstNode;
692  }
693 
694  /// <summary>
695  /// The create parameter ast.
696  /// </summary>
697  /// <param name="context">
698  /// </param>
699  /// <param name="node">
700  /// </param>
701  protected override void CreateParameterAst(ParsingContext context, ParseTreeNode node)
702  {
703  base.CreateParameterAst(context, node);
704 
705  //// parameter_declaration.Rule =
706  //// [0] [1] [2] [3] [4]
707  //// attribute_qualifier_pre + parameter_qualifier_pre + parameter_type + indexable_identifier.Opt() + parameter_qualifier_post;
708  var parameter = (Parameter)node.AstNode;
709 
710  parameter.Qualifiers = (Qualifier)node.ChildNodes[1].AstNode;
711 
712  var postQualifier = (Tuple<Expression, Qualifier>)node.ChildNodes[4].AstNode;
713  parameter.InitialValue = postQualifier.Item1;
714  parameter.Qualifiers |= postQualifier.Item2;
715  }
716 
717  private void CreateParameterQualifierPost(ParsingContext context, ParseTreeNode node)
718  {
719  //// [0] [1] [2]
720  //// parameter_qualifier_post.Rule = semantic_list_opt
721  //// | "=" + initializer + semantic_list_opt;
722 
723  Tuple<Expression, Qualifier> postQualifier;
724 
725  if (node.ChildNodes.Count == 3)
726  {
727  postQualifier = new Tuple<Expression, Qualifier>((Expression)node.ChildNodes[1].AstNode, (Qualifier)node.ChildNodes[2].AstNode);
728  }
729  else
730  {
731  postQualifier = new Tuple<Expression, Qualifier>(null, (Qualifier)node.ChildNodes[0].AstNode);
732  }
733 
734  node.AstNode = postQualifier;
735  }
736 
737  /// <summary>
738  /// The create parameter qualifier.
739  /// </summary>
740  /// <param name="context">
741  /// </param>
742  /// <param name="node">
743  /// </param>
744  protected virtual void CreateParameterQualifier(ParsingContext context, ParseTreeNode node)
745  {
746  //// [0]
747  //// storage_class_specifier | _("in") | "out" | "inout" | "point" | "line" | "triangle" | "triangleadj";
748  if (node.ChildNodes[0].AstNode is Qualifier)
749  {
750  node.AstNode = node.ChildNodes[0].AstNode;
751  }
752  else
753  {
754  var qualifier = Shaders.Ast.Hlsl.ParameterQualifier.Parse(node.ChildNodes[0].Token.Text);
755  qualifier.Span = SpanConverter.Convert(node.Span);
756  node.AstNode = qualifier;
757  }
758  }
759 
760  protected override void CreateStorageQualifier(ParsingContext context, ParseTreeNode node)
761  {
762  var qualifier = AstCompositeEnum<Qualifier>(node);
763 
764  if (node.ChildNodes.Count == 1)
765  {
766  qualifier = Shaders.Ast.Hlsl.StorageQualifier.Parse(node.ChildNodes[0].Token.Text);
767  qualifier.Span = SpanConverter.Convert(node.Span);
768  }
769 
770  // Use Hlsl Storage Qualifiers to parse the qualifier
771  node.AstNode = qualifier;
772  }
773 
774  /// <summary>
775  /// The create variable declarator ast.
776  /// </summary>
777  /// <param name="parsingcontext">
778  /// </param>
779  /// <param name="node">
780  /// </param>
781  protected override void CreateVariableDeclaratorAst(ParsingContext parsingcontext, ParseTreeNode node)
782  {
783  // Create default declarator using the follozing inherited rule
784  ////
785  //// variable_declarator.Rule =
786  //// [0] [1] [2]
787  //// variable_declarator_raw
788  ////| variable_declarator_raw + "=" + initializer;
789  ////
790  //// Rules added by this override:
791  ////| variable_declarator_raw + state_initializer
792  ////| variable_declarator_raw + state_array_initializer;
793  base.CreateVariableDeclaratorAst(parsingcontext, node);
794  var value = (Variable)node.AstNode;
795 
796  // Get initial value
797  if (node.ChildNodes.Count == 2)
798  {
799  value.InitialValue = (Expression)node.ChildNodes[1].AstNode;
800  }
801  }
802 
803  protected override void CreateVariableDeclaratorRawAst(ParsingContext parsingcontext, ParseTreeNode node)
804  {
805  //// Get base declaration:
806  //// variable_declarator_raw.Rule =
807  //// [0] [1]
808  //// indexable_identifier_declarator + variable_declarator_qualifier_post
809  base.CreateVariableDeclaratorRawAst(parsingcontext, node);
810  var value = (Variable)node.AstNode;
811 
812  //// Add annotations:
813  //// indexable_identifier_declarator + variable_declarator_qualifier_post +
814  value.Attributes.Add((Annotations)node.ChildNodes[2].AstNode);
815  }
816 
817  private static void CreateConstantBufferTypeAst(ParsingContext context, ParseTreeNode node)
818  {
819  node.AstNode = ConstantBufferType.Parse(node.ChildNodes[0].Token.Text);
820  }
821 
822  private static void CreateFloatQualifier(ParsingContext context, ParseTreeNode node)
823  {
824  node.AstNode = FloatQualifier.Parse(node.ChildNodes[0].Token.Text);
825  }
826 
827  private static void CreateIdentifierDotAst(ParsingContext context, ParseTreeNode node)
828  {
829  // identifier_dot.Rule =
830  // [0] [1] [2]
831  // identifier_or_generic + "." + identifier_dot_list;
832  var value = Ast<IdentifierDot>(node);
833  value.Identifiers.Add((Identifier)node.ChildNodes[0].AstNode);
834  value.Identifiers.AddRange((List<Identifier>)node.ChildNodes[2].AstNode);
835  }
836 
837  private void CreateStringRawLiteral(ParsingContext context, ParseTreeNode node)
838  {
839  node.AstNode = node.Token.Text.Trim('"');
840  }
841 
842  private static void CreateIdentifierGenericAst(ParsingContext context, ParseTreeNode node)
843  {
844  // identifier_generic.Rule =
845  // [0] [1] [2] [3]
846  // identifier
847  // | identifier + "<" + class_identifier_generic_parameter_list + ">";
848  var identifier = (Identifier)node.ChildNodes[0].AstNode;
849 
850  if (node.ChildNodes.Count == 4)
851  {
852  var value = Ast<IdentifierGeneric>(node);
853  value.Text = identifier.Text;
854  value.Identifiers.AddRange((List<Identifier>)node.ChildNodes[2].AstNode);
855  }
856  else
857  {
858  node.AstNode = identifier;
859  }
860  }
861 
862  private static void CreateTypeGenericAst(ParsingContext context, ParseTreeNode node)
863  {
864  var value = Ast<TypeName>(node);
865  value.Name = (Identifier)node.ChildNodes[0].AstNode;
866  }
867 
868  private static void CreateMethodOperatorIdentifierAst(ParsingContext context, ParseTreeNode node)
869  {
870  // method_operator_identifier.Rule =
871  // _("operator") + "[" + "]"
872  // _("operator") + "+"
873  // ...etc.
874  // Get the deepest valid node (either an AstNode or a Token)
875  var value = Ast<Identifier>(node);
876  var text = new StringBuilder();
877  foreach (var subNode in node.ChildNodes)
878  text.Append(subNode.Token.Text);
879  value.Text = text.ToString();
880  }
881 
882  private static void CreateMethodSpecialIdentifierAst(ParsingContext context, ParseTreeNode node)
883  {
884  //// method_special_identifier.Rule =
885  //// [0] [1] [2]
886  //// identifier + "." + method_operator_identifier
887  //// | method_operator_identifier;
888  if (node.ChildNodes.Count == 1)
889  {
890  node.AstNode = node.ChildNodes[0].AstNode;
891  }
892  else
893  {
894  var newnode = Ast<IdentifierDot>(node);
895  newnode.Identifiers.Add((Identifier)node.ChildNodes[0].AstNode);
896  newnode.Identifiers.Add((Identifier)node.ChildNodes[2].AstNode);
897  }
898  }
899 
900  protected virtual void CreateIdentifierSubGenericAst(ParsingContext context, ParseTreeNode node)
901  {
902  node.AstNode = node.ChildNodes[0].AstNode;
903  }
904  }
905 }
SiliconStudio.Shaders.Ast.Hlsl.ParameterQualifier ParameterQualifier
static void CreateSemanticAst(ParsingContext context, ParseTreeNode node)
The create semantic ast.
Specialized ParameterQualifier for Hlsl.
static void CreateAttributeAst(ParsingContext context, ParseTreeNode node)
The create attribute ast.
override void CreateParameterAst(ParsingContext context, ParseTreeNode node)
The create parameter ast.
static void CreateStateValuesAst(ParsingContext context, ParseTreeNode node)
The create state values ast.
static void CreateVectorAst(ParsingContext parsingContext, ParseTreeNode node)
Creates the vector ast.
static void CreateClassDeclarationAst(ParsingContext context, ParseTreeNode node)
The create class declaration ast.
static void CreateMatrixAst(ParsingContext parsingContext, ParseTreeNode node)
Creates the matrix ast.
static void CreateConstantBufferAst(ParsingContext context, ParseTreeNode node)
The create constant buffer ast.
static SourceLocation Convert(Irony.Parsing.SourceLocation sourceLocation)
override void CreateVariableDeclaratorAst(ParsingContext parsingcontext, ParseTreeNode node)
The create variable declarator ast.
static void CreateTechniqueAst(ParsingContext context, ParseTreeNode node)
The create technique ast.
An interface used by generic definitions and instance.
Definition: IGenerics.cs:10
Abstract node.
Definition: Node.cs:15
static void CreateVariableDeclaratorQualifierPostAst(ParsingContext context, ParseTreeNode node)
The create variable declarator qualifier post ast.
static void CreateAnnotationsOptAst(ParsingContext context, ParseTreeNode node)
The create annotations opt ast.
static void CreateTextureDMSAst(ParsingContext context, ParseTreeNode node)
The create texture dms ast.
static void CreateClassBaseTypeAst(ParsingContext context, ParseTreeNode node)
The create class base type ast.
static void CreateIdentifierNsAst(ParsingContext context, ParseTreeNode node)
The create identifier ns ast.
A variable declaration.
Definition: Variable.cs:11
A single parameter declaration.
Definition: Parameter.cs:10
Describes a packoffset(value).
Definition: PackOffset.cs:13
override void CreateStorageQualifier(ParsingContext context, ParseTreeNode node)
The create storage qualifier.
ParseTreeNodeList ChildNodes
Definition: ParseTree.cs:41
virtual void CreateIdentifierSubGenericAst(ParsingContext context, ParseTreeNode node)
virtual void CreateParameterQualifier(ParsingContext context, ParseTreeNode node)
The create parameter qualifier.
static void CreateStringLiteralAst(ParsingContext context, ParseTreeNode node)
The create string literal ast.
static void CreatePassAst(ParsingContext context, ParseTreeNode node)
The create pass ast.
SiliconStudio.Shaders.Ast.Hlsl.StorageQualifier StorageQualifier
Base type for all types.
Definition: TypeBase.cs:11
static void CreateIdentifierSpecialReferenceAst(ParsingContext context, ParseTreeNode node)
The create identifier special reference ast.
A generic identifier in the form Typename
override void CreateVariableDeclaratorRawAst(ParsingContext parsingcontext, ParseTreeNode node)
The create variable declarator raw ast.
static void CreateCompileExpressionAst(ParsingContext context, ParseTreeNode node)
The create compile expression ast.
static void CreateStateExpressionAst(ParsingContext context, ParseTreeNode node)
The create state expression ast.
static void CreateIdentifierCompositeList(ParsingContext context, ParseTreeNode node)
The create identifier composite list.
static void CreateAsmAst(ParsingContext context, ParseTreeNode node)
The create asm ast.
char * dest
Definition: lz4.h:61
static void CreateCastExpressionAst(ParsingContext parsingcontext, ParseTreeNode node)
The create cast expression ast.
static void CreatePackOffsetAst(ParsingContext context, ParseTreeNode node)
The create pack offset ast.
static void CreateInterfaceAst(ParsingContext context, ParseTreeNode node)
The create interface ast.
static readonly Qualifier None
None Enum.
Definition: Qualifier.cs:18
static void CreatePassStatementAst(ParsingContext context, ParseTreeNode node)
The create pass statement ast.
A field of a struct.
Definition: Literal.cs:13
static void CreateTypedefAst(ParsingContext parsingcontext, ParseTreeNode node)
The create typedef ast.
static void CreateAnnotationsAst(ParsingContext context, ParseTreeNode node)
The create annotations ast.
static void CreateRegisterLocationAst(ParsingContext context, ParseTreeNode node)
The create register location ast.
Methods used to create the Abstract Syntax Tree..