public static void UsingTypeUnion(TypeUnion <Paging, Ordering> queryParameters) { // Detect with `is` and the Left, Right and Both classes if (queryParameters is TypeUnion <Paging, Ordering> .Left p) { Console.WriteLine($"This is a Paging only at page {p.Value.Page} with {p.Value.ItemsPerPage} items per page"); } // With pattern matching switch (queryParameters) { case TypeUnion <Paging, Ordering> .Left: Console.WriteLine("Left"); break; case TypeUnion <Paging, Ordering> .Right: Console.WriteLine("Right"); break; case TypeUnion <Paging, Ordering> .Both: Console.WriteLine("Both"); break; } // But if you need ordering info, you will need to test both Right and Both. // Or you could use this helper syntax : if (queryParameters.TryGetRight(out var ordering)) { Console.WriteLine($"Ordering {(ordering.Ascending ? "Ascending" : "Descending")}"); } }
public static void DemoBoth() { TypeUnion <Paging, Ordering> queryParameters; // Can be left (Paging) queryParameters = new TypeUnion <Paging, Ordering> .Left(new Paging(1, 50)); // Can be right (Ordering) queryParameters = new TypeUnion <Paging, Ordering> .Right(new Ordering(true)); // But can also be both at the same time! queryParameters = new TypeUnion <Paging, Ordering> .Both(new Paging(10, 10), new Ordering(false)); }
public virtual bool ImplicitCoercionToUnion(TypeNode sourceType, TypeUnion union, TypeViewer typeViewer){ if (union == null) return false; TypeNodeList types = union.Types; for (int i = 0, n = types == null ? 0 : types.Count; i < n; i++){ TypeNode t = types[i]; if (t == null) continue; if (this.ImplicitCoercionFromTo(sourceType, t, typeViewer)) return true; } return true; }
protected virtual Expression CoerceFromTypeUnion(Expression source, TypeUnion sourceType, TypeNode targetType, bool explicitCoercion, TypeNode originalTargetType, TypeViewer typeViewer){ if (source == null || sourceType == null || targetType == null) return null; if (targetType == SystemTypes.Object) return this.CoerceTypeUnionToObject(source, typeViewer); int cErrors = (this.Errors != null) ? this.Errors.Count : 0; if (explicitCoercion){ Method coercion = this.UserDefinedExplicitCoercionMethod(source, sourceType, targetType, false, originalTargetType, typeViewer); if (coercion != null && coercion.ReturnType == targetType && coercion.Parameters != null && coercion.Parameters[0] != null && this.ImplicitCoercionFromTo(sourceType, coercion.Parameters[0].Type, typeViewer)) return this.ImplicitCoercion(new MethodCall(new MemberBinding(null, coercion), new ExpressionList(source), NodeType.Call, coercion.ReturnType), targetType, typeViewer); } Method getTag = TypeViewer.GetTypeView(typeViewer, sourceType).GetMethod(StandardIds.GetTag); if (getTag == null) return null; Method getValue = TypeViewer.GetTypeView(typeViewer, sourceType).GetMethod(StandardIds.GetValue); if (getValue == null) return null; Local src = new Local(sourceType); Local srcOb = new Local(SystemTypes.Object, source.SourceContext); Local tgt = new Local(targetType); Expression callGetTag = new MethodCall(new MemberBinding(new UnaryExpression(src, NodeType.AddressOf), getTag), null); Expression callGetValue = new MethodCall(new MemberBinding(new UnaryExpression(src, NodeType.AddressOf), getValue), null); TypeNodeList types = sourceType.Types; int n = types == null ? 0 : types.Count; Block endOfSwitch = new Block(); StatementList statements = new StatementList(5+n); statements.Add(new AssignmentStatement(src, source)); statements.Add(new AssignmentStatement(srcOb, callGetValue)); BlockList cases = new BlockList(n); statements.Add(new SwitchInstruction(callGetTag, cases)); bool hadCoercion = false; Block eb = new Block(new StatementList(1)); Construct c = new Construct(new MemberBinding(null, SystemTypes.InvalidCastException.GetConstructor()), null, SystemTypes.InvalidCastException); eb.Statements.Add(new Throw(c)); for (int i = 0; i < n; i++){ TypeNode t = types[i]; if (t == null) continue; if (!explicitCoercion && !this.ImplicitCoercionFromTo(t, targetType, typeViewer)) return null; Expression expr = this.ExplicitCoercion(srcOb, t, typeViewer); if (expr == null) return null; expr = this.ExplicitCoercion(expr, targetType, typeViewer); if (expr == null) { cases.Add(eb); statements.Add(eb); } else { Block b = new Block(new StatementList(2)); hadCoercion = true; expr.SourceContext = srcOb.SourceContext; b.Statements.Add(new AssignmentStatement(tgt, expr)); b.Statements.Add(new Branch(null, endOfSwitch)); cases.Add(b); statements.Add(b); } } if (this.Errors != null) { for (int ie = cErrors, ne = this.Errors.Count; ie < ne; ie++) { this.Errors[ie] = null; } } if (!hadCoercion) return null; statements.Add(endOfSwitch); statements.Add(new ExpressionStatement(tgt)); return new BlockExpression(new Block(statements)); //TODO: wrap this in a CoerceTypeUnion node so that source code can be reconstructed easily }
public virtual Expression CoerceToTypeUnion(Expression source, TypeNode sourceType, TypeUnion targetType, TypeViewer typeViewer){ if (source == null || sourceType == null || targetType == null) return null; if (this.UserDefinedImplicitCoercionMethod(source, sourceType, targetType, true, typeViewer) != null) return null; TypeUnion tType = targetType.UnlabeledUnion; if (tType == null) return null; Method coercion = this.UserDefinedImplicitCoercionMethod(source, sourceType, tType, true, typeViewer); if (coercion == null) return null; //No coercion possible TypeNode chosenType = coercion.Parameters[0].Type; TypeNodeList types1 = tType.Types; TypeNodeList types2 = targetType.Types; for (int i = 0, n = types1.Count; i < n; i++){ TypeNode t = types1[i]; if (t == chosenType){ source = this.ExplicitCoercion(source, types2[i], typeViewer); if (source == null) return null; return this.ExplicitCoercion(source, targetType, typeViewer); } } Debug.Assert(false); return null; }
public record TestRecord( // You can put the converter on a record's property [property: JsonConverter(typeof(OneOfJsonConverter <int, DateTime>))] TypeUnion <int, DateTime> DateOrTimestamp );
void AddWriteChoice(TypeUnion tu, StatementList statements, TypeNode referringType, Expression src, Identifier writer) { // generate the following code: // Type srcType = src.GetType(); // if (choiceType.IsAssignableFrom(srcType)){ // XxxxSerializer s = new XxxxSerializer(); // s.Serialize((runtimeType)src, writer); // } else if (...) { // // and so on. // } // What we cannot do here is by creating nested XmlSerializers // based on runtime type because this could cause infinite recurrsion. // So we cannot serialize a type union where one of the choices is "object". TypeNodeList choices = tu.Types; MethodCall call = new MethodCall(); call.Callee = new QualifiedIdentifier(src, Identifier.For("GetType")); call.Operands = new ExpressionList(); Local local = new Local(SystemTypes.Type); statements.Add(new AssignmentStatement(local, call)); for (int i = 0, n = choices.Length; i < n; i++) { TypeNode choiceType = choices[i]; if (choiceType == null) continue; // type resolution error. // if (choiceType.IsAssignableFrom(srcType)){ BinaryExpression condition = new BinaryExpression( new MethodCall( new QualifiedIdentifier(new UnaryExpression(new MemberBinding(null, choiceType), NodeType.Typeof), Identifier.For("IsAssignableFrom")), new ExpressionList(new Expression[] { local })), Literal.True, NodeType.Eq); Block block = new Block(); block.Statements = new StatementList(); BinaryExpression cast = CastTo(src, choiceType); Expression name = null, ns = null; GetNameAndNamespace(choiceType, out name, out ns); Expression simplename = name, simplens = ns; // Check for choice of type: [string] and match this with XmlTextNode. TypeNode unwrapped = UnwrapSingletonTuple(choiceType, true); if (unwrapped == null) unwrapped = choiceType; if (unwrapped != null && unwrapped.IsPrimitive) { simplename = simplens = null; choiceType = unwrapped; } if (!AddWriteSimpleType(choiceType, block.Statements, referringType, writer, cast, simplename, simplens)) { AddCallSerializer(choiceType, block.Statements, cast, writer, name, ns); } If ifStatement = new If(condition, block, null); statements.Add(ifStatement); } }
public virtual Differences VisitTypeUnion(TypeUnion typeUnion1, TypeUnion typeUnion2){ Differences differences = this.GetMemberDifferences(typeUnion1, typeUnion2); if (differences == null){Debug.Assert(false); differences = new Differences(typeUnion1, typeUnion2);} if (differences.NumberOfDifferences > 0 || differences.NumberOfSimilarities > 0) return differences; if (typeUnion1 == null || typeUnion2 == null){ if (typeUnion1 != typeUnion2) differences.NumberOfDifferences++; else differences.NumberOfSimilarities++; return differences; } TypeUnion changes = (TypeUnion)typeUnion2.Clone(); TypeUnion deletions = (TypeUnion)typeUnion2.Clone(); TypeUnion insertions = (TypeUnion)typeUnion2.Clone(); AttributeList attrChanges, attrDeletions, attrInsertions; Differences diff = this.VisitAttributeList(typeUnion1.Attributes, typeUnion2.Attributes, out attrChanges, out attrDeletions, out attrInsertions); if (diff == null){Debug.Assert(false); return differences;} changes.Attributes = attrChanges; deletions.Attributes = attrDeletions; insertions.Attributes = attrInsertions; differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; if (typeUnion1.Flags == typeUnion2.Flags) differences.NumberOfSimilarities++; else differences.NumberOfDifferences++; diff = this.VisitIdentifier(typeUnion1.Name, typeUnion2.Name); if (diff == null){Debug.Assert(false); return differences;} changes.Name = diff.Changes as Identifier; deletions.Name = diff.Deletions as Identifier; insertions.Name = diff.Insertions as Identifier; Debug.Assert(diff.Changes == changes.Name && diff.Deletions == deletions.Name && diff.Insertions == insertions.Name); differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; TypeNodeList typeChanges, typeDeletions, typeInsertions; diff = this.VisitTypeNodeList(typeUnion1.TemplateParameters, typeUnion2.TemplateParameters, out typeChanges, out typeDeletions, out typeInsertions); if (diff == null){Debug.Assert(false); return differences;} changes.TemplateParameters = typeChanges; deletions.TemplateParameters = typeDeletions; insertions.TemplateParameters = typeInsertions; differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; diff = this.VisitTypeNodeList(typeUnion1.Types, typeUnion2.Types, out typeChanges, out typeDeletions, out typeInsertions); if (diff == null){Debug.Assert(false); return differences;} changes.Types = typeChanges; deletions.Types = typeDeletions; insertions.Types = typeInsertions; differences.NumberOfDifferences += diff.NumberOfDifferences; differences.NumberOfSimilarities += diff.NumberOfSimilarities; if (differences.NumberOfDifferences == 0){ differences.Changes = null; differences.Deletions = null; differences.Insertions = null; }else{ differences.Changes = changes; differences.Deletions = deletions; differences.Insertions = insertions; } return differences; }
public override TypeNode VisitTypeReference(TypeNode type) { if (type == null) { return(null); } Class cl = type as Class; if (cl != null) { this.VisitTypeReference(cl.BaseClass); } if (this.MembersToFind[type.UniqueKey] != null) { this.FoundMembers[type.UniqueKey] = type; if (!this.insideMethodBody) { this.AllReferencesAreConfinedToMethodBodies = false; } return(type); } switch (type.NodeType) { case NodeType.ArrayType: ArrayType arrType = (ArrayType)type; this.VisitTypeReference(arrType.ElementType); return(type); case NodeType.DelegateNode: { FunctionType ftype = type as FunctionType; if (ftype == null) { goto default; } this.VisitTypeReference(ftype.ReturnType); this.VisitParameterList(ftype.Parameters); return(type); } case NodeType.Pointer: Pointer pType = (Pointer)type; this.VisitTypeReference(pType.ElementType); return(type); case NodeType.Reference: Reference rType = (Reference)type; this.VisitTypeReference(rType.ElementType); return(type); case NodeType.TupleType: { TupleType tType = (TupleType)type; MemberList members = tType.Members; int n = members == null ? 0 : members.Count; for (int i = 0; i < n; i++) { Field f = members[i] as Field; if (f == null) { continue; } this.VisitTypeReference(f.Type); } return(type); } case NodeType.TypeIntersection: TypeIntersection tIntersect = (TypeIntersection)type; this.VisitTypeReferenceList(tIntersect.Types); return(type); case NodeType.TypeUnion: TypeUnion tUnion = (TypeUnion)type; this.VisitTypeReferenceList(tUnion.Types); return(type); case NodeType.ArrayTypeExpression: ArrayTypeExpression aExpr = (ArrayTypeExpression)type; this.VisitTypeReference(aExpr.ElementType); return(type); case NodeType.BoxedTypeExpression: BoxedTypeExpression bExpr = (BoxedTypeExpression)type; this.VisitTypeReference(bExpr.ElementType); return(type); case NodeType.ClassExpression: ClassExpression cExpr = (ClassExpression)type; this.VisitExpression(cExpr.Expression); this.VisitTypeReferenceList(cExpr.TemplateArguments); return(type); case NodeType.ClassParameter: case NodeType.TypeParameter: return(type); case NodeType.ConstrainedType: ConstrainedType conType = (ConstrainedType)type; this.VisitTypeReference(conType.UnderlyingType); this.VisitExpression(conType.Constraint); return(type); case NodeType.FlexArrayTypeExpression: FlexArrayTypeExpression flExpr = (FlexArrayTypeExpression)type; this.VisitTypeReference(flExpr.ElementType); return(type); case NodeType.FunctionTypeExpression: FunctionTypeExpression ftExpr = (FunctionTypeExpression)type; this.VisitParameterList(ftExpr.Parameters); this.VisitTypeReference(ftExpr.ReturnType); return(type); case NodeType.InvariantTypeExpression: InvariantTypeExpression invExpr = (InvariantTypeExpression)type; this.VisitTypeReference(invExpr.ElementType); return(type); case NodeType.InterfaceExpression: InterfaceExpression iExpr = (InterfaceExpression)type; this.VisitExpression(iExpr.Expression); this.VisitTypeReferenceList(iExpr.TemplateArguments); return(type); case NodeType.NonEmptyStreamTypeExpression: NonEmptyStreamTypeExpression neExpr = (NonEmptyStreamTypeExpression)type; this.VisitTypeReference(neExpr.ElementType); return(type); case NodeType.NonNullTypeExpression: NonNullTypeExpression nnExpr = (NonNullTypeExpression)type; this.VisitTypeReference(nnExpr.ElementType); return(type); case NodeType.NonNullableTypeExpression: NonNullableTypeExpression nbExpr = (NonNullableTypeExpression)type; this.VisitTypeReference(nbExpr.ElementType); return(type); case NodeType.NullableTypeExpression: NullableTypeExpression nuExpr = (NullableTypeExpression)type; this.VisitTypeReference(nuExpr.ElementType); return(type); case NodeType.OptionalModifier: case NodeType.RequiredModifier: TypeModifier modType = (TypeModifier)type; this.VisitTypeReference(modType.ModifiedType); this.VisitTypeReference(modType.Modifier); return(type); case NodeType.PointerTypeExpression: PointerTypeExpression pExpr = (PointerTypeExpression)type; this.VisitTypeReference(pExpr.ElementType); return(type); case NodeType.ReferenceTypeExpression: ReferenceTypeExpression rExpr = (ReferenceTypeExpression)type; this.VisitTypeReference(rExpr.ElementType); return(type); case NodeType.StreamTypeExpression: StreamTypeExpression sExpr = (StreamTypeExpression)type; this.VisitTypeReference(sExpr.ElementType); return(type); case NodeType.TupleTypeExpression: TupleTypeExpression tuExpr = (TupleTypeExpression)type; this.VisitFieldList(tuExpr.Domains); return(type); case NodeType.TypeExpression: TypeExpression tExpr = (TypeExpression)type; this.VisitExpression(tExpr.Expression); this.VisitTypeReferenceList(tExpr.TemplateArguments); return(type); case NodeType.TypeIntersectionExpression: TypeIntersectionExpression tiExpr = (TypeIntersectionExpression)type; this.VisitTypeReferenceList(tiExpr.Types); return(type); case NodeType.TypeUnionExpression: TypeUnionExpression tyuExpr = (TypeUnionExpression)type; this.VisitTypeReferenceList(tyuExpr.Types); return(type); default: if (type.Template != null && type.TemplateArguments != null) { this.VisitTypeReference(type.Template); this.VisitTypeReferenceList(type.TemplateArguments); } return(type); } }
public DebugFieldNode(DebugEnvironment envr, IDebugSymbol symbol, Identifier name, IDebugValue container, TypeNode declaringType, int id) { this.debugEnv = envr; this.Symbol = symbol; this.Container = container; this.Name = name; this.index = id; this.DeclaringType = declaringType; switch (symbol.Type.Kind) { case TypeKind.Class: this.Type = new DebugClassNode(this.debugEnv, this.Symbol.Type, ((IDebugFieldSymbol )symbol).GetValue(Container)); break; case TypeKind.Stream: this.Type = symbol.Type.CompilerType; break; case TypeKind.Tuple: StructTypes sType = ((IDebugStructuralType)this.Symbol.Type).StructuralType; switch (sType) { case StructTypes.Tuple: FieldList list = new FieldList(); IEnumSymbol symbols = ((IDebugStructuralType)this.Symbol.Type).GetMembers(null, true, SymbolKind.Field, SymbolModifiers.All); if (symbols != null) { while (symbols.Current != null) { Field fieldMember = new DebugFieldNode(this.debugEnv, symbols.Current, new Identifier(symbols.Current.Name), ((IDebugFieldSymbol )symbol).GetValue(Container), null, 0); SymbolModifiers modifier = symbols.Current.Modifiers; if ((modifier & SymbolModifiers.Abstract) != 0) { fieldMember.Flags |= FieldFlags.None; } if ((modifier & SymbolModifiers.Final) != 0) { fieldMember.Flags |= FieldFlags.None; } if ((modifier & SymbolModifiers.Private) != 0) { fieldMember.Flags |= FieldFlags.Private; } if ((modifier & SymbolModifiers.Public) != 0) { fieldMember.Flags |= FieldFlags.Public; } if ((modifier & SymbolModifiers.Static) != 0) { fieldMember.Flags |= FieldFlags.Static; } list.Add(fieldMember); symbols.MoveNext(); } } Class dummy = new Class(); dummy.DeclaringModule = new Module(); this.Type = TupleType.For(list, dummy); break; case StructTypes.Union: // HACK: Need a better way for identifying return types this.Type = TypeUnion.For(SymbolHelper.GetTypeList(this.Symbol.Type.FullName, this.debugEnv.context), new Module()); break; case StructTypes.Intersection: // TODO: Need to figure out Intersection Types, I think depends on figuring out return Type //this.Type = TypeIntersection.For(typeList, new Module()); this.Type = new Class(); break; } /*FieldList list = new FieldList(); * IEnumSymbol symbols = ((IDebugStructuralType) this.Symbol.Type).GetMembers(null, true, SymbolKind.Field, SymbolModifiers.All); * if (symbols != null){ * while(symbols.Current != null){ * list.Add(new DebugFieldNode(this.debugEnv, symbols.Current, new Identifier(symbols.Current.Name), null, null, 0)); * symbols.MoveNext(); * } * } * Class dummy = new Class(); * dummy.DeclaringModule = new Module(); * this.Type = TupleType.For(list, dummy);*/ break; case TypeKind.Primitive: switch (this.Symbol.Type.TypeCode) { case TypeCode.Boolean: this.Type = SystemTypes.Boolean; break; case TypeCode.Char: this.Type = SystemTypes.Char; break; case TypeCode.Int16: this.Type = SystemTypes.Int16; break; case TypeCode.UInt16: this.Type = SystemTypes.UInt32; break; case TypeCode.Int32: this.Type = SystemTypes.Int32; break; case TypeCode.UInt32: this.Type = SystemTypes.UInt32; break; case TypeCode.Int64: this.Type = SystemTypes.Int64; break; case TypeCode.UInt64: this.Type = SystemTypes.UInt64; break; case TypeCode.Double: this.Type = SystemTypes.Double; break; case TypeCode.Single: this.Type = SystemTypes.Single; break; case TypeCode.SByte: this.Type = SystemTypes.Int8; break; case TypeCode.Byte: this.Type = SystemTypes.UInt8; break; case TypeCode.String: this.Type = SystemTypes.String; break; } break; case TypeKind.Enum: this.Type = new DebugEnumNode(this.debugEnv, this.Symbol.Type); break; } }
static void Main(string[] args) { IType Int = TypeSingleton.Integer, Bool = TypeSingleton.Boolean, Str = TypeSingleton.String, Func = new TypeFunction(new TypeTuple(), TypeSingleton.Void), Tuple = new TypeTuple(), Union = new TypeUnion(), Void = TypeSingleton.Void, Any = TypeSingleton.Any; Tokenizer Indentation = Tokenizers.Indentation, MathOperator = Tokenizers.Predicate("&|+-".Contains), MathOperator2 = Tokenizers.Predicate("*/%".Contains), ComparisonOperator = Tokenizers.Predicate("=<>".Contains), PrefixOperator = Tokenizers.Match("!"), String = Tokenizers.Quote('"', '"'), Integer = Tokenizers.Predicate(char.IsDigit), Symbol = Tokenizers.Predicate(char.IsLetterOrDigit); var compiler = new CompilerHelper(Indentation, MathOperator, MathOperator2, PrefixOperator, ComparisonOperator, String, Integer, Symbol); Func <string, Token> GetToken = compiler.GetToken; var SymbolParser = Tokens(Symbol); Parser <TypeName> TypeName; Parser <IEnumerable <TypeName> > TypeNames = null; Parser <(string, TypeName)> Variable; Parser <IEnumerable <(string, TypeName)> > Variables; TypeName = parser => new TypeName(SymbolParser.Invoke(parser), TypeNames(parser)); TypeNames = ListOf(GetToken("{"), TypeName, GetToken(","), GetToken("}")); Variable = parser => (SymbolParser.Invoke(parser), TypeName(parser)); Variables = ListOf(GetToken("["), Variable, GetToken(","), GetToken("]")); var expr = new ExprBuilders(new ExprWriters()); // Parser to Analyzer mappings compiler.ParserRules.SetRules( ParserRules.Rule(expr.CheckedCast, Prefix(GetToken("->"), TypeName), Expression), ParserRules.Rule(expr.Sequence, Sequence(Indentation, Expression)), ParserRules.Rule(expr.Function, Variables, Expression), ParserRules.Rule(expr.Function, ListOf(GetToken("{"), Variable, GetToken(","), GetToken("}")), Variables, Expression), ParserRules.Rule(expr.VariableAssign, Prefix(GetToken("let"), Suffix(SymbolParser, GetToken("="))), Expression), ParserRules.Rule(expr.Identity, Prefix(GetToken("("), Suffix(Expression, GetToken(")")))), ParserRules.Rule(expr.LiteralString, Tokens(String)), ParserRules.Rule(expr.LiteralInt, Tokens(Integer)), ParserRules.Rule(expr.LiteralBooleanTrue, GetToken("true")), ParserRules.Rule(expr.LiteralBooleanFalse, GetToken("false")), ParserRules.Rule(expr.If, Prefix(GetToken("if"), Expression), Expression, Prefix(GetToken("else"), Expression)), ParserRules.Rule(expr.This, GetToken("this")), ParserRules.Rule(expr.FunctionOperatorSingle, Tokens(PrefixOperator), Expression), ParserRules.Rule(expr.Variable, SymbolParser) ); compiler.ParserRules.SetInfixRules( ParserRules.Rule(expr.ContextVariable, weight: 6, Prefix(GetToken("."), SymbolParser)), ParserRules.Rule(expr.FunctionSetGenerics, weight: 5, TypeNames), ParserRules.Rule(expr.FunctionOperator, weight: 4, Tokens(MathOperator2), WeightedExpression(4)), ParserRules.Rule(expr.FunctionOperator, weight: 3, Tokens(MathOperator), WeightedExpression(3)), ParserRules.Rule(expr.FunctionOperator, weight: 2, Tokens(ComparisonOperator), WeightedExpression(2)), ParserRules.Rule(expr.BooleanAnd, weight: 1, Prefix(GetToken("and"), WeightedExpression(1))), ParserRules.Rule(expr.BooleanOr, weight: 1, Prefix(GetToken("or"), WeightedExpression(1))), ParserRules.Rule(expr.FunctionCall, weight: 6, ListOf(GetToken("("), Expression, GetToken(","), GetToken(")"))) ); compiler.AddType("int", Int); compiler.AddType("bool", Bool); compiler.AddType("string", Str); compiler.AddType("fun", Func); compiler.AddType("tuple", Tuple); compiler.AddType("union", Union); compiler.AddType("any", Any); compiler.AddType("void", Void); // Set of core functions. // TODO Optimize: compiler should 'unwrap' all short functions compiler.AddFunction("print", VMCommand.Print, Void, Any); compiler.AddFunction("<", VMCommand.CompareLessThan, Bool, Int, Int); compiler.AddFunction("+", VMCommand.MathAddition, Int, Int, Int); compiler.AddFunction("-", VMCommand.MathSubstraction, Int, Int, Int); compiler.AddFunction("*", VMCommand.MathMultiplication, Int, Int, Int); compiler.AddFunction("/", VMCommand.MathDivision, Int, Int, Int); compiler.AddFunction("!", VMCommand.BooleanNot, Bool, Bool); compiler.AddFunction("==", VMCommand.EqualInt, Bool, Bool, Bool); compiler.AddFunction("==", VMCommand.EqualInt, Bool, Int, Int); try { compiler.RunFile("Example"); } catch (CompilationException e) { Console.WriteLine("Compilation Error: " + e.Message); } }
public EventingVisitor(Action<TypeUnion> visitTypeUnion) { VisitedTypeUnion += visitTypeUnion; } public event Action<TypeUnion> VisitedTypeUnion; public override TypeUnion VisitTypeUnion(TypeUnion typeUnion) { if (VisitedTypeUnion != null) VisitedTypeUnion(typeUnion); return base.VisitTypeUnion(typeUnion); }
private static void AssertExpectedDate(TypeUnion <int, DateTime> value) { Assert.IsTrue(value is TypeUnion <int, DateTime> .Right); }
public virtual void VisitTypeUnion(TypeUnion typeUnion){ this.VisitTypeNode(typeUnion); }
internal void CompileTypeUnion(TypeUnion tu, Member mem) { bool hasChoice = false; this.builder.OpenGroup(); TypeNodeList members = tu.Types; for (int i = 0, n = members == null ? 0 : members.Length; i < n; i++) { TypeNode memType = members[i]; if (memType == null) continue; // type was not resolved. TypeNode type = Unwrap(memType); if (type == null) continue; // error handling. if (builder.HasTerminal) { builder.AddChoice(mem,tu); hasChoice = true; } Method m = new Method(); m.ReturnType = memType; if (type is TupleType) { CompileTuple(type as TupleType, m); } else if (type.Template == SystemTypes.GenericList || type.Template == SystemTypes.GenericList || type.Template == SystemTypes.GenericIList || type.Template == SystemTypes.GenericIEnumerable){ CompileGenericList(type, 0, Int32.MaxValue, m); } else if (type.Template == SystemTypes.GenericNonEmptyIEnumerable){ CompileGenericList(type,1, Int32.MaxValue, m); } else if (type.Template == SystemTypes.GenericBoxed) { CompileGenericList(type, 0, 1, m); } else if (type is TypeUnion) { CompileTypeUnion(type as TypeUnion, m); } else { if (memType is TypeAlias) { TypeAlias alias = memType as TypeAlias; builder.AddNamedTerminal(alias.Name, m, alias.AliasedType); } else builder.AddNamedTerminal(Checker.GetDefaultElementName(type), m, type); } } if (!hasChoice && builder.HasTerminal) builder.AddNop(mem, tu); this.builder.CloseGroup(); }
public virtual void VisitTypeswitchCaseList(TypeswitchCaseList oldCases, TypeswitchCaseList newCases, TypeUnion tUnion) { if (oldCases == null || newCases == null || tUnion == null) { Debug.Assert(false); return; } TypeNodeList types = tUnion.Types; if (types == null) return; bool complainedAboutDefault = false; for (int i = 0, n = oldCases.Count; i < n; i++) { TypeswitchCase tcase = this.VisitTypeswitchCase(oldCases[i]); if (tcase == null) continue; TypeNode t = tcase.LabelType; if (t == null) { if (tcase.LabelTypeExpression == null && !complainedAboutDefault) { complainedAboutDefault = true; this.HandleError(tcase, Error.DefaultNotAllowedInTypeswitch); } continue; } int j = types.SearchFor(t); if (j < 0) { //TODO: look for a single field tuple with the same type as t and arrange for coercion this.HandleError(tcase.LabelTypeExpression, Error.TypeCaseNotFound, this.GetTypeName(t), this.GetTypeName(tUnion)); continue; } if (newCases[j] != null) continue; //TODO: give an error newCases[j] = tcase; } }
/// <summary> /// This method is not yet implemented /// </summary> /// <param name="writer">The <see cref="Newtonsoft.Json.JsonWriter"/> to write to.</param> /// <param name="value">The value.</param> /// <param name="serializer">The calling serializer.</param> public override void WriteJson(JsonWriter writer, TypeUnion <TLeft, TRight>?value, JsonSerializer serializer) { throw new NotImplementedException(); }
public virtual TypeUnion VisitTypeUnion(TypeUnion typeUnion){ return (TypeUnion)this.VisitTypeNode(typeUnion); }
/// <summary> /// Deserializes the entity using the <see cref="ConverterKind"/> rules. /// </summary> /// <param name="reader">The <see cref="JsonReader"/> to read from.</param> /// <param name="objectType">Type of the object.</param> /// <param name="existingValue">The existing value of object being read. If there is no existing value then <c>null</c> will be used.</param> /// <param name="hasExistingValue">The existing value has a value.</param> /// <param name="serializer">The calling serializer.</param> /// <returns>The object value.</returns> public override TypeUnion <TLeft, TRight> ReadJson(JsonReader reader, Type objectType, TypeUnion <TLeft, TRight>?existingValue, bool hasExistingValue, JsonSerializer serializer) { var path = reader.Path; JToken token = JToken.ReadFrom(reader); return(this.ReadToken(token, serializer, path)); }
void AddReadChoice(Block block, TypeUnion tu, StatementList statements, Identifier reader, Expression target, Expression required, Expression result){ // Read next element and figure out which of the choices in the type union it is then read the matching Type. Local nameLocal = new Local(Identifier.For("name"),SystemTypes.String,block); Local nsLocal = new Local(Identifier.For("ns"),SystemTypes.String,block); Local nodeType = new Local(Identifier.For("nodeType"),Runtime.XmlNodeType,block); statements.Add(new AssignmentStatement(nameLocal, new QualifiedIdentifier(reader, Identifier.For("LocalName")))); statements.Add(new AssignmentStatement(nsLocal, new QualifiedIdentifier(reader, Identifier.For("NamespaceURI")))); statements.Add(new AssignmentStatement(nodeType, new QualifiedIdentifier(reader, Identifier.For("NodeType")))); Local localRequired = new Local(Identifier.Empty,SystemTypes.Boolean,block); statements.Add(new AssignmentStatement(localRequired, Literal.True)); Expression readString = new MethodCall(new QualifiedIdentifier(reader, Identifier.For("ReadString")), null, NodeType.Callvirt, SystemTypes.String); If ifIsElement = new If(new BinaryExpression(nodeType, new QualifiedIdentifier(Identifier.For("XmlNodeType"), Identifier.For("Element")), NodeType.Eq), new Block(new StatementList()), new Block(new StatementList())); statements.Add(ifIsElement); StatementList elseList = ifIsElement.TrueBlock.Statements; StringBuilder expecting = new StringBuilder(); Expression bestCoercion = null; TypeNode bestChoice = null; TypeNode bestUnwrappedChoice = null; bool stringCoercionAmbiguous = false; for (int i = 0, n = tu.Types.Length; i < n; i++) { TypeNode choice = tu.Types[i]; if (choice == null) continue; // type resolution error. TypeNode unwrapped = UnwrapSingletonTuple(Unwrap(choice), false); if (unwrapped == null) unwrapped = choice; Expression coercion = GetConvertFromString(unwrapped, readString, false); if (coercion != null) { // Keep track of the best coercion to string and use this to handle text nodes below. if (bestChoice == null){ bestChoice = choice; bestUnwrappedChoice = unwrapped; bestCoercion = coercion; } else if (tempTypeSystem.IsBetterMatch(unwrapped, bestUnwrappedChoice, SystemTypes.String)) { bestChoice = choice; bestUnwrappedChoice = unwrapped; bestCoercion = coercion; } else { stringCoercionAmbiguous = true; } } BinaryExpression be = IsStartOf(block, choice, statements, nameLocal, nsLocal, expecting); StatementList trueStatements = new StatementList(); If ifIsStartOf = new If(be, new Block(trueStatements), new Block(new StatementList())); elseList.Add(ifIsStartOf); Local choiceTarget = new Local(Identifier.Empty, choice, block); if (choice.Template == SystemTypes.GenericBoxed){ choice = Checker.GetCollectionElementType(choice); } if (!AddReadSimpleType(choice, trueStatements, reader, choiceTarget, result, false)) { AddCallDeserializer(choice, trueStatements, reader, choiceTarget, localRequired, result); } trueStatements.Add(new AssignmentStatement(target, CastTo(choiceTarget, target.Type))); elseList = ifIsStartOf.FalseBlock.Statements; } if (bestCoercion != null && !stringCoercionAmbiguous) { // Then we can also accept text nodes StatementList ifTextStatements = new StatementList(); If ifIsText = new If(IsTextNode(nodeType), new Block(ifTextStatements), null); ifIsElement.FalseBlock.Statements.Add(ifIsText); // then we can also handle text nodes in this choice. ifTextStatements.Add(new AssignmentStatement(target, CastTo(CastTo(bestCoercion, bestChoice), tu))); ifTextStatements.Add(new AssignmentStatement(result, Literal.True)); } // If this was a required element, then throw an error. If isRequired = new If(new BinaryExpression(required, Literal.True, NodeType.Eq), new Block(new StatementList()), new Block(new StatementList())); elseList.Add(isRequired); InvalidContent(isRequired.TrueBlock.Statements, reader, expecting.ToString()); isRequired.FalseBlock.Statements.Add(new AssignmentStatement(result, Literal.False)); }
public virtual Expression CoerceObjectToTypeUnion(Expression source, TypeUnion targetType, TypeViewer typeViewer){ Method fromObject = TypeViewer.GetTypeView(typeViewer, targetType).GetMethod(StandardIds.FromObject, SystemTypes.Object, SystemTypes.Type); Method getType = Runtime.GetType; ExpressionList arguments = new ExpressionList(2); arguments.Add(source); arguments.Add(new MethodCall(new MemberBinding(new Expression(NodeType.Dup), getType), null, NodeType.Call)); MethodCall fromObjectCall = new MethodCall(new MemberBinding(null, fromObject), arguments, NodeType.Call); fromObjectCall.Type = targetType; return fromObjectCall; }
public virtual TypeUnion VisitTypeUnion(TypeUnion typeUnion, TypeUnion changes, TypeUnion deletions, TypeUnion insertions){ return (TypeUnion)this.VisitTypeNode(typeUnion, changes, deletions, insertions); }
/// <summary> /// This method is not yet implemented /// </summary> /// <param name="writer"></param> /// <param name="value"></param> /// <param name="options"></param> public override void Write(Utf8JsonWriter writer, TypeUnion <TLeft, TRight> value, JsonSerializerOptions options) { throw new NotImplementedException(); }