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); } } }
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 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); } }
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); } }
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); } }
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); } }
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); } }
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); } }
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); } }
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); } }
public void ResolveTypesInStatement(StatementSyntax statement) { switch (statement) { case VariableDeclarationStatementSyntax variableDeclaration: ResolveTypesInVariableDeclaration(variableDeclaration); break; case ExpressionSyntax expression: InferExpressionType(expression); break; default: throw NonExhaustiveMatchException.For(statement); } }
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); } }
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 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)); }