Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
ParadoxGrammar.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 
6 using Irony.Parsing;
7 
8 using SiliconStudio.Paradox.Shaders.Parser.Ast;
9 using SiliconStudio.Shaders.Ast;
10 using SiliconStudio.Shaders.Ast.Hlsl;
11 using SiliconStudio.Shaders.Utility;
12 
13 namespace SiliconStudio.Paradox.Shaders.Parser.Grammar
14 {
15  public partial class ParadoxGrammar
16  {
17  private static void CreateShaderClassSpecifierAst(ParsingContext context, ParseTreeNode node)
18  {
19  // [0] [1] [2] [3] [4] [5]
20  // "class" + type_name + shader_class_base_type.Star() + "{" + scope_declaration.Star() + "}";
21  var value = Ast<ShaderClassType>(node);
22 
23  ParseClassGenerics((Identifier)node.ChildNodes[1].AstNode, value);
24  value.BaseClasses.AddRange((List<ShaderTypeName>)node.ChildNodes[2].AstNode);
25  FillListFromNodes(node.ChildNodes[4].ChildNodes, value.Members);
26  }
27 
28  protected static void ParseClassGenerics(Identifier input, ShaderClassType dest)
29  {
30  // Parse generic identifier and convert it to simple identifier by adding contraint to the class type
31  var genericIdentifier = input as ClassIdentifierGeneric;
32  if (genericIdentifier != null)
33  {
34  foreach (var genericIdentifierItem in genericIdentifier.Generics)
35  {
36  dest.ShaderGenerics.Add(genericIdentifierItem);
37  }
38  input = new Identifier(input.Text) { Span = genericIdentifier.Span };
39  }
40  dest.Name = input;
41  }
42 
43  private static void CreateClassIdentifierGenericAst(ParsingContext context, ParseTreeNode node)
44  {
45  // identifier_generic.Rule =
46  // [0] [1] [2] [3]
47  // identifier
48  // | identifier + "<" + class_identifier_generic_parameter_list + ">";
49  var identifier = (Identifier)node.ChildNodes[0].AstNode;
50 
51  if (node.ChildNodes.Count == 4)
52  {
53  var value = Ast<ClassIdentifierGeneric>(node);
54  value.IsSpecialReference = true;
55  value.Text = identifier.Text;
56  value.Generics.AddRange((List<Variable>)node.ChildNodes[2].AstNode);
57  }
58  else
59  {
60  node.AstNode = identifier;
61  }
62  }
63 
64  protected override void CreateStorageQualifier(ParsingContext context, ParseTreeNode node)
65  {
66  var qualifier = AstCompositeEnum<Qualifier>(node);
67 
68  if (node.ChildNodes.Count == 1)
69  {
70  qualifier = ParadoxStorageQualifier.Parse(node.ChildNodes[0].Token.Text);
71  qualifier.Span = SpanConverter.Convert(node.Span);
72  }
73 
74  // Use Hlsl Storage Qualifiers to parse the qualifier
75  node.AstNode = qualifier;
76  }
77 
78  private static void CreateSemanticTypeAst(ParsingContext context, ParseTreeNode node)
79  {
80  Ast<SemanticType>(node);
81  }
82 
83  private static void CreateLinkTypeAst(ParsingContext context, ParseTreeNode node)
84  {
85  Ast<LinkType>(node);
86  }
87 
88  private static void CreateVarTypeAst(ParsingContext context, ParseTreeNode node)
89  {
90  Ast<VarType>(node);
91  }
92 
93  private static void CreateForEachStatementAst(ParsingContext context, ParseTreeNode node)
94  {
95  var value = Ast<ForEachStatement>(node);
96 
97  //// for_statement.Rule = _
98  //// [0] [1] [2] [3] [4] [5] [6] [7]
99  //// Keyword("foreach") + "(" + type + identifier + Keyword("in") + expression + ")" + statement;
100  value.Variable = new Variable { Type = (TypeBase)node.ChildNodes[2].AstNode, Name = (Identifier)node.ChildNodes[3].AstNode };
101  value.Collection = (Expression)node.ChildNodes[5].AstNode;
102  value.Body = (Statement)node.ChildNodes[7].AstNode;
103  }
104 
105  protected override void CreateIdentifierSubGenericAst(ParsingContext context, ParseTreeNode node)
106  {
107  base.CreateIdentifierSubGenericAst(context, node);
108  if ( node.AstNode is Literal)
109  {
110  node.AstNode = new LiteralIdentifier((Literal)node.AstNode);
111  }
112  else if (node.AstNode is TypeBase)
113  {
114  node.AstNode = new TypeIdentifier((TypeBase)node.AstNode);
115  }
116  }
117 
119  {
120  var value = Ast<Variable>(node);
121 
122  //// class_identifier_sub_generic.Rule =
123  //// [0] [1]
124  //// type + identifier;
125 
126  value.Name = (Identifier)node.ChildNodes[1].AstNode;
127  value.Type = (TypeBase)node.ChildNodes[0].AstNode;
128 
129  /*base.CreateIdentifierSubGenericAst(context, node);
130  if (node.AstNode is Literal)
131  {
132  node.AstNode = new LiteralIdentifier((Literal)node.AstNode);
133  }
134  else if (node.AstNode is TypeBase)
135  {
136  node.AstNode = new TypeIdentifier((TypeBase)node.AstNode);
137  }*/
138  }
139 
140  private static void CreateClassTypeAst(ParsingContext context, ParseTreeNode node)
141  {
142  var value = Ast<ShaderTypeName>(node);
143  value.Name = (Identifier)node.ChildNodes[0].AstNode;
144  }
145 
146  protected static void CreateShaderClassBaseTypeAst(ParsingContext context, ParseTreeNode node)
147  {
148  //// [0]
149  //// (":" + shader_type_name).Q();
150  if (node.ChildNodes[0].ChildNodes.Count == 1)
151  node.AstNode = node.ChildNodes[0].ChildNodes[0].AstNode;
152  else
153  node.AstNode = new List<ShaderTypeName>();
154  }
155 
156  private static void CreateParametersAst(ParsingContext context, ParseTreeNode node)
157  {
158  var value = Ast<ParametersBlock>(node);
159  // [0] [1] [2] [3]
160  // params_block.Rule = attribute_qualifier_pre + Keyword("params") + identifier + block_statement;
161 
162  // value.Attributes = (List<AttributeBase>)node.ChildNodes[0].AstNode;
163  value.Name = (Identifier)node.ChildNodes[2].AstNode;
164  value.Body = (BlockStatement)node.ChildNodes[3].AstNode;
165  }
166 
167  private static void CreateShaderBlockAst(ParsingContext context, ParseTreeNode node)
168  {
169  var value = Ast<ShaderBlock>(node);
170  // [0] [1] [2] [3] [4]
171  // shader_block.Rule = attribute_qualifier_pre + Keyword("partial").Opt() + Keyword("shader") + identifier_raw + block_statement;
172 
173  // value.Attributes = (List<AttributeBase>)node.ChildNodes[0].AstNode;
174  value.IsPartial = node.ChildNodes[1].ChildNodes.Count == 1;
175  value.Name = (Identifier)node.ChildNodes[3].AstNode;
176  value.Body = (BlockStatement)node.ChildNodes[4].AstNode;
177  }
178 
179  private static void CreateMixinStatementAst(ParsingContext context, ParseTreeNode node)
180  {
181  var value = Ast<MixinStatement>(node);
182  // [0] [1] [2] [3]
183  //mixin_statement.Rule = Keyword("mixin") + Keyword("compose") + expression + ";"
184  // | Keyword("mixin") + Keyword("remove") + expression + ";"
185  // | Keyword("mixin") + Keyword("macro") + expression + ";"
186  // | Keyword("mixin") + Keyword("mixin") + expression + ";"
187  // | Keyword("mixin") + Keyword("clone") + ";"
188  // | Keyword("mixin") + expression + ";";
189 
190  value.Value = (node.ChildNodes[1].AstNode as Expression);
191  if (value.Value == null)
192  {
193  var typeName = node.ChildNodes[1].Term.Name;
194  MixinStatementType type;
195  Enum.TryParse(typeName, true, out type);
196  value.Type = type;
197 
198  if (type != MixinStatementType.Clone)
199  {
200  value.Value = (Expression)node.ChildNodes[2].AstNode;
201  }
202  }
203  }
204 
205  private static void CreateUsingStatement(ParsingContext context, ParseTreeNode node)
206  {
207  var value = Ast<UsingStatement>(node);
208 
209  // [0] [1]
210  //using_statement.Rule = Keyword("using") + identifier_or_dot + ";";
211  value.Name = (Identifier)node.ChildNodes[1].AstNode;
212  }
213 
214  private static void CreateUsingParametersStatement(ParsingContext context, ParseTreeNode node)
215  {
216  var value = Ast<UsingParametersStatement>(node);
217 
218  // [0] [1] [2] [3]
219  //using_params_statement.Rule = Keyword("using") + Keyword("params") + expression + ";"
220  // | Keyword("using") + Keyword("params") + expression + block_statement;
221  value.Name = (Expression)node.ChildNodes[2].AstNode;
222  if (node.ChildNodes.Count == 4)
223  {
224  value.Body = (BlockStatement)node.ChildNodes[3].AstNode;
225  }
226  }
227 
228  private static void CreateEnumBlockAst(ParsingContext context, ParseTreeNode node)
229  {
230  var value = Ast<EnumType>(node);
231  // [0] [1] [2] [3] [4]
232  //enum_block.Rule = attribute_qualifier_pre + Keyword("enum") + identifier_raw + "{" + enum_item_list + "}";
233  value.Attributes = (List<AttributeBase>)node.ChildNodes[0].AstNode;
234  value.Name = (Identifier)node.ChildNodes[2].AstNode;
235  value.Values.AddRange((List<Expression>)node.ChildNodes[4].AstNode);
236  }
237 
238  private static void CreateEnumItemAst(ParsingContext context, ParseTreeNode node)
239  {
240  // [0] [1] [2]
241  //enum_item.Rule = identifier + "=" + expression
242  // | identifier;
243  if (node.ChildNodes.Count == 1)
244  {
245  var value = Ast<VariableReferenceExpression>(node);
246  value.Name = (Identifier)node.ChildNodes[0].AstNode;
247  }
248  else
249  {
250  var value = Ast<AssignmentExpression>(node);
251  value.Target = new VariableReferenceExpression((Identifier)node.ChildNodes[0].AstNode);
252  value.Operator = AssignmentOperator.Default;
253  value.Value = (Expression)node.ChildNodes[2].AstNode;
254  }
255  }
256 
257  private static void CreateForEachParamsStatementAst(ParsingContext context, ParseTreeNode node)
258  {
259  var value = Ast<ForEachStatement>(node);
260  //// [0] [1] [2] [3] [4] [5]
261  //// foreach_params_statement.Rule = Keyword("foreach") + "(" + Keyword("params") + conditional_expression + ")" + statement;
262  value.Collection = (Expression)node.ChildNodes[3].AstNode;
263  value.Body = (Statement)node.ChildNodes[5].AstNode;
264  }
265 
266  private static void CreateNamespaceBlockAst(ParsingContext context, ParseTreeNode node)
267  {
268  var value = Ast<NamespaceBlock>(node);
269  //// [0] [1] [2]
270  //// namespace_block.Rule = Keyword("namespace") + identifier_or_dot + toplevel_declaration_block;
271  value.Name = (Identifier)node.ChildNodes[1].AstNode;
272  value.Body = (List<Node>)node.ChildNodes[2].AstNode;
273  }
274 
275  private static void CreateDeclarationBlockAst(ParsingContext context, ParseTreeNode node)
276  {
277  // [0] [1]
278  // toplevel_declaration_block.Rule = "{" + toplevel_declaration_list + "}";
279  node.AstNode = (List<Node>)node.ChildNodes[1].AstNode;
280  }
281  }
282 }
283 
string Text
Gets or sets the name.
Definition: Identifier.cs:77
void CreateClassIdentifierSubGenericAst(ParsingContext context, ParseTreeNode node)
static void CreateShaderClassBaseTypeAst(ParsingContext context, ParseTreeNode node)
override void CreateIdentifierSubGenericAst(ParsingContext context, ParseTreeNode node)
A variable declaration.
Definition: Variable.cs:11
Base root class for all statements.
Definition: Statement.cs:11
ParseTreeNodeList ChildNodes
Definition: ParseTree.cs:41
static void ParseClassGenerics(Identifier input, ShaderClassType dest)
Base type for all types.
Definition: TypeBase.cs:11
override void CreateStorageQualifier(ParsingContext context, ParseTreeNode node)
The create storage qualifier.
char * dest
Definition: lz4.h:61
A field of a struct.
Definition: Literal.cs:13