Esempio n. 1
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 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);
            }
        }
        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 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);
            }
        }
        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);
            }
        }
        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));
        }
        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);
                }
            }
        }
Esempio n. 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);
            }
        }
Esempio n. 10
0
        private DataType InferBinaryExpressionType(
            BinaryExpressionSyntax binaryExpression)
        {
            InferExpressionType(binaryExpression.LeftOperand);
            var leftType  = binaryExpression.LeftOperand.Type;
            var @operator = binaryExpression.Operator;

            InferExpressionType(binaryExpression.RightOperand);
            var rightType = binaryExpression.RightOperand.Type;

            // If either is unknown, then we can't know whether there is a a problem.
            // Note that the operator could be overloaded
            if (leftType == DataType.Unknown || rightType == DataType.Unknown)
            {
                return(binaryExpression.Type = DataType.Unknown);
            }

            bool compatible;

            switch (@operator)
            {
            case BinaryOperator.Plus:
            case BinaryOperator.Minus:
            case BinaryOperator.Asterisk:
            case BinaryOperator.Slash:
                compatible            = NumericOperatorTypesAreCompatible(ref binaryExpression.LeftOperand, ref binaryExpression.RightOperand, null);
                binaryExpression.Type = compatible ? leftType : DataType.Unknown;
                break;

            case BinaryOperator.EqualsEquals:
            case BinaryOperator.NotEqual:
            case BinaryOperator.LessThan:
            case BinaryOperator.LessThanOrEqual:
            case BinaryOperator.GreaterThan:
            case BinaryOperator.GreaterThanOrEqual:
                compatible = (leftType == DataType.Bool && rightType == DataType.Bool) ||
                             NumericOperatorTypesAreCompatible(ref binaryExpression.LeftOperand, ref binaryExpression.RightOperand, null);
                binaryExpression.Type = DataType.Bool;
                break;

            case BinaryOperator.And:
            case BinaryOperator.Or:
                compatible            = leftType == DataType.Bool && rightType == DataType.Bool;
                binaryExpression.Type = DataType.Bool;
                break;

            default:
                throw NonExhaustiveMatchException.ForEnum(@operator);
            }
            if (!compatible)
            {
                diagnostics.Add(TypeError.OperatorCannotBeAppliedToOperandsOfType(file,
                                                                                  binaryExpression.Span, @operator,
                                                                                  binaryExpression.LeftOperand.Type,
                                                                                  binaryExpression.RightOperand.Type));
            }

            return(binaryExpression.Type);
        }
        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);
            }
        }
Esempio n. 13
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);
            }
        }
Esempio n. 14
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);
            }
        }
        public override string ToString()
        {
            switch (Fixty)
            {
            case UnaryOperatorFixity.Prefix:
                return($"{Operator.ToSymbolString()}{Operand}");

            case UnaryOperatorFixity.Postfix:
                return($"{Operand}{Operator.ToSymbolString()}");

            default:
                throw NonExhaustiveMatchException.ForEnum(Fixty);
            }
        }
Esempio n. 17
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);
            }
        }
Esempio n. 18
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);
            }
        }
Esempio n. 19
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);
            }
        }
Esempio n. 20
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);
            }
        }
Esempio n. 23
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);
            }
        }
Esempio n. 24
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);
            }
        }
Esempio n. 25
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);
            }
        }
Esempio n. 26
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());
        }
Esempio n. 27
0
        private static bool CompileCode(
            Project project,
            string cacheDir,
            string codePath,
            object consoleLock)
        {
            var compiler = new CLangCompiler();

            var runtimeLibrarySourcePath = System.IO.Path.Combine(cacheDir, CodeEmitter.RuntimeLibraryCodeFileName);

            File.WriteAllText(runtimeLibrarySourcePath, CodeEmitter.RuntimeLibraryCode, Encoding.UTF8);
            var runtimeLibraryHeaderPath = System.IO.Path.Combine(cacheDir, CodeEmitter.RuntimeLibraryHeaderFileName);

            File.WriteAllText(runtimeLibraryHeaderPath, CodeEmitter.RuntimeLibraryHeader, Encoding.UTF8);

            var    sourceFiles       = new[] { codePath, runtimeLibrarySourcePath };
            var    headerSearchPaths = new[] { cacheDir };
            string outputPath;

            switch (project.Template)
            {
            case ProjectTemplate.App:
            {
                outputPath = System.IO.Path.ChangeExtension(codePath, "exe");
            }
            break;

            case ProjectTemplate.Lib:
            {
                outputPath = System.IO.Path.ChangeExtension(codePath, "dll");
            }
            break;

            default:
                throw NonExhaustiveMatchException.ForEnum(project.Template);
            }

            lock (consoleLock)
            {
                Console.WriteLine($"CLang Compiling {project.Name} ({project.Path})...");
                var exitCode = compiler.Compile(ConsoleCompilerOutput.Instance, sourceFiles,
                                                headerSearchPaths, outputPath);

                return(exitCode == 0);
            }
        }
 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);
     }
 }
        // Useful for debugging
        public override string ToString()
        {
            switch (State)
            {
            case PromiseState.Pending:
                return("⧼pending⧽");

            case PromiseState.InProgress:
                return("⧼in progress⧽");

            case PromiseState.Fulfilled:
                return(DataType.ToString());

            default:
                throw NonExhaustiveMatchException.ForEnum(State);
            }
        }
        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));
        }