/// <summary>
        /// Sets the target variables names for a multivector input\output variable parameter in the code block
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="grade"></param>
        /// <param name="indexList"></param>
        /// <param name="getTargetVarName"></param>
        /// <returns></returns>
        public GMacTargetVariablesNaming SetMultivectorParameters(AstDatastoreValueAccess valueAccess, int grade, IEnumerable <int> indexList, Func <int, string> getTargetVarName)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                return(this);
            }

            if (valueAccess.AssociatedValueAccess.ExpressionType.IsFrameMultivector() == false)
            {
                throw new InvalidOperationException("Specified macro parameter is not of multivector type");
            }

            //Find the parameters in the code block that are components of the given multivector value access
            var primitiveValueAccessList =
                CodeBlock.GetParametersValueAccess(
                    valueAccess.SelectMultivectorComponents(grade, indexList)
                    );

            foreach (var primitiveValueAccess in primitiveValueAccessList)
            {
                var id = primitiveValueAccess.GetBasisBladeId();

                var targetVarName = getTargetVarName(id);

                SetScalarParameter(primitiveValueAccess, targetVarName);
            }

            return(this);
        }
        /// <summary>
        /// Sets the target variables names for a multivector input\output variable parameter in the code block
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="getTargetVarName"></param>
        /// <returns></returns>
        public GMacTargetVariablesNaming SetMultivectorParameters(AstDatastoreValueAccess valueAccess, IDictionary <int, string> getTargetVarName)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                return(this);
            }

            if (valueAccess.AssociatedValueAccess.ExpressionType.IsFrameMultivector() == false)
            {
                throw new InvalidOperationException("Specified macro parameter is not of multivector type");
            }

            //Find the parameters in the code block that are components of the given multivector value access
            var primitiveValueAccessList = CodeBlock.GetParametersValueAccess(valueAccess);

            foreach (var primitiveValueAccess in primitiveValueAccessList)
            {
                var id = primitiveValueAccess.GetBasisBladeId();

                string targetVarName;

                if (getTargetVarName.TryGetValue(id, out targetVarName) == false)
                {
                    continue;
                }

                SetScalarParameter(primitiveValueAccess, targetVarName);
            }

            return(this);
        }
Exemple #3
0
        /// <summary>
        /// Bind a macro parameter of multivector type to a set of target language variables or constant values
        /// using a generating function acting on each basis blade of the multivector
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="bindingFunction"></param>
        /// <param name="ignoreNullPatterns"></param>
        /// <returns></returns>
        public GMacMacroBinding BindMultivectorUsing(AstDatastoreValueAccess valueAccess, Func <AstFrame, int, GMacScalarBinding> bindingFunction, bool ignoreNullPatterns = true)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                throw new ArgumentNullException(nameof(valueAccess));
            }

            if (valueAccess.AssociatedValueAccess.ExpressionType.IsFrameMultivector() == false)
            {
                throw new InvalidOperationException("Specified macro parameter is not of multivector type");
            }

            var frameInfo =
                new AstFrame(
                    ((GMacFrameMultivector)valueAccess.AssociatedValueAccess.ExpressionType).ParentFrame
                    );

            var primitiveValueAccessList =
                valueAccess.ExpandAll();

            foreach (var primitiveValueAccess in primitiveValueAccessList)
            {
                var id = primitiveValueAccess.GetBasisBladeId();

                var scalarPattern = bindingFunction(frameInfo, id);

                if (ignoreNullPatterns == false || scalarPattern != null)
                {
                    BindScalarToPattern(primitiveValueAccess, scalarPattern);
                }
            }

            return(this);
        }
Exemple #4
0
        /// <summary>
        /// Remove the given parameters from the binding pattern
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <returns></returns>
        public GMacMacroBinding UnBind(AstDatastoreValueAccess valueAccess)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                return(this);
            }

            if (valueAccess.IsScalar)
            {
                _patternDictionary.Remove(valueAccess.ValueAccessName);
                return(this);
            }

            var valueAccessNamesList =
                valueAccess
                .AssociatedValueAccess
                .ExpandAll()
                .Select(v => v.GetName());

            foreach (var valueAccessName in valueAccessNamesList)
            {
                _patternDictionary.Remove(valueAccessName);
            }

            return(this);
        }
Exemple #5
0
        /// <summary>
        /// Bind a macro parameter of any type to a pattern of the same type
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="pattern"></param>
        /// <returns></returns>
        public GMacMacroBinding BindToTreePattern(AstDatastoreValueAccess valueAccess, IGMacTypedBinding pattern)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                throw new ArgumentNullException(nameof(valueAccess));
            }

            if (valueAccess.AssociatedValueAccess.ExpressionType.IsSameType(pattern.GMacType.AssociatedType) == false)
            {
                throw new InvalidOperationException(
                          $"Specified macro parameter {valueAccess.ValueAccessName} of type {valueAccess.GMacTypeSignature} is not of same type {pattern.GMacType.GMacTypeSignature} as given pattern"
                          );
            }

            var assignmentsList = valueAccess.AssociatedValueAccess.ExpandAndAssignAll(pattern);

            foreach (var assignment in assignmentsList)
            {
                BindScalarToPattern(
                    assignment.Item1.ToAstDatastoreValueAccess(),
                    assignment.Item2
                    );
            }

            return(this);
        }
        /// <summary>
        /// Sets the target variables names for a multivector input\output variable parameter in the code block
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="subspace"></param>
        /// <param name="getTargetVarName"></param>
        /// <returns></returns>
        public GMacTargetVariablesNaming SetMultivectorParameters(AstDatastoreValueAccess valueAccess, AstFrameSubspace subspace, Func <int, string> getTargetVarName)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                return(this);
            }

            return(SetMultivectorParameters(valueAccess, subspace.BasisBladeIDs, getTargetVarName));
        }
Exemple #7
0
        /// <summary>
        /// If the given value access is a multivector this binds a given subspace to variables
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="grade"></param>
        /// <returns></returns>
        public GMacMacroBinding BindMultivectorPartToVariables(AstDatastoreValueAccess valueAccess, int grade)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                throw new ArgumentNullException(nameof(valueAccess));
            }

            return(BindToVariables(valueAccess.SelectMultivectorComponents(grade)));
        }
Exemple #8
0
        /// <summary>
        /// Find all primitive parameters in this code block that are sub-components of the given
        /// macro parameter value access component
        /// </summary>
        /// <param name="paramValueAccess"></param>
        /// <returns></returns>
        public IEnumerable <IGMacCbParameterVariable> GetParameters(AstDatastoreValueAccess paramValueAccess)
        {
            var result = new List <IGMacCbParameterVariable>();

            if (paramValueAccess.IsNullOrInvalid())
            {
                return(result);
            }

            var name = paramValueAccess.ValueAccessName;

            //A single parameter is to be found
            if (paramValueAccess.IsPrimitive)
            {
                var item = ParameterVariables.FirstOrDefault(
                    p => p.ValueAccessName == name
                    );

                if (ReferenceEquals(item, null) == false)
                {
                    result.Add(item);
                }

                return(result);
            }

            //Partial multivectors require special treatment
            if (paramValueAccess.IsPartialMultivector)
            {
                var primitiveValueAccessList = paramValueAccess.ExpandAll();

                foreach (var primitiveValueAccess in primitiveValueAccessList)
                {
                    IGMacCbParameterVariable paramVar;

                    if (TryGetParameterVariable(primitiveValueAccess, out paramVar))
                    {
                        result.Add(paramVar);
                    }
                }

                return(result);
            }

            //All other cases can be searched by name
            name = name + ".";

            result.AddRange(
                ParameterVariables.Where(
                    p => p.ValueAccessName.IndexOf(name, StringComparison.Ordinal) == 0
                    )
                );

            return(result);
        }
        /// <summary>
        /// Sets the target variables name for a scalar input\output variable parameter in the code block
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="targetVarName"></param>
        /// <returns></returns>
        public GMacTargetVariablesNaming SetScalarParameter(AstDatastoreValueAccess valueAccess, string targetVarName)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                return(this);
            }

            IGMacCbParameterVariable paramVar;

            if (CodeBlock.TryGetParameterVariable(valueAccess, out paramVar))
            {
                paramVar.TargetVariableName = targetVarName;
            }

            return(this);
        }
        /// <summary>
        /// Sets the target variables names for an input\output variable parameter in the code block
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="getTargetVarName"></param>
        /// <returns></returns>
        public GMacTargetVariablesNaming SetParameters(AstDatastoreValueAccess valueAccess, Func <IGMacCbParameterVariable, string> getTargetVarName)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                return(this);
            }

            //Find the parameters in the code block that are components of the given value access
            var paramVarsList = CodeBlock.GetParameters(valueAccess);

            foreach (var paramVar in paramVarsList)
            {
                paramVar.TargetVariableName = getTargetVarName(paramVar);
            }

            return(this);
        }
        /// <summary>
        /// Sets the target variables names for an input\output parameter
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="getTargetVarName"></param>
        /// <returns></returns>
        public GMacTargetVariablesNaming SetParameters(AstDatastoreValueAccess valueAccess, Func <AstDatastoreValueAccess, string> getTargetVarName)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                return(this);
            }

            //Find the parameters in the code block that are components of the given value access
            var primitiveValueAccessList = CodeBlock.GetParametersValueAccess(valueAccess);

            foreach (var primitiveValueAccess in primitiveValueAccessList)
            {
                var targetVarName = getTargetVarName(primitiveValueAccess);

                SetScalarParameter(primitiveValueAccess, targetVarName);
            }

            return(this);
        }
Exemple #12
0
        /// <summary>
        /// Bind a macro parameter of any type to a set of variables
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <returns></returns>
        public GMacMacroBinding BindToVariables(AstDatastoreValueAccess valueAccess)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                throw new ArgumentNullException(nameof(valueAccess));
            }

            if (valueAccess.IsScalar)
            {
                BindScalarToPattern(valueAccess, GMacScalarBinding.CreateVariable(BaseMacro.Root));

                return(this);
            }

            var primitiveValueAccessList = valueAccess.ExpandAll();

            foreach (var primitiveValueAccess in primitiveValueAccessList)
            {
                BindScalarToPattern(primitiveValueAccess, GMacScalarBinding.CreateVariable(BaseMacro.Root));
            }

            return(this);
        }
        /// <summary>
        /// Sets the target variables names for an input\output variable parameter in the code block
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="targetVarNamesDict"></param>
        /// <returns></returns>
        public GMacTargetVariablesNaming SetParameters(AstDatastoreValueAccess valueAccess, IDictionary <string, string> targetVarNamesDict)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                return(this);
            }

            //Find the parameters in the code block that are components of the given value access
            var primitiveValueAccessList = CodeBlock.GetParametersValueAccess(valueAccess);

            foreach (var primitiveValueAccess in primitiveValueAccessList)
            {
                var name = primitiveValueAccess.ValueAccessName;

                string targetVarName;

                if (targetVarNamesDict.TryGetValue(name, out targetVarName))
                {
                    SetScalarParameter(primitiveValueAccess, targetVarName);
                }
            }

            return(this);
        }
Exemple #14
0
        /// <summary>
        /// Bind a macro parameter of any type to a constant of the same type
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public GMacMacroBinding BindToConstants(AstDatastoreValueAccess valueAccess, AstValue value)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                throw new ArgumentNullException(nameof(valueAccess));
            }

            //This is checked inside each primitive binding to select appropriate action according to the
            // BindOutputToConstantBehavior mamber
            //if (valueAccess.IsInputParameter == false)
            //    throw new InvalidOperationException(
            //        String.Format(
            //            "Specified value access {0} is not a macro input parameter",
            //            valueAccess.ValueAccessName
            //            )
            //        );

            if (valueAccess.AssociatedValueAccess.ExpressionType.IsSameType(value.AssociatedValue.ExpressionType) == false)
            {
                throw new InvalidOperationException(
                          $"Specified macro parameter {valueAccess.ValueAccessName} of type {valueAccess.GMacTypeSignature} is not of same type {value.GMacTypeSignature} as given value"
                          );
            }

            var assignmentsList = valueAccess.AssociatedValueAccess.ExpandAndAssignAll(value.AssociatedValue);

            foreach (var assignment in assignmentsList)
            {
                BindScalarToConstant(
                    assignment.Item1.ToAstDatastoreValueAccess(),
                    assignment.Item2.ToExpr()
                    );
            }

            return(this);
        }
Exemple #15
0
        /// <summary>
        /// All binding methods eventually call this one so all checks are performed here
        /// If the given scalar binding is null the scalar macro parameter is un-bound
        /// </summary>
        /// <param name="valueAccess"></param>
        /// <param name="scalarBinding"></param>
        /// <returns></returns>
        public GMacMacroBinding BindScalarToPattern(AstDatastoreValueAccess valueAccess, GMacScalarBinding scalarBinding)
        {
            if (valueAccess.IsNullOrInvalid())
            {
                throw new ArgumentNullException(nameof(valueAccess));
            }

            var valueAccessName = valueAccess.ValueAccessName;

            if (valueAccess.IsMacroParameter == false || valueAccess.IsScalar == false)
            {
                throw new InvalidOperationException(
                          $"Unable to bind the value access {valueAccessName} as it's either non-scalar or not a macro parameter"
                          );
            }

            if (scalarBinding == null)
            {
                return(UnBind(valueAccess));
            }

            if (valueAccess.AssociatedValueAccess.RootSymbol.ParentLanguageSymbol.ObjectId != AssociatedMacro.ObjectId)
            {
                throw new InvalidOperationException(
                          $"Unable to bind the value access {valueAccessName} as it's not a peremeter of the macro {AssociatedMacro.SymbolAccessName}"
                          );
            }

            GMacMacroParameterBinding paramBinding = null;

            if (valueAccess.IsOutputParameter && scalarBinding.IsConstant)
            {
                switch (BindOutputToConstantBehavior)
                {
                case GMacBindOutputToConstantBehavior.Prevent:
                    throw new InvalidOperationException(
                              $"Unable to bind the output macro parameter {valueAccessName} to a constant"
                              );

                case GMacBindOutputToConstantBehavior.Ignore:
                    return(this);

                case GMacBindOutputToConstantBehavior.BindToVariable:
                    paramBinding = GMacMacroParameterBinding.CreateVariable(valueAccess);
                    break;
                }
            }
            else
            {
                paramBinding = GMacMacroParameterBinding.Create(valueAccess, scalarBinding);
            }

            //If the value access already exists remove it from the dictionary to preserve
            //order of parameters bindings
            if (_patternDictionary.ContainsKey(valueAccessName))
            {
                _patternDictionary.Remove(valueAccessName);
            }

            _patternDictionary.Add(valueAccessName, paramBinding);

            return(this);
        }