예제 #1
0
        public FieldGetContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node, MemberNameRepository nameRepo) : base(node)
        {
            this.OwnDataType = node.DataType;

            if (node.NodeString == 0)
            {
                accessor = SyntaxFactory.DefaultExpression(SyntaxUtil.ScriptTypeSyntax(node.DataType));
            }
            else
            {
                var stringVal = SyntaxUtil.GetScriptString(scenario, node);

                if (stringVal == "none")
                {
                    accessor = SyntaxFactory.DefaultExpression(SyntaxUtil.ScriptTypeSyntax(node.DataType));
                }
                else
                {
                    if (nameRepo.TryGetName(stringVal, node.DataType.ToString(), node.NodeData_H16, out var finalName))
                    {
                        accessor = SyntaxFactory.IdentifierName(finalName);
                    }
                    else
                    {
                        accessor = SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(stringVal));
                    }
                }
            }

            accessor = accessor.WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(node.DataType));
        }
예제 #2
0
        public IfStatementContext(ScenarioTag.ScriptSyntaxNode node, Scope containingScope) : base(node)
        {
            var resultVarName = "ifResult_" + this.GetHashCode();

            resultVariable = IdentifierName(resultVarName)
                             .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(containingScope.Type));
            this.containingScope = containingScope;
            this.producesValue   = containingScope.Type != ScriptDataType.Void;
            this.shouldHoist     = containingScope.IsInStatementContext == false && containingScope.SuppressHoisting == false;
        }
예제 #3
0
        public void GenerateInto(Scope scope)
        {
            Debug.Assert(operand != null, "Not enough operands for unary expression");

            scope.Context.AddExpression(
                SyntaxFactory.PrefixUnaryExpression(
                    operatorSyntaxKind,
                    SyntaxFactory.ParenthesizedExpression(operand))
                .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(this.OwnDataType.Value)));
        }
예제 #4
0
        public VariableAccessContext(ScenarioTag tag, ScenarioTag.ScriptSyntaxNode node) : base(node)
        {
            this.OwnDataType = node.DataType;

            access = SyntaxFactory.MemberAccessExpression(
                SyntaxKind.SimpleMemberAccessExpression,
                SyntaxFactory.ThisExpression(),
                SyntaxFactory.IdentifierName(
                    SyntaxUtil.SanitizeIdentifier(
                        SyntaxUtil.GetScriptString(tag, node))))
                     .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(node.DataType));
        }
예제 #5
0
        public ScriptInvocationContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node) : base(node)
        {
            var method = scenario.ScriptMethods[node.OperationId];

            invocation = SyntaxFactory.InvocationExpression(
                SyntaxFactory.MemberAccessExpression(
                    SyntaxKind.SimpleMemberAccessExpression,
                    SyntaxFactory.ThisExpression(),
                    SyntaxFactory.IdentifierName(
                        SyntaxUtil.SanitizeIdentifier(method.Description))))
                         .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(method.ReturnType));
        }
예제 #6
0
        public TagGetContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node) : base(node)
        {
            this.OwnDataType = node.DataType;

            invocation = InvocationExpression(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                     IdentifierName("Engine"),
                                                                     GenericName(Identifier(nameof(IScriptEngine.GetTag)))
                                                                     .WithTypeArgumentList(TypeArgumentList(SingletonSeparatedList(
                                                                                                                SyntaxUtil.ScriptTypeSyntax(this.OwnDataType.Value))))))
                         .AddArgumentListArguments(
                Argument(SyntaxUtil.LiteralExpression(SyntaxUtil.GetScriptString(scenario, node))),
                Argument(SyntaxUtil.LiteralExpression(node.NodeData_32)))
                         .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(node.DataType));
        }
예제 #7
0
        public void GenerateInto(Scope scope)
        {
            Debug.Assert(operands.Count >= 2, "Not enough operands for binary expression");

            var ops = new Queue <ExpressionSyntax>();

            foreach (var op in operands)
            {
                ops.Enqueue(op);
            }

            var            left    = ops.Dequeue();
            ScriptDataType?topType = this.OwnDataType;

            while (ops.Any())
            {
                var right = ops.Dequeue();

                var binExp = SyntaxFactory.BinaryExpression(operatorSyntaxKind,
                                                            left, right);

                if (numericPromotionOperators.Contains(this.operatorSyntaxKind) &&
                    SyntaxUtil.TryGetTypeOfExpression(left, out var leftType) &&
                    SyntaxUtil.TryGetTypeOfExpression(right, out var rightType))
                {
                    var promoted = SyntaxUtil.BinaryNumericPromotion(leftType, rightType);
                    binExp  = binExp.WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(promoted));
                    topType = promoted;
                }

                left = binExp;
            }

            if (topType.HasValue && topType.Value != scope.Type)
            {
                left = SyntaxUtil.CreateCast(topType.Value, scope.Type, SyntaxFactory.ParenthesizedExpression(left));
            }

            scope.Context.AddExpression(left);
        }
예제 #8
0
        public EntityGetContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node, MemberNameRepository nameRepo) : base(node)
        {
            this.OwnDataType = node.DataType;

            if (node.NodeString == 0)
            {
                accessor = SyntaxFactory.DefaultExpression(SyntaxUtil.ScriptTypeSyntax(node.DataType));
            }
            else
            {
                var stringVal = SyntaxUtil.GetScriptString(scenario, node);

                if (stringVal == "none")
                {
                    accessor = SyntaxFactory.DefaultExpression(SyntaxUtil.ScriptTypeSyntax(node.DataType));
                }
                else
                {
                    if (nameRepo.TryGetName(stringVal, nameof(ScenarioTag.EntityReference), node.NodeData_H16, out var finalName))
                    {
                        accessor = SyntaxFactory.IdentifierName(finalName);
                    }
                    else
                    {
                        accessor = SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(stringVal));
                    }

                    if (node.DataType != ScriptDataType.EntityIdentifier)
                    {
                        accessor = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                        accessor,
                                                                        SyntaxFactory.IdentifierName(nameof(ScenarioEntity <object> .Entity)));
                    }
                }
            }

            accessor = accessor.WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(node.DataType));
        }
예제 #9
0
        public void GenerateInto(Scope scope)
        {
            var invocationExpression = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                            SyntaxFactory.IdentifierName("Engine"),
                                                                            SyntaxFactory.IdentifierName(this.MethodName));

            ExpressionSyntax invocation = SyntaxFactory.InvocationExpression(invocationExpression)
                                          .WithArgumentList(SyntaxFactory.ArgumentList(
                                                                SyntaxFactory.SeparatedList(this.arguments)))
                                          .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(this.ReturnType));

            var tempArgs = new List <Type>();

            foreach (var t in argumentTypes)
            {
                if (t.HasValue && SyntaxUtil.TryGetTypeFromScriptType(t.Value, out var T))
                {
                    tempArgs.Add(T);
                }
                else
                {
                    break;
                }
            }

            if (tempArgs.Count == argumentTypes.Count)
            {
                // Do full overload match
                var method = typeof(IScriptEngine).GetMethod(this.MethodName,
                                                             BindingFlags.Public | BindingFlags.Instance,
                                                             null,
                                                             tempArgs.ToArray(),
                                                             null);

                if (method != null)
                {
                    SyntaxUtil.AwaitIfNeeded(method, ref invocation, out var materializedReturnType);

                    if (SyntaxUtil.TryGetScriptTypeFromType(materializedReturnType, out var fromType))
                    {
                        // Insert cast to destination
                        invocation = SyntaxUtil.CreateCast(fromType, this.ReturnType, invocation)
                                     .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(this.ReturnType));
                    }
                }
            }
            else
            {
                // Fallback to name only lookup
                var scriptEngineMethods = typeof(IScriptEngine).GetMethods().Where(m => m.Name == this.MethodName);

                if (scriptEngineMethods.Any())
                {
                    //var hasOverload = scriptEngineMethods.Any(m => m.ReturnType == destinationType);

                    //if (hasOverload == false)
                    {
                        var method = scriptEngineMethods.First();

                        SyntaxUtil.AwaitIfNeeded(method, ref invocation, out var materializedReturnType);

                        if (SyntaxUtil.TryGetScriptTypeFromType(materializedReturnType, out var fromType) && fromType != this.ReturnType)
                        {
                            // Insert cast to destination
                            invocation = SyntaxUtil.CreateCast(fromType, this.ReturnType, invocation)
                                         .WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(this.ReturnType));
                        }
                    }
                }
            }

            scope.Context.AddExpression(invocation);
        }
예제 #10
0
        public AiGetContext(ScenarioTag scenario, ScenarioTag.ScriptSyntaxNode node, MemberNameRepository nameRepo) : base(node)
        {
            this.OwnDataType = node.DataType;

            if (node.NodeString == 0)
            {
                accessor = SyntaxFactory.DefaultExpression(SyntaxUtil.ScriptTypeSyntax(node.DataType));
            }
            else
            {
                var stringVal = SyntaxUtil.GetScriptString(scenario, node);

                var slashIndex = stringVal.IndexOf('/');

                if (slashIndex > 0)
                {
                    Debug.Assert(node.NodeData_B0 == 192);

                    // It's a squad member accessor
                    var squadName  = stringVal.Substring(0, slashIndex);
                    var memberName = stringVal.Substring(slashIndex + 1);

                    if (nameRepo.TryGetName(squadName, node.DataType.ToString(), node.NodeData_B1, out var finalSquad) &&
                        nameRepo.NestedRepos.TryGetValue(finalSquad, out var nestedRepo) &&
                        nestedRepo.TryGetName(memberName, node.DataType.ToString(), node.NodeData_H16, out var finalProp))
                    {
                        accessor = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                        SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(finalSquad)),
                                                                        SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(finalProp)));
                    }
                    else
                    {
                        accessor = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                        SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(squadName)),
                                                                        SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(memberName)));
                    }
                }
                else
                {
                    // Ambiguous reference to either a squad or squad group...?
                    if (nameRepo.TryGetName(stringVal, node.DataType.ToString(), node.NodeData_H16, out var finalSquad))
                    {
                        if (nameRepo.NestedRepos.TryGetValue(finalSquad, out var nestedRepo))
                        {
                            accessor = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                            SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(finalSquad)),
                                                                            SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier("Squad")));
                        }
                        else
                        {
                            accessor = SyntaxFactory.IdentifierName(finalSquad);
                        }
                    }
                    else
                    {
                        accessor = SyntaxFactory.IdentifierName(SyntaxUtil.SanitizeIdentifier(stringVal));
                    }
                }
            }

            accessor = accessor.WithAdditionalAnnotations(ScriptGenAnnotations.TypeAnnotation(node.DataType));
        }