Example #1
0
        static string BuildArgumentValues(
            IFunctionInstance function,
            NamedCollection <IArgumentDeclaration> arguments,
            INamedExpressionTuple expressions,
            ICppScope scope,
            string kind)
        {
            if (arguments.IsEmpty())
            {
                return(string.Empty);
            }
            var name     = scope.MakeLocalName();
            var typeName = GetFunctionTypeName(function.Name, kind);

            scope.Runtime.AddLine($"{typeName} {name};");
            var argN = 0;

            foreach (var expression in expressions.Tuple)
            {
                var argument = arguments[argN];
                argN++;
                var value = Dynamic((dynamic)expression.Expression, scope);
                if (argument.IsAssignable)
                {
                    scope.Runtime.AddLine($"{name}.{CppEscape(argument.Name)} = &{value};");
                }
                else
                {
                    scope.Runtime.AddLine($"{name}.{CppEscape(argument.Name)} = {value};");
                }
            }
            return(name);
        }
Example #2
0
        static void BuildArgumentValues(
            ILocalValueScope localValues,
            INamedExpressionTuple expressions,
            ILocalIdentifierScope argumentScope,
            ArgumentInstanceCollection arguments,
            IContext argumentContext,
            IContext functionContext)
        {
            var argN = 0;

            foreach (var expression in expressions.Tuple)
            {
                var argumentName = expression.Name;
                if (string.IsNullOrEmpty(argumentName))
                {
                    argumentName = arguments[argN].Name;
                    argN++;
                }
                var argument = (IArgumentInstance)argumentScope[argumentName];
                var value    = Dynamic((dynamic)expression.Expression, argumentContext);
                var casted   = ImplicitCast(value, argument.Type);
                localValues.Add(argument, casted);
            }
            for (; argN < arguments.Count; argN++)
            {
                var argument = arguments[argN];
                var value    = Dynamic((dynamic)argument.Argument.Value, functionContext);
                localValues.Add(argument, value);
            }
        }
Example #3
0
 void AssertNamedExpressionTuple(INamedExpressionTuple expected, INamedExpressionTuple actual, string label = "")
 {
     Assert.AreEqual(expected.Tuple.Count, actual.Tuple.Count, $"{label}.Tuple.Count");
     for (var i = 0; i < expected.Tuple.Count; i++)
     {
         AssertNamedExpression(expected.Tuple[i], actual.Tuple[i], label: $"{label}.Tuple[{i}]");
     }
 }
Example #4
0
 static ITypedValue ImplicitCast(INamedExpressionTuple tuple, IModuleInstance type)
 {
     if (tuple.Tuple.Count == 1)
     {
         return(ImplicitCast((dynamic)tuple.Tuple.First().Expression, type));
     }
     throw new ArgumentException(message: "Invalid argument tuple");
 }
Example #5
0
        static IExpression Dynamic(INamedExpressionTuple expressionTuple, IContext context)
        {
            IExpression result = null;

            foreach (var sub in expressionTuple.Tuple)
            {
                result = Dynamic((dynamic)sub.Expression, context);
            }
            return(result);
        }
Example #6
0
        static string Dynamic(INamedExpressionTuple expressionTuple, ICppScope scope)
        {
            string result = null;

            foreach (var sub in expressionTuple.Tuple)
            {
                result = Dynamic((dynamic)sub.Expression, scope);
            }
            return(result);
        }
Example #7
0
        static IExpression ParseResolved(
            IFunctionOverloads function,
            INamedExpressionTuple leftArguments,
            IEnumerator <TokenData> tokens,
            IContext context,
            ref bool done)
        {
            var pool = function.Overloads;

            return(ParseFunctionOverloads(pool, leftArguments, tokens, context, ref done));
        }
Example #8
0
        static IExpression CreateFunctionInvocation(
            IList <IFunctionInstance> pool,
            TextFileRange range,
            INamedExpressionTuple leftArguments,
            INamedExpressionTuple rightArguments)
        {
            var filteredPool = FilterFunctionLeftArguments(pool, leftArguments);

            filteredPool = FilterFunctionRightArguments(filteredPool, rightArguments);
            return(filteredPool.Count != 1 ? null : CreateFunctionInvocation(filteredPool.First(), range, leftArguments, rightArguments));
            // TODO: proper error handling
        }
Example #9
0
 static IList <IFunctionInstance> ParseAndFilterFunctionRightArguments(
     IList <IFunctionInstance> pool,
     ref INamedExpressionTuple rightArguments,
     IEnumerator <TokenData> tokens,
     IContext context,
     ref bool done)
 {
     if (!pool.IsEmpty() && (pool.Count != 1 || pool[0].RightArguments.Count != 0))
     {
         rightArguments = Parse(tokens, context, ref done);
         return(FilterFunctionRightArguments(pool, rightArguments));
     }
     return(pool);
 }
Example #10
0
        static IExpression CreateFunctionInvocation(
            IFunctionInstance function,
            TextFileRange range,
            INamedExpressionTuple leftArguments,
            INamedExpressionTuple rightArguments)
        {
            var invocation = new FunctionInvocation {
                Function = function,
                Range    = range,
                Left     = AssignArguments(function.LeftArguments, leftArguments),
                Right    = AssignArguments(function.RightArguments, rightArguments)
            };

            return(invocation);
        }
Example #11
0
        static IExpression ParseResolved(
            ITypedInstance typed,
            INamedExpressionTuple leftArguments,
            IEnumerator <TokenData> tokens,
            IContext context,
            ref bool done)
        {
            var result = new TypedReference {
                Range    = tokens.Current.Range,
                Type     = typed.Type,
                Instance = typed
            };

            if (!tokens.MoveNext())
            {
                done = true;
            }
            return(result);
        }
Example #12
0
        static IExpression ParseFunctionOverloads(IList <IFunctionInstance> pool, INamedExpressionTuple leftArguments, IEnumerator <TokenData> tokens, IContext context, ref bool done)
        {
            var range = tokens.Current.Range;
            INamedExpressionTuple rightArguments = new NamedExpressionTuple();

            if (!tokens.MoveNext())
            {
                done = true;
                return(CreateFunctionInvocation(pool, range, leftArguments, rightArguments));
            }

            var filteredPool = FilterFunctionLeftArguments(pool, leftArguments);

            filteredPool = ParseAndFilterFunctionRightArguments(filteredPool, ref rightArguments, tokens, context, ref done);
            if (filteredPool.Count != 1)
            {
                return(null);
            }
            // TODO: proper error handling
            return(CreateFunctionInvocation(filteredPool.First(), range, leftArguments, rightArguments));
        }
Example #13
0
        static void ExtractArgumentReferenceValues(
            ILocalValueScope localValues,
            INamedExpressionTuple expressions,
            ArgumentInstanceCollection arguments,
            IContext callerContext)
        {
            var argN = 0;

            foreach (var expression in expressions.Tuple)
            {
                var argument = arguments[argN];

                argN++;
                if (argument.Argument.IsAssignable && expression.Expression is ITypedReference reference)
                {
                    var referenceDecl = callerContext.Values[reference.Instance];
                    var value         = localValues[argument];
                    var casted        = ImplicitCast(value, referenceDecl.Type);
                    Array.Copy(casted.Data, referenceDecl.Data, referenceDecl.Data.Length);
                }
            }
        }
Example #14
0
        static INamedExpressionTuple ParseResult(INamedExpressionTuple result, IEnumerator <TokenData> tokens, IContext context, ref bool done)
        {
            while (!done)
            {
                var token = tokens.Current;
                switch (token.Type)
                {
                case Token.OperatorLiteral:
                    var    operatorLiteral            = (IIdentifierLiteral)token.Data;
                    var    itentifyerLiteralList      = new List <TokenData>();
                    string operatorLiteralContent     = operatorLiteral.Content;
                    string operatorLiteralContentTail = "";
                    string notFoundLiteral            = "";
                    while (!operatorLiteralContent.IsEmpty())
                    {
                        if (operatorLiteralContent == "&")
                        {
                            if (!tokens.MoveNext())
                            {
                                done = true;
                            }
                            if (done)
                            {
                                return(result);          // TODO: report error: missing tokens
                            }
                            var inner      = Parse(tokens, context, ref done);
                            var execResult = CompileTime.Execute(inner, context);
                            if (execResult != null)
                            {
                                if (execResult is INamedExpressionTuple execNamedTuple)
                                {
                                    result.Tuple.AddRange(execNamedTuple.Tuple);
                                }
                                else
                                {
                                    result.Tuple.Add(new NamedExpression {
                                        Expression = execResult
                                    });
                                }
                            }
                            continue;
                        }

                        var resolve = context.Identifiers[operatorLiteralContent];
                        if (resolve == null)
                        {
                            if (operatorLiteralContent.Length == 1)
                            {
                                notFoundLiteral           += operatorLiteralContent;
                                operatorLiteralContent     = operatorLiteralContentTail;
                                operatorLiteralContentTail = "";
                            }
                            else
                            {
                                operatorLiteralContentTail = operatorLiteralContent.Last() + operatorLiteralContentTail;
                                operatorLiteralContent     = operatorLiteralContent.Substring(0, operatorLiteralContent.Length - 1);
                            }
                        }
                        else
                        {
                            if (!notFoundLiteral.IsEmpty())
                            {
                                itentifyerLiteralList.Add(new TokenData
                                {
                                    Type = Token.IdentifierLiteral,
                                    Data = new IdentifierLiteral {
                                        Content = notFoundLiteral
                                    }
                                });
                                notFoundLiteral = "";
                            }
                            itentifyerLiteralList.Add(new TokenData
                            {
                                Type = Token.IdentifierLiteral,
                                Data = new IdentifierLiteral {
                                    Content = operatorLiteralContent
                                }
                                // TODO Error and Range
                            });
                            operatorLiteralContent     = operatorLiteralContentTail;
                            operatorLiteralContentTail = "";
                        }
                    }

                    if (!notFoundLiteral.IsEmpty())
                    {
                        itentifyerLiteralList.Add(new TokenData
                        {
                            Type = Token.IdentifierLiteral,
                            Data = new IdentifierLiteral {
                                Content = notFoundLiteral
                            }
                        });
                    }

                    using (var newTokens = itentifyerLiteralList.Before(tokens).GetEnumerator())
                    {
                        return(ParseResult(result, newTokens, context, ref done));
                    }

                case Token.IdentifierLiteral:
                    var identifierLiteral = (IIdentifierLiteral)token.Data;
                    var resolved          = context.Identifiers[identifierLiteral.Content];
                    if (null != resolved)
                    {
                        var subexpression = ParseResolved((dynamic)resolved, result, tokens, context, ref done);
                        result.Tuple.Add(new NamedExpression {
                            Expression = subexpression ?? identifierLiteral
                        });
                        continue;
                    }
                    result.Tuple.Add(new NamedExpression {
                        Expression = identifierLiteral
                    });
                    break;

                case Token.StringLiteral:
                    var stringLiteral = (IStringLiteral)token.Data;
                    result.Tuple.Add(new NamedExpression {
                        Expression = stringLiteral
                    });
                    break;

                case Token.NumberLiteral:
                    var numberLiteral = (INumberLiteral)token.Data;
                    result.Tuple.Add(new NamedExpression {
                        Expression = numberLiteral
                    });
                    break;

                case Token.BlockStartIndentation:
                    var tokenBlock = (IBlockLiteral)token.Data;
                    result.Tuple.Add(new NamedExpression {
                        Expression = tokenBlock
                    });
                    break;
                }
                if (done)
                {
                    break;
                }
                if (!tokens.MoveNext())
                {
                    done = true;
                }
            }
            return(result);
        }
Example #15
0
        static INamedExpressionTuple AssignArguments(NamedCollection <IArgumentInstance> instances, INamedExpressionTuple arguments)
        {
            var result = new NamedExpressionTuple();
            var o      = arguments.Tuple.Count - instances.Count;

            foreach (var instance in instances)
            {
                // TODO: check that conversion exists
                result.Tuple.Add(arguments.Tuple[o]);
                arguments.Tuple.RemoveAt(o);
            }
            // TODO: check that enough arguments are given
            return(result);
        }
Example #16
0
 static IList <IFunctionInstance> FilterFunctionRightArguments(IList <IFunctionInstance> pool, INamedExpressionTuple rightArguments)
 {
     return(pool.Where(
                f => f.Declaration.RightArguments == null ||
                f.Declaration.MandatoryRightArgumentCount() <= rightArguments.Tuple.Count &&
                (f.Declaration.MaxRightArgumentCount() == null || !(f.Declaration.MaxRightArgumentCount() < rightArguments.Tuple.Count))).ToList());
 }
Example #17
0
 static IList <IFunctionInstance> FilterFunctionLeftArguments(IList <IFunctionInstance> pool, INamedExpressionTuple leftArguments)
 {
     return(pool.Where(
                f => {
         if (f.Declaration.LeftArguments == null)
         {
             return true;
         }
         if (f.Declaration.LeftArguments.Count > leftArguments.Tuple.Count)
         {
             return false;
         }
         var o = leftArguments.Tuple.Count - f.Declaration.LeftArguments.Count;
         foreach (var fArg in f.Declaration.LeftArguments)
         {
             var givenArg = leftArguments.Tuple[o];
             if (!CanImplicitConvertExpressionTo(givenArg.Expression, fArg.Type))
             {
                 return false;
             }
             o++;
         }
         return f.Declaration.LeftArguments.Count <= leftArguments.Tuple.Count;
     }).ToList());
 }