public static GenericTypeDef FromJson(Json.ArrayExpression type)
        {
            if (type.ElementCount != 3)
            {
                throw new BonsaiParseException("Expected 3 JSON array elements for a generic type definition.", type);
            }

            var typeDef = TypeRef.FromJson(type.GetElement(1));

            if (type.GetElement(2) is not Json.ArrayExpression args)
            {
                throw new BonsaiParseException("Expected a JSON array in 'node[2]' for the type arguments of a generic type definition.", type);
            }

            var n = args.ElementCount;

            if (n < 1)
            {
                throw new BonsaiParseException("Expected at least 1 JSON array element in 'node[2]' for the type arguments of a generic type definition.", type);
            }

            var typeArgs = new TypeRef[n];

            for (var i = 0; i < n; i++)
            {
                var arg     = args.GetElement(i);
                var typeRef = TypeRef.FromJson(arg);
                typeArgs[i] = typeRef;
            }

            return(new GenericTypeDef(typeDef, typeArgs));
        }
        public static SimpleTypeDef FromJson(Json.ArrayExpression type)
        {
            if (type.ElementCount != 3)
            {
                throw new BonsaiParseException("Expected 3 JSON array elements for a simple type definition.", type);
            }

            var typeName = type.GetElement(1);

            if (typeName.NodeType != Json.ExpressionType.String)
            {
                throw new BonsaiParseException("Expected a JSON string in 'node[1]' for the type name of a simple type definition.", type);
            }

            var assemblyIndex = type.GetElement(2);

            if (assemblyIndex.NodeType != Json.ExpressionType.Number)
            {
                throw new BonsaiParseException("Expected a JSON number in 'node[2]' for the reference to the assembly of a simple type definition.", type);
            }

            var assemblyIndexValue = Helpers.ParseInt32((string)((Json.ConstantExpression)assemblyIndex).Value);

            return(new SimpleTypeDef((string)((Json.ConstantExpression)typeName).Value, assemblyIndexValue));
        }
Exemple #3
0
            public override ExpressionSlim VisitArray(Json.ArrayExpression node)
            {
                var newElements = new Json.Expression[node.Elements.Count];

                node.Elements.CopyTo(newElements, 0);
                newElements[0] = Json.Expression.Null();
                var newNode = Json.Expression.Array(newElements);

                return(base.VisitArray(newNode));
            }
Exemple #4
0
        public static StructuralTypeDef FromJson(Json.ArrayExpression type)
        {
            var n = type.ElementCount - 1;

            var stms = new AnonymousStructuralTypeMember[n];

            for (var i = 0; i < n; i++)
            {
                var element = type.GetElement(i + 1);
                var member  = AnonymousStructuralTypeMember.FromJson(element);
                stms[i] = member;
            }

            return(new AnonymousStructuralTypeDef(stms));
        }
Exemple #5
0
        public static RecordStructuralTypeDef FromJson(DeserializationDomain domain, Json.ArrayExpression type)
        {
            if (domain.IsV08)
            {
                throw new NotSupportedException("Record types are only supported in Bonsai v0.9 or later.");
            }

            var count = type.ElementCount;

            if (count is not 2 and not 3)
            {
                throw new BonsaiParseException("Expected 2 or 3 JSON array elements for a structural type definition.", type);
            }

            if (type.GetElement(1) is not Json.ArrayExpression membersJson)
            {
                throw new BonsaiParseException("Expected a JSON array in 'node[1]' for the structural type members.", type);
            }

            var membersCount = membersJson.ElementCount;

            var members = new RecordStructuralTypeMember[membersCount];

            for (var i = 0; i < membersCount; i++)
            {
                var memberJson = membersJson.GetElement(i);
                var member     = RecordStructuralTypeMember.FromJson(memberJson);
                members[i] = member;
            }

            var hasValueEqualitySemantics = true;

            if (count == 3)
            {
                var hasValueEqualitySemanticsExpr = type.GetElement(2);

                if (hasValueEqualitySemanticsExpr.NodeType != Json.ExpressionType.Boolean)
                {
                    throw new BonsaiParseException("Expected a JSON Boolean in 'node[2]' for the value equality semantics flag.", type);
                }

                hasValueEqualitySemantics = (bool)((Json.ConstantExpression)hasValueEqualitySemanticsExpr).Value;
            }

            return(new RecordStructuralTypeDef(hasValueEqualitySemantics, members));
        }
        public ParameterExpression Lookup(Json.ArrayExpression expression)
        {
            var n = expression.ElementCount;

            if (n is not 2 and not 3)
            {
                throw new BonsaiParseException("Expected 2 or 3 JSON array elements for an expression of type 'Parameter'.", expression);
            }

            if (n == 2)
            {
                if (expression.GetElement(1) is not Json.ConstantExpression indexJson || !int.TryParse(indexJson.Value.ToString(), out int index))
                {
                    throw new BonsaiParseException("Expected a JSON number in 'node[1]' containing a global parameter reference to bind an expression of type 'Parameter'.", expression);
                }

                if (_globals == null || index < 0 || index >= _globals.Length)
                {
                    throw new BonsaiParseException(string.Format(CultureInfo.InvariantCulture, "A global parameter with index {0} is not defined.", index), expression);
                }

                return(_globals[index]);
            }
            else
            {
                if (expression.GetElement(1) is not Json.ConstantExpression scopeJson || !int.TryParse(scopeJson.Value.ToString(), out int scope))
                {
                    throw new BonsaiParseException("Expected a JSON number in 'node[1]' containing a parameter scope to bind an expression of type 'Parameter'.", expression);
                }

                var targetScope = GetScope(scope, expression);

                if (expression.GetElement(2) is not Json.ConstantExpression indexJson || !int.TryParse(indexJson.Value.ToString(), out int index))
                {
                    throw new BonsaiParseException("Expected a JSON number in 'node[2]' containing a parameter index to bind an expression of type 'Parameter'.", expression);
                }

                if (index < 0 || index >= targetScope.Length)
                {
                    throw new BonsaiParseException(string.Format(CultureInfo.InvariantCulture, "A parameter with index {0} is not available at scope depth {1}.", index, scope), expression);
                }

                return(targetScope[index]);
            }
        }
        /// <summary>
        /// Visits a JSON expression tree array node to produce a pretty printing string.
        /// </summary>
        /// <param name="node">JSON expression tree array node to visit.</param>
        /// <returns>Pretty printing string representation of the array node.</returns>
        public override string VisitArray(ArrayExpression node)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            // PERF: This is currently only used for debugging purposes, but we can improve this a lot.

            var sb = new StringBuilder();

            sb.AppendLine("[");
            foreach (var line in string.Join(",\n", Enumerable.Range(0, node.ElementCount).Select(i => Visit(node.GetElement(i)))).Split('\n'))
            {
                sb.Append(_indent);
                sb.AppendLine(line.TrimEnd(s_CrLf));
            }
            sb.Append(']');
            return(sb.ToString());
        }
        public IEnumerable <ParameterExpression> Push(Json.ArrayExpression parameters)
        {
            var n = parameters.ElementCount;

            var res = new ParameterExpression[n];

            for (var i = 0; i < n; i++)
            {
                var parameter = parameters.GetElement(i);

                if (parameter is not Json.ArrayExpression decl)
                {
                    throw new BonsaiParseException("Expected JSON array expression for the declaration of a 'Parameter' expression.", parameter);
                }

                var count = decl.ElementCount;
                if (count is not 1 and not 2)
                {
                    throw new BonsaiParseException("Expected 1 or 2 JSON array elements for the type reference and an optional name of a 'Parameter' expression node.", parameter);
                }

                ParameterExpression param;

                var type = GetType(decl.GetElement(0));
                if (count == 2)
                {
                    var name = (string)((Json.ConstantExpression)decl.GetElement(1)).Value;
                    param = Expression.Parameter(type, name);
                }
                else
                {
                    param = Expression.Parameter(type);
                }

                res[i] = param;
            }

            _params.Push(res);

            return(res);
        }
Exemple #9
0
        public static ArrayTypeDef FromJson(Json.ArrayExpression type)
        {
            var count = type.ElementCount;

            if (count is not(2 or 3))
            {
                throw new BonsaiParseException("Expected 2 or 3 JSON array elements for an array type definition.", type);
            }

            var elementType = TypeRef.FromJson(type.GetElement(1));
            var rank        = default(int?);

            if (count == 3)
            {
                if (type.GetElement(2) is not Json.ConstantExpression rankJson || !int.TryParse((string)rankJson.Value, out int value))
                {
                    throw new BonsaiParseException("Expected a JSON number in 'node[2]' for the rank of an array type definition.", type);
                }
                rank = value;
            }

            return(new ArrayTypeDef(elementType, rank));
        }
Exemple #10
0
            protected override ExpressionSlim VisitUnaryExpression(Json.ArrayExpression node, ExpressionType nodeType)
            {
                var newNode = Json.Expression.Array(Array.Empty <Json.Expression>());

                return(base.VisitUnaryExpression(newNode, nodeType));
            }
Exemple #11
0
            protected override ExpressionSlim VisitQuoteExpression(Json.ArrayExpression node)
            {
                var newNode = Json.Expression.Array(Array.Empty <Json.Expression>());

                return(base.VisitQuoteExpression(newNode));
            }
Exemple #12
0
            protected override MemberBindingSlim VisitMemberMemberBinding(Json.ArrayExpression node)
            {
                var newNode = Json.Expression.Array(Array.Empty <Json.Expression>());

                return(base.VisitMemberMemberBinding(newNode));
            }
Exemple #13
0
            protected override ExpressionSlim VisitConvertExpression(Json.ArrayExpression node, bool isChecked)
            {
                var newNode = Json.Expression.Array(Array.Empty <Json.Expression>());

                return(base.VisitConvertExpression(newNode, isChecked));
            }