private FixedList<DataType> ResolveTypesInParameters(
             FunctionDeclarationSyntax function,
             ExpressionTypeResolver expressionResolver)
        {
            var types = new List<DataType>();
            foreach (var parameter in function.Parameters)
                switch (parameter)
                {
                    case NamedParameterSyntax namedParameter:
                    {
                        parameter.Type.BeginFulfilling();
                        var type =
                            expressionResolver.CheckAndEvaluateTypeExpression(namedParameter
                                .TypeExpression);
                        types.Add(parameter.Type.Fulfill(type));
                    }
                    break;
                    case SelfParameterSyntax _:
                        // Skip, we have already handled the self parameter
                        break;
                    case FieldParameterSyntax fieldParameter:
                        throw new NotImplementedException();
                    default:
                        throw NonExhaustiveMatchException.For(parameter);
                }

            return types.ToFixedList();
        }
        public static string ToSymbolString(this UnaryOperator @operator)
        {
            switch (@operator)
            {
            case UnaryOperator.At:
                return("@");

            case UnaryOperator.Not:
                return("not ");

            case UnaryOperator.Caret:
                return("^");

            case UnaryOperator.Minus:
                return("-");

            case UnaryOperator.Plus:
                return("+");

            case UnaryOperator.Question:
                return("?");

            default:
                throw NonExhaustiveMatchException.For(@operator);
            }
        }
        public override void VisitExpression(ExpressionSyntax expression, Void args)
        {
            base.VisitExpression(expression, args);
            // If it already has a value mode, we are good
            if (expression == null || expression.ValueSemantics != null)
            {
                return;
            }

            var type = expression.Type;

            switch (type)
            {
            case NeverType _:
                expression.ValueSemantics = ValueSemantics.Never;
                break;

            case ReferenceType _:
            case UnknownType _:
                expression.ValueSemantics = ValueSemantics.Copy;
                break;

            case ValueType valueType:
                expression.ValueSemantics = valueType.Semantics;
                break;

            default:
                throw NonExhaustiveMatchException.For(type);
            }
        }
示例#4
0
        private void InferExpressionTypeInInvocation(ExpressionSyntax callee, FixedList <DataType> argumentTypes)
        {
            switch (callee)
            {
            case IdentifierNameSyntax identifierName:
            {
                var symbols = identifierName.LookupInContainingScope();
                symbols = ResolveOverload(symbols, null, argumentTypes);
                AssignReferencedSymbolAndType(identifierName, symbols);
            }
            break;

            case MemberAccessExpressionSyntax memberAccess:
            {
                var left             = InferExpressionType(memberAccess.Expression);
                var containingSymbol = GetSymbolForType(left);
                var symbols          = containingSymbol.Lookup(memberAccess.Member.Name);
                symbols           = ResolveOverload(symbols, left, argumentTypes);
                memberAccess.Type = AssignReferencedSymbolAndType(memberAccess.Member, symbols);
            }
            break;

            default:
                throw NonExhaustiveMatchException.For(callee);
            }
        }
        public string Convert(DataType type)
        {
            switch (type)
            {
            case VoidType _:
                return("void");

            case SimpleType simpleType:
                return(nameMangler.Mangle(simpleType.Name));

            case ObjectType t:
                return(nameMangler.Mangle(t));

            case PointerType ptr:
                var referenced = ptr.Referent.AssertResolved();
                if (referenced == DataType.Any)
                {
                    return("void*");
                }
                return(Convert(referenced) + "*");

            case FunctionType functionType:
                return($"{Convert(functionType.ReturnType)}(*)({string.Join(", ", functionType.ParameterTypes.Select(Convert))})");

            default:
                throw NonExhaustiveMatchException.For(type);
            }
        }
        private static void BuildScopesInFunctionParameters(
            LexicalScope containingScope,
            FunctionDeclarationSyntax function,
            ExpressionLexicalScopesBuilder binder)
        {
            if (function.GenericParameters != null)
            {
                foreach (var parameter in function.GenericParameters)
                {
                    binder.VisitExpression(parameter.TypeExpression, containingScope);
                }
            }

            foreach (var parameter in function.Parameters)
            {
                switch (parameter)
                {
                case NamedParameterSyntax namedParameter:
                    binder.VisitExpression(namedParameter.TypeExpression, containingScope);
                    break;

                case SelfParameterSyntax _:
                case FieldParameterSyntax _:
                    // Nothing to bind
                    break;

                default:
                    throw NonExhaustiveMatchException.For(parameter);
                }
            }
        }
        private LexicalScope BuildNamespaceScopes(
            LexicalScope containingScope,
            RootName ns)
        {
            Name name;

            switch (ns)
            {
            case GlobalNamespaceName _:
                return(containingScope);

            case QualifiedName qualifiedName:
                containingScope = BuildNamespaceScopes(containingScope, qualifiedName.Qualifier);
                name            = qualifiedName;
                break;

            case SimpleName simpleName:
                name = simpleName;
                break;

            default:
                throw NonExhaustiveMatchException.For(ns);
            }

            var symbolsInNamespace       = allSymbols.Where(s => s.FullName.HasQualifier(name));
            var symbolsNestedInNamespace = allSymbols.Where(s => s.FullName.IsNestedIn(name));

            return(new NestedScope(containingScope, symbolsInNamespace, symbolsNestedInNamespace));
        }
示例#8
0
        public void Emit(Declaration declaration, Code code)
        {
            switch (declaration)
            {
            case FunctionDeclaration function:
                if (function.IsExternal)
                {
                    EmitExternalFunctionSignature(function, code);
                }
                else
                {
                    EmitFunction(function, code);
                }
                break;

            case ConstructorDeclaration constructor:
                EmitConstructor(constructor, code);
                break;

            case TypeDeclaration type:
                EmitType(type, code);
                break;

            default:
                throw NonExhaustiveMatchException.For(declaration);
            }
        }
        private static void AcquireClaim(
            Place assignToPlace,
            Operand operand,
            HashSet <Claim> claimsBeforeStatement,
            HashSet <Claim> claimsAfterStatement)
        {
            switch (operand)
            {
            case Place place:
                var coreVariable = place.CoreVariable();
                var claim        = claimsBeforeStatement.SingleOrDefault(t => t.Variable == coreVariable);
                // Copy types don't have claims right now
                if (claim != null && assignToPlace != null)     // copy types don't have claims right now
                {
                    var loan = new Loan(assignToPlace.CoreVariable(),
                                        operand,
                                        claim.ObjectId);
                    if (!claimsAfterStatement.Contains(loan))
                    {
                        claimsAfterStatement.Add(loan);
                    }
                }
                break;

            case Constant _:
                // no loans to acquire
                break;

            default:
                throw NonExhaustiveMatchException.For(operand);
            }
        }
        private string ConvertPlace(Place place)
        {
            switch (place)
            {
            case VariableReference variable:
                return("_" + NameOf(variable));

            default:
                throw NonExhaustiveMatchException.For(place);
            }
        }
        private Place ConvertToPlace(ExpressionSyntax value)
        {
            switch (value)
            {
            case IdentifierNameSyntax identifier:
                // TODO what if this isn't just a variable?
                return(graph.VariableFor(identifier.ReferencedSymbol.FullName.UnqualifiedName));

            default:
                throw NonExhaustiveMatchException.For(value);
            }
        }
示例#12
0
        private static void GatherRestrictions(Operand operand, List <Restriction> restrictions)
        {
            switch (operand)
            {
            case Place place:
                //case VariableReference variable:
                restrictions.Add(new Restriction(place.CoreVariable(), false));
                break;

            default:
                throw NonExhaustiveMatchException.For(operand);
            }
        }
示例#13
0
        private static void EnlivenVariables(BitArray variables, Value value)
        {
            switch (value)
            {
            case ConstructorCall constructorCall:
                foreach (var argument in constructorCall.Arguments)
                {
                    EnlivenVariables(variables, argument);
                }
                break;

            case UnaryOperation unaryOperation:
                EnlivenVariables(variables, unaryOperation.Operand);
                break;

            case BinaryOperation binaryOperation:
                EnlivenVariables(variables, binaryOperation.LeftOperand);
                EnlivenVariables(variables, binaryOperation.RightOperand);
                break;

            case Place place:
                variables[place.CoreVariable()] = true;
                break;

            case FunctionCall functionCall:
                if (functionCall.Self != null)
                {
                    EnlivenVariables(variables, functionCall.Self);
                }
                foreach (var argument in functionCall.Arguments)
                {
                    EnlivenVariables(variables, argument);
                }
                break;

            case VirtualFunctionCall virtualFunctionCall:
                EnlivenVariables(variables, virtualFunctionCall.Self);
                foreach (var argument in virtualFunctionCall.Arguments)
                {
                    EnlivenVariables(variables, argument);
                }
                break;

            case Constant _:
                // No variables
                break;

            default:
                throw NonExhaustiveMatchException.For(value);
            }
        }
        private string ConvertType(DataType type)
        {
            switch (type)
            {
            case ObjectType objectType:
                return(nameMangler.Mangle(objectType));

            case SimpleType simpleType:
                return(nameMangler.Mangle(simpleType.Name));

            default:
                throw NonExhaustiveMatchException.For(type);
            }
        }
示例#15
0
        private static Parameter BuildParameter(ParameterSyntax parameter)
        {
            switch (parameter)
            {
            case NamedParameterSyntax namedParameter:
                return(new Parameter(namedParameter.MutableBinding, namedParameter.Name, namedParameter.Type.Resolved()));

            case SelfParameterSyntax selfParameter:
                return(new Parameter(selfParameter.MutableBinding, selfParameter.Name, selfParameter.Type.Resolved()));

            default:
                throw NonExhaustiveMatchException.For(parameter);
            }
        }
示例#16
0
        public override Name Qualify(Name name)
        {
            switch (name)
            {
            case SimpleName simpleName:
                return(new QualifiedName(this, simpleName));

            case QualifiedName qualifiedName:
                return(new QualifiedName(Qualify(qualifiedName.Qualifier), qualifiedName.UnqualifiedName));

            default:
                throw NonExhaustiveMatchException.For(name);
            }
        }
示例#17
0
        private static int EstimateSize(Name name)
        {
            switch (name)
            {
            case QualifiedName qualifiedName:
                return(EstimateSize(qualifiedName.Qualifier) + 1 +
                       EstimateSize(qualifiedName.UnqualifiedName));

            case SimpleName simpleName:
                return(1 + simpleName.Text.Length);

            default:
                throw NonExhaustiveMatchException.For(name);
            }
        }
示例#18
0
        private static void KillVariables(BitArray variables, Place lvalue)
        {
            switch (lvalue)
            {
            case Dereference dereference:
                KillVariables(variables, dereference.DereferencedValue);
                break;

            case VariableReference variableReference:
                variables[variableReference.VariableNumber] = false;
                break;

            default:
                throw NonExhaustiveMatchException.For(lvalue);
            }
        }
        public void Check(MemberDeclarationSyntax declaration)
        {
            switch (declaration)
            {
            case TypeDeclarationSyntax typeDeclaration:
                Check(typeDeclaration);
                break;

            case FunctionDeclarationSyntax function:
                Check(function);
                break;

            default:
                throw NonExhaustiveMatchException.For(declaration);
            }
        }
        public virtual void VisitTypeDeclaration(TypeDeclarationSyntax typeDeclaration, A args)
        {
            switch (typeDeclaration)
            {
            case ClassDeclarationSyntax classDeclaration:
                VisitClassDeclaration(classDeclaration, args);
                break;

            case null:
                // Ignore
                break;

            default:
                throw NonExhaustiveMatchException.For(typeDeclaration);
            }
        }
示例#21
0
        private DataType InferMemberAccessType(MemberAccessExpressionSyntax memberAccess)
        {
            var left   = InferExpressionType(memberAccess.Expression);
            var symbol = GetSymbolForType(left);

            switch (memberAccess.Member)
            {
            case IdentifierNameSyntax identifier:
                var memberSymbols = symbol.Lookup(identifier.Name);
                var type          = AssignReferencedSymbolAndType(identifier, memberSymbols);
                return(memberAccess.Type = type);

            default:
                throw NonExhaustiveMatchException.For(memberAccess.Member);
            }
        }
示例#22
0
        public void ResolveTypesInStatement(StatementSyntax statement)
        {
            switch (statement)
            {
            case VariableDeclarationStatementSyntax variableDeclaration:
                ResolveTypesInVariableDeclaration(variableDeclaration);
                break;

            case ExpressionSyntax expression:
                InferExpressionType(expression);
                break;

            default:
                throw NonExhaustiveMatchException.For(statement);
            }
        }
示例#23
0
        public static string ToSymbolString(this BinaryOperator @operator)
        {
            switch (@operator)
            {
            case BinaryOperator.Plus:
                return("+");

            case BinaryOperator.Minus:
                return("-");

            case BinaryOperator.Asterisk:
                return("*");

            case BinaryOperator.Slash:
                return("/");

            case BinaryOperator.EqualsEquals:
                return("==");

            case BinaryOperator.NotEqual:
                return("=/=");

            case BinaryOperator.LessThan:
                return("<");

            case BinaryOperator.LessThanOrEqual:
                return("<=");

            case BinaryOperator.GreaterThan:
                return(">");

            case BinaryOperator.GreaterThanOrEqual:
                return(">=");

            case BinaryOperator.And:
                return("and");

            case BinaryOperator.Or:
                return("or");

            case BinaryOperator.DotDot:
                return("..");

            default:
                throw NonExhaustiveMatchException.For(@operator);
            }
        }
示例#24
0
        public FixedList <Declaration> Build(IEnumerable <DeclarationSyntax> declarationSyntaxes)
        {
            var declarations = new List <Declaration>();

            foreach (var namespacedDeclaration in declarationSyntaxes.Where(d => !d.Poisoned))
            {
                switch (namespacedDeclaration)
                {
                case NamedFunctionDeclarationSyntax namedFunction:
                    declarations.Add(new FunctionDeclaration(
                                         namedFunction.IsExternalFunction,
                                         namedFunction.DeclaringType != null,
                                         namedFunction.FullName,
                                         namedFunction.Type.Resolved(),
                                         BuildParameters(namedFunction.Parameters),
                                         namedFunction.ReturnType.Resolved(),
                                         namedFunction.ControlFlow));
                    break;

                case ClassDeclarationSyntax classDeclaration:
                    declarations.Add(new TypeDeclaration(
                                         classDeclaration.FullName,
                                         classDeclaration.Type.Resolved(),
                                         BuildGenericParameters(classDeclaration.GenericParameters),
                                         BuildClassMembers(classDeclaration, declarations)));
                    break;

                case ConstructorDeclarationSyntax constructorDeclaration:
                {
                    var constructorType = (FunctionType)constructorDeclaration.Type.Resolved();
                    var parameters      = BuildConstructorParameters(constructorDeclaration);
                    constructorType = new FunctionType(parameters.Select(p => p.Type), constructorType.ReturnType);
                    declarations.Add(new ConstructorDeclaration(constructorDeclaration.FullName,
                                                                constructorType,
                                                                parameters,
                                                                constructorDeclaration.ReturnType.Resolved(),
                                                                constructorDeclaration.ControlFlow));
                }
                break;

                default:
                    throw NonExhaustiveMatchException.For(namespacedDeclaration);
                }
            }

            return(declarations.ToFixedList());
        }
 private void ResolveSignatureTypesInDeclaration(DeclarationSyntax declaration)
 {
     switch (declaration)
     {
         case FunctionDeclarationSyntax f:
             ResolveSignatureTypesInFunction(f);
             break;
         case TypeDeclarationSyntax t:
             ResolveSignatureTypesInTypeDeclaration(t);
             break;
         case FieldDeclarationSyntax f:
             ResolveSignatureTypesInField(f);
             break;
         default:
             throw NonExhaustiveMatchException.For(declaration);
     }
 }
        public GenericParameterSyntax ParseGenericParameter()
        {
            Name name;
            var  dollar = Tokens.AcceptToken <IDollarToken>();

            if (dollar != null)
            {
                var lifetime = Tokens.RequiredToken <ILifetimeNameToken>();
                var span     = TextSpan.Covering(dollar.Span, lifetime.Span);

                switch (lifetime)
                {
                case IIdentifierToken lifetimeIdentifier:
                    name = nameContext.Qualify(lifetimeIdentifier.Value);
                    break;

                case IRefKeywordToken _:
                    name = nameContext.Qualify(SpecialName.Ref);
                    break;

                case IOwnedKeywordToken _:
                    Add(ParseError.OwnedNotValidAsGenericLifetimeParameter(File, span));
                    // We just treat it as if they had written `$\owned`
                    name = nameContext.Qualify("owned");
                    break;

                default:
                    throw NonExhaustiveMatchException.For(lifetime);
                }

                return(new GenericParameterSyntax(true, false, name, null));
            }

            var isParams   = Tokens.Accept <IParamsKeywordToken>();
            var identifier = Tokens.RequiredToken <IIdentifierToken>();

            name = nameContext.Qualify(identifier.Value);
            ExpressionSyntax typeExpression = null;

            if (Tokens.Accept <IColonToken>())
            {
                typeExpression = ParseExpression();
            }
            return(new GenericParameterSyntax(false, isParams, name, typeExpression));
        }
示例#27
0
        private static ISymbol GetSymbolForType(DataType type)
        {
            switch (type)
            {
            case UnknownType _:
                return(UnknownSymbol.Instance);

            case ObjectType objectType:
                return(objectType.Symbol);

            case SizedIntegerType integerType:
                // TODO this seems a very strange way to handle this. Shouldn't the symbol be on the type?
                return(PrimitiveSymbols.Instance.Single(p => p.FullName == integerType.Name));

            default:
                throw NonExhaustiveMatchException.For(type);
            }
        }
 private static DataType ResolveReturnType(
     FunctionDeclarationSyntax function,
     ExpressionTypeResolver expressionResolver)
 {
     function.ReturnType.BeginFulfilling();
     switch (function)
     {
         case NamedFunctionDeclarationSyntax namedFunction:
             return ResolveReturnType(function, namedFunction.ReturnTypeExpression, expressionResolver);
         case OperatorDeclarationSyntax @operator:
             return ResolveReturnType(function, @operator.ReturnTypeExpression, expressionResolver);
         case ConstructorDeclarationSyntax _:
         case InitializerDeclarationSyntax _:
             return function.ReturnType.Fulfill(function.DeclaringType.Metatype.Instance);
         default:
             throw NonExhaustiveMatchException.For(function);
     }
 }
示例#29
0
        private bool NumericOperatorTypesAreCompatible(
            ref ExpressionSyntax leftOperand,
            ref ExpressionSyntax rightOperand,
            DataType resultType)
        {
            var leftType  = leftOperand.Type;
            var rightType = rightOperand.Type;

            switch (leftType)
            {
            case PointerType _:
            {
                // TODO it may need to be size
                throw new NotImplementedException();
            }

            case IntegerConstantType _:
                // TODO may need to promote based on size
                throw new NotImplementedException();

            //return !IsIntegerType(rightType);
            case UnsizedIntegerType integerType:
                // TODO this isn't right we might need to convert either of them
                InsertImplicitConversionIfNeeded(ref rightOperand, integerType);
                return(rightOperand.Type is UnsizedIntegerType);

            case SizedIntegerType integerType:
                // TODO this isn't right we might need to convert either of them
                InsertImplicitConversionIfNeeded(ref rightOperand, integerType);
                return(rightOperand.Type is SizedIntegerType);

            case ObjectType _:
            case BoolType _:
            case VoidType _:           // This might need a special error message
            case StringConstantType _: // String concatenation will be handled outside this function
                // Other object types can't be used in numeric expressions
                return(false);

            default:
                // In theory we could just return false here, but this way we are forced to note
                // exactly which types this doesn't work on.
                throw NonExhaustiveMatchException.For(leftType);
            }
        }
示例#30
0
        private static void Mangle(Name name, StringBuilder builder)
        {
            switch (name)
            {
            case SimpleName simpleName:
                builder.Append(simpleName.IsSpecial ? 'ₐ' : 'ᵢ');
                ManglePart(simpleName.Text, builder);
                break;

            case QualifiedName qualifiedName:
                Mangle(qualifiedName.Qualifier, builder);
                builder.Append('·');
                Mangle(qualifiedName.UnqualifiedName, builder);
                break;

            default:
                throw NonExhaustiveMatchException.For(name);
            }
        }