Exemplo n.º 1
0
        private void AssignInferredType(AstExpressionOperand operand, AstTypeDefinition typeDef)
        {
            var typeRef = AstTypeReferenceType.From(typeDef);

            typeRef.IsInferred = true;
            SymbolTable !.Add(typeRef);
            operand.SetTypeReference(typeRef);
        }
Exemplo n.º 2
0
        public override void VisitExpressionOperand(AstExpressionOperand operand)
        {
            operand.VisitChildren(this);

            if (operand.HasTypeReference)
            {
                return;
            }

            if (operand.HasExpression)
            {
                var expr = operand.Expression;
                Ast.Guard(expr.TypeReference, "AstExpression.TypeReference not set.");
                operand.SetTypeReference(expr.TypeReference);
                return;
            }

            var litBool = operand.LiteralBoolean;

            if (litBool is not null)
            {
                Ast.Guard(SymbolTable, "No SymbolTable set.");

                var typeDef = SymbolTable !.FindDefinition <AstTypeDefinition>(
                    AstIdentifierIntrinsic.Bool.SymbolName.CanonicalName, AstSymbolKind.Type);
                Ast.Guard(typeDef, "No AstTypeDefintion was found for Boolean.");
                AssignInferredType(operand, typeDef !);
                return;
            }

            var numeric = operand.LiteralNumeric;

            if (numeric is not null)
            {
                Ast.Guard(SymbolTable, "No SymbolTable set.");

                var typeDef = FindTypeByBitCount(numeric.GetBitCount(), numeric.Sign);
                Ast.Guard(typeDef, "No AstTypeDefintion was found by bit count.");
                AssignInferredType(operand, typeDef !);
                return;
            }

            var litString = operand.LiteralString;

            if (litString is not null)
            {
                Ast.Guard(SymbolTable, "No SymbolTable set.");

                var typeDef = SymbolTable !.FindDefinition <AstTypeDefinition>(
                    AstIdentifierIntrinsic.Str.SymbolName.CanonicalName, AstSymbolKind.Type);
                Ast.Guard(typeDef, "No AstTypeDefintion was found for String.");
                AssignInferredType(operand, typeDef !);
                return;
            }

            var var = operand.VariableReference;

            if (var is not null)
            {
                Ast.Guard(SymbolTable, "No SymbolTable was set.");
                Ast.Guard(var.Identifier, "Variable has no Identifier");

                if (!var.HasTypeReference)
                {
                    var def = (IAstTypeReferenceSite?)
                              var.VariableDefinition ?? var.ParameterDefinition;

                    var typeRef = def?.TypeReference;
                    if (typeRef is not null)
                    {
                        var.SetTypeReference(typeRef.MakeCopy());
                    }
                }

                if (var.HasTypeReference)
                {
                    operand.SetTypeReference(var.TypeReference.MakeCopy());
                }
            }

            var fld = operand.FieldReference;

            if (fld?.Symbol.IsDefined ?? false)
            {
                var enumOptDef = fld.Symbol.DefinitionAs <AstTypeDefinitionEnumOption>();
                if (enumOptDef is not null)
                {
                    var enumDef = enumOptDef.ParentAs <AstTypeDefinitionEnum>();
                    operand.SetTypeReference(AstTypeReferenceType.From(enumDef !));
                }
            }

            var fn = operand.FunctionReference;

            if (fn?.FunctionType.HasTypeReference ?? false)
            {
                operand.SetTypeReference(fn.FunctionType.TypeReference.MakeCopy());
            }

            if (operand.HasTypeReference)
            {
                Visit(operand.TypeReference);
            }
        }