private ILanguageExpression CompileStructureConstructor(GMacStructureConstructor structureCons, OperandsByValueAccess operands) { ILanguageExpressionAtomic compiledDefaultValueSource = null; if (structureCons.HasDefaultValueSource) { compiledDefaultValueSource = (ILanguageExpressionAtomic)CompileExpression(structureCons.DefaultValueSource); } var compiledOperands = OperandsByValueAccess.Create(); foreach (var command in operands.AssignmentsList) { var compiledLhsValue = CompileLhsValueAccess(command.LhsValueAccess); var compiledRhsExpr = (ILanguageExpressionAtomic)CompileExpression(command.RhsExpression); compiledOperands.AddOperand(compiledLhsValue, compiledRhsExpr); } return(structureCons.Structure.CreateConstructorExpression(compiledDefaultValueSource, compiledOperands)); }
private ILanguageExpression translate_Expression_Function_Macro(GMacMacro macro, ParseTreeNode node) { var operands = OperandsByValueAccess.Create(); if (node.ChildNodes.Count == 0) { return(BasicPolyadic.Create(macro.OutputParameterType, macro, operands)); } var expressionFunctionInputsNode = node.ChildNodes[0]; var subNode = expressionFunctionInputsNode.ChildNodes[0]; switch (subNode.Term.ToString()) { case GMacParseNodeNames.ExpressionFunctionInputsAssignments: var expressionFunctionInputsAssignmentsNode = subNode; foreach (var nodeExpressionFunctionInputsAssignmentsItem in expressionFunctionInputsAssignmentsNode.ChildNodes) { var lhsNode = nodeExpressionFunctionInputsAssignmentsItem.ChildNodes[0].ChildNodes[0]; var rhsNode = nodeExpressionFunctionInputsAssignmentsItem.ChildNodes[1]; var lhsValAccess = GMacValueAccessGenerator.Translate_LValue_MacroParameter(Context, lhsNode, macro); var rhsExpr = BasicExpressionGenerator.Generate_PolyadicOperand( lhsValAccess.ExpressionType, GMacExpressionGenerator.Translate(BasicExpressionGenerator, rhsNode) ); operands.AddOperand(lhsValAccess, rhsExpr); } break; case GMacParseNodeNames.ExpressionFunctionInputsExpressions: var nodeExpressionFunctionInputsExpressions = subNode; var i = -1; foreach (var parameter in macro.Parameters) { if (i >= nodeExpressionFunctionInputsExpressions.ChildNodes.Count) { break; } //The first parameter of any macro is the 'result' output parameter; ignore it if (i >= 0) { var rhsNode = nodeExpressionFunctionInputsExpressions.ChildNodes[i]; var lhsValAccess = LanguageValueAccess.Create(parameter); var rhsExpr = BasicExpressionGenerator.Generate_PolyadicOperand( lhsValAccess.ExpressionType, GMacExpressionGenerator.Translate(BasicExpressionGenerator, rhsNode) ); operands.AddOperand(lhsValAccess, rhsExpr); } i = i + 1; } if (nodeExpressionFunctionInputsExpressions.ChildNodes.Count > i) { return(CompilationLog.RaiseGeneratorError <ILanguageExpression>("Expecting a list of at most " + i + " expression as input to the macro call", node)); } break; default: return(CompilationLog.RaiseGeneratorError <ILanguageExpression>("Expecting a list of expressions or list of parameter assignments as input to the macro call", node)); } return(BasicPolyadic.Create(macro.OutputParameterType, macro, operands)); }
private ILanguageExpression translate_Expression_Function_Structure(GMacStructure structure, ILanguageExpressionAtomic defaultValueSource, ParseTreeNode node) { var operands = OperandsByValueAccess.Create(); if (node.ChildNodes.Count == 0) { return (defaultValueSource == null ? structure.CreateConstructorExpression(operands) : structure.CreateConstructorExpression(defaultValueSource, operands)); } var expressionFunctionInputsNode = node.ChildNodes[0]; var subNode = expressionFunctionInputsNode.ChildNodes[0]; switch (subNode.Term.ToString()) { case GMacParseNodeNames.ExpressionFunctionInputsAssignments: var expressionFunctionInputsAssignmentsNode = subNode; foreach (var nodeExpressionFunctionInputsAssignmentsItem in expressionFunctionInputsAssignmentsNode.ChildNodes) { var lhsNode = nodeExpressionFunctionInputsAssignmentsItem.ChildNodes[0].ChildNodes[0]; var rhsNode = nodeExpressionFunctionInputsAssignmentsItem.ChildNodes[1]; var lhsValAccess = GMacValueAccessGenerator.Translate_LValue_StructureMember(Context, lhsNode, structure); var rhsExpr = BasicExpressionGenerator.Generate_PolyadicOperand( lhsValAccess.ExpressionType, GMacExpressionGenerator.Translate(BasicExpressionGenerator, rhsNode) ); operands.AddOperand(lhsValAccess, rhsExpr); } break; case GMacParseNodeNames.ExpressionFunctionInputsExpressions: var expressionFunctionInputsExpressionsNode = subNode; var i = 0; foreach (var dataMember in structure.DataMembers) { if (i >= expressionFunctionInputsExpressionsNode.ChildNodes.Count) { break; } var rhsNode = expressionFunctionInputsExpressionsNode.ChildNodes[i]; var lhsValAccess = LanguageValueAccess.Create(dataMember); var rhsExpr = BasicExpressionGenerator.Generate_PolyadicOperand( lhsValAccess.ExpressionType, GMacExpressionGenerator.Translate(BasicExpressionGenerator, rhsNode) ); operands.AddOperand(lhsValAccess, rhsExpr); i = i + 1; } if (expressionFunctionInputsExpressionsNode.ChildNodes.Count > i) { return(CompilationLog.RaiseGeneratorError <ILanguageExpression>("Expecting a list of at most " + i + " expression as input to the structure construction", node)); } break; default: return(CompilationLog.RaiseGeneratorError <ILanguageExpression>("Expecting a list of expressions or a list of member assignments as input to the structure construction", node)); } return (defaultValueSource == null ? structure.CreateConstructorExpression(operands) : structure.CreateConstructorExpression(defaultValueSource, operands)); }
/// <summary> /// Create a composite type initialized constructor RHS expression based on the given command with /// partial LHS value access and a new temporary local variable as explained in Optimize_ReplaceAllLHSPartialAccess /// </summary> /// <param name="commandInfo"></param> /// <param name="newLvalue"></param> /// <returns></returns> private BasicPolyadic CreateConstructorExpression(HlCommandInfo commandInfo, SymbolLValue newLvalue) { var oldValueAccess = commandInfo.AssociatedCommand.LhsValueAccess; var oldLvalue = oldValueAccess.RootSymbolAsLValue; var firstDefStId = _lValuesTable.GetFirstDefiningCommandInfo(oldLvalue).CommandInfoId; var useDefaultSource = firstDefStId < 0 || firstDefStId != commandInfo.CommandInfoId; var typeStructure = oldValueAccess.RootSymbolAsLValue.SymbolType as GMacStructure; if (typeStructure != null) { var structure = typeStructure; var operands = OperandsByValueAccess.Create(); var dataMemberName = ((ValueAccessStepByKey <string>)oldValueAccess.LastAccessStep).AccessKey; var dataMember = structure.GetDataMember(dataMemberName); var operandLhsValueAccess = LanguageValueAccess.Create(dataMember); var operandRhsExpr = LanguageValueAccess.Create(newLvalue); operandLhsValueAccess.Append(oldValueAccess.AccessSteps.Skip(2)); operands.AddOperand(operandLhsValueAccess, operandRhsExpr); if (useDefaultSource) { return(structure.CreateConstructorExpression( LanguageValueAccess.Create(oldLvalue), operands )); } return(structure.CreateConstructorExpression(operands)); } if (!(oldValueAccess.RootSymbolAsLValue.SymbolType is GMacFrameMultivector)) { throw new InvalidOperationException("Unknown composite type to be constructed"); } var mvType = (GMacFrameMultivector)oldValueAccess.RootSymbolAsLValue.SymbolType; var operandsByIndex = OperandsByIndex.Create(); var stepByKey = oldValueAccess.LastAccessStep as ValueAccessStepByKey <int>; if (stepByKey != null) { var id = stepByKey.AccessKey; operandsByIndex.AddOperand(id, LanguageValueAccess.Create(newLvalue)); } else { var stepByKeyList = oldValueAccess.LastAccessStep as ValueAccessStepByKeyList <int>; if (stepByKeyList == null) { throw new InvalidOperationException("Invalid access step for a multivector"); } var idsList = stepByKeyList.AccessKeyList; foreach (var id in idsList) { operandsByIndex.AddOperand(id, LanguageValueAccess.Create(newLvalue).Append(id, ((GMacAst)BaseMacro.RootAst).ScalarType)); } } if (useDefaultSource) { return(mvType.CreateConstructorExpression( LanguageValueAccess.Create(oldLvalue), operandsByIndex )); } return(mvType.CreateConstructorExpression(operandsByIndex)); }