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); } }
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)); }
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); } }
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); } }
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 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)); }
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); } }
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); } }
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); } }