public static void ValidatePayloadTypes(ITranslationErrorHandler handler, ParserRuleContext context, PLanguageType payloadType, IReadOnlyList <IPExpr> arguments) { if (arguments.Count == 0) { if (!payloadType.IsSameTypeAs(PrimitiveType.Null)) { throw handler.TypeMismatch(context, PrimitiveType.Null, payloadType); } } else if (arguments.Count == 1) { CheckArgument(handler, context, payloadType, arguments[0]); } else if (payloadType.Canonicalize() is TupleType tuple) { foreach (Tuple <IPExpr, PLanguageType> pair in arguments.Zip(tuple.Types, Tuple.Create)) { CheckArgument(handler, context, pair.Item2, pair.Item1); } } else { throw handler.IncorrectArgumentCount(context, arguments.Count, 1); } }
private static void ValidateEventPayloadToTransitionTarget(ITranslationErrorHandler handler, ParserRuleContext sourceLocation, PLanguageType eventPayloadType, Function targetFunction) { IReadOnlyList <PLanguageType> entrySignature = targetFunction.Signature.ParameterTypes.ToList(); if (entrySignature.Count == 0) { return; } if (entrySignature.Count == 1 && entrySignature[0].IsAssignableFrom(eventPayloadType)) { return; } if (entrySignature.Count == 1 && eventPayloadType.Canonicalize() is TupleType tuple && tuple.Types.Count == 1 && entrySignature[0].IsAssignableFrom(tuple.Types[0])) { return; } if (entrySignature.Count == 1) { throw handler.TypeMismatch(sourceLocation, eventPayloadType, entrySignature[0]); } PLanguageType entrySignatureType = new TupleType(entrySignature.ToArray()); if (!entrySignatureType.IsAssignableFrom(eventPayloadType)) { throw handler.TypeMismatch(sourceLocation, eventPayloadType, entrySignatureType); } }
public override IPExpr VisitChooseExpr(PParser.ChooseExprContext context) { // if choose is without an argument then its a choose boolean if (context.expr() == null) { return(new ChooseExpr(context, null, PrimitiveType.Bool)); } IPExpr subExpr = Visit(context.expr()); PLanguageType subExprType = subExpr.Type; switch (subExprType.Canonicalize()) { case SequenceType seqType: return(new ChooseExpr(context, subExpr, seqType.ElementType)); case SetType setType: return(new ChooseExpr(context, subExpr, setType.ElementType)); case PrimitiveType primType when primType.IsSameTypeAs(PrimitiveType.Int): return(new ChooseExpr(context, subExpr, PrimitiveType.Int)); default: throw handler.IllegalChooseSubExprType(context, subExprType); } }
public override bool IsAssignableFrom(PLanguageType otherType) { // Copying semantics: both the other key and value types must be subtypes of this key/value type. return(otherType.Canonicalize() is MapType other && KeyType.IsAssignableFrom(other.KeyType) && ValueType.IsAssignableFrom(other.ValueType)); }
public string GetJavaTypeName(PLanguageType type, bool isVar = false) { switch (type.Canonicalize()) { case DataType _: throw new NotImplementedException("DateType is not implemented."); case EnumType enumType: return($"EnumValue<{GetEnumTypeName(enumType.EnumDecl)}>"); case ForeignType foreignType: return(GetForeignTypeName(foreignType)); case MapType _: return(GetMapTypeName()); case NamedTupleType _: return(GetNamedTupleTypeName()); case PermissionType _: throw new NotImplementedException("PermissionType is not implemented."); case PrimitiveType primitiveType when primitiveType.IsSameTypeAs(PrimitiveType.Any): throw new NotImplementedException("AnyType is not implemented."); case PrimitiveType primitiveType when primitiveType.IsSameTypeAs(PrimitiveType.Bool): return("BoolValue"); case PrimitiveType primitiveType when primitiveType.IsSameTypeAs(PrimitiveType.Int): return("IntValue"); case PrimitiveType primitiveType when primitiveType.IsSameTypeAs(PrimitiveType.Float): return("FloatValue"); case PrimitiveType primitiveType when primitiveType.IsSameTypeAs(PrimitiveType.String): return("StringValue"); case PrimitiveType primitiveType when primitiveType.IsSameTypeAs(PrimitiveType.Event): return(GetEventInterfaceName()); case PrimitiveType primitiveType when primitiveType.IsSameTypeAs(PrimitiveType.Machine): throw new NotImplementedException("MachineType is not implemented."); case PrimitiveType primitiveType when primitiveType.IsSameTypeAs(PrimitiveType.Null): return(isVar ? "" : "void"); case SequenceType _: return(GetSeqTypeName()); case SetType _: return(GetSetTypeName()); case TupleType _: return(GetTupleTypeName()); default: throw new ArgumentOutOfRangeException(nameof(type)); } }
private string SimplifiedRep(PLanguageType type) { switch (type.Canonicalize()) { case DataType _: return("B"); case EnumType _: return("E"); case ForeignType foreign: return(foreign.CanonicalRepresentation); case MapType mapType: return($"MK{SimplifiedRep(mapType.KeyType)}V{SimplifiedRep(mapType.ValueType)}"); case PermissionType _: return("R"); case PrimitiveType primitiveType when Equals(primitiveType, PrimitiveType.Bool): return("b"); case PrimitiveType primitiveType when Equals(primitiveType, PrimitiveType.Int): return("i"); case PrimitiveType primitiveType when Equals(primitiveType, PrimitiveType.Float): return("f"); case PrimitiveType primitiveType when Equals(primitiveType, PrimitiveType.Event): return("e"); case PrimitiveType primitiveType when Equals(primitiveType, PrimitiveType.Machine): return("m"); case PrimitiveType primitiveType when Equals(primitiveType, PrimitiveType.Any): return("a"); case PrimitiveType primitiveType when Equals(primitiveType, PrimitiveType.Null): return("n"); case PrimitiveType _: throw new ArgumentException("unrecognized primitive type", nameof(type)); case SequenceType sequenceType: return($"S{SimplifiedRep(sequenceType.ElementType)}"); case SetType setType: return($"U{SimplifiedRep(setType.ElementType)}"); case TupleType tupleType: return($"T{tupleType.Types.Count}{string.Join("", tupleType.Types.Select(SimplifiedRep))}"); case TypeDefType _: throw new ArgumentException("typedefs should be impossible after canonicalization", nameof(type)); } throw new ArgumentException("unrecognized type kind", nameof(type)); }
public string GetTypeName(PLanguageType type) { type = type.Canonicalize(); if (typeNames.TryGetValue(type, out var name)) { return(name); } // TODO: generate "nicer" names for generated types. name = UniquifyName(type.TypeKind.Name); typeNames[type] = name; return(name); }
public override IPExpr VisitKeywordExpr(PParser.KeywordExprContext context) { switch (context.fun.Text) { case "keys": { IPExpr expr = Visit(context.expr()); if (!(expr.Type.Canonicalize() is MapType mapType)) { throw handler.TypeMismatch(expr, TypeKind.Map); } return(new KeysExpr(context, expr, new SequenceType(mapType.KeyType))); } case "values": { IPExpr expr = Visit(context.expr()); if (!(expr.Type.Canonicalize() is MapType mapType)) { throw handler.TypeMismatch(expr, TypeKind.Map); } return(new ValuesExpr(context, expr, new SequenceType(mapType.ValueType))); } case "sizeof": { var expr = Visit(context.expr()); if (!(expr.Type.Canonicalize() is SequenceType) && !(expr.Type.Canonicalize() is MapType) && !(expr.Type.Canonicalize() is SetType)) { throw handler.TypeMismatch(expr, TypeKind.Map, TypeKind.Sequence, TypeKind.Set); } return(new SizeofExpr(context, expr)); } case "default": { PLanguageType type = TypeResolver.ResolveType(context.type(), table, handler); return(new DefaultExpr(context, type.Canonicalize())); } default: { throw handler.InternalError(context, new ArgumentException($"Unknown keyword expression {context.fun.Text}", nameof(context))); } } }
public string GetNameForType(PLanguageType type) { type = type.Canonicalize(); if (typeNames.TryGetValue(type, out string name)) { return(name); } name = NamePrefix + "GEND_TYPE_" + SimplifiedRep(type); name = UniquifyName(name); typeNames.Add(type, name); return(name); }
public static bool TypeIsOfKind(PLanguageType type, TypeKind kind) { return(type.Canonicalize().TypeKind.Equals(kind)); }
public override bool IsAssignableFrom(PLanguageType otherType) { // Copying semantics: Can assign to a sequence variable if the other sequence's elements are subtypes of this sequence's elements. return(otherType.Canonicalize() is SequenceType other && ElementType.IsAssignableFrom(other.ElementType)); }
public override bool IsAssignableFrom(PLanguageType otherType) { return(otherType.Canonicalize() is ForeignType other && CanonicalRepresentation == other.CanonicalRepresentation); }