Beispiel #1
0
        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")}");
            }
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
 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;
 }
Beispiel #4
0
 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
 }
Beispiel #5
0
 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
     );
Beispiel #7
0
    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;
    }
Beispiel #9
0
        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);
            }
        }
Beispiel #10
0
        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;
            }
        }
Beispiel #11
0
        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);
 }
Beispiel #14
0
 public virtual void VisitTypeUnion(TypeUnion typeUnion){
   this.VisitTypeNode(typeUnion);
 }
Beispiel #15
0
    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();      
    }
Beispiel #16
0
 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;
   }
 }
Beispiel #17
0
 /// <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();
 }
Beispiel #18
0
 public virtual TypeUnion VisitTypeUnion(TypeUnion typeUnion){
   return (TypeUnion)this.VisitTypeNode(typeUnion);
 }
Beispiel #19
0
        /// <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));
        }
Beispiel #20
0
    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));

    }
Beispiel #21
0
 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;
 }
Beispiel #22
0
 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();
 }