Пример #1
0
        public static MemberDef FromJson(DeserializationDomain domain, Json.Expression member)
        {
            if (member is not Json.ArrayExpression info)
            {
                throw new BonsaiParseException("Expected a JSON array for a member definition.", member);
            }

            if (info.ElementCount < 1)
            {
                throw new BonsaiParseException("Expected at least 1 JSON array element for a member definition.", member);
            }

            var type = info.GetElement(0);

            if (type.NodeType != Json.ExpressionType.String)
            {
                throw new BonsaiParseException("Expected a JSON string in 'node[0]' for the member type discriminator.", member);
            }

            var kind = (string)((Json.ConstantExpression)type).Value;

            return(kind switch
            {
                Discriminators.MemberInfo.Constructor => GetConstructorDef(domain, info),
                Discriminators.MemberInfo.Field => GetFieldDef(domain, info),
                Discriminators.MemberInfo.Property => GetPropertyDef(domain, info),
                Discriminators.MemberInfo.SimpleMethod => GetSimpleMethodDef(domain, info),
                Discriminators.MemberInfo.OpenGenericMethod => GetOpenGenericMethodDef(domain, info),
                Discriminators.MemberInfo.ClosedGenericMethod => GetClosedGenericMethodDef(info),
                _ => throw new BonsaiParseException(string.Format(CultureInfo.InvariantCulture, "Unexpected member type discriminator '{0}'.", kind), member),
            });
Пример #2
0
        private object DeserializeConstant(Json.Expression json, Type type)
        {
            object result;

            var stream = new MemoryStream();

            try
            {
                using var writer = new StreamWriter(stream);

                stream = null;

                var deserialize = _genericDeserialize.MakeGenericMethod(new[] { type });

                writer.Write(json.ToString());
                writer.Flush();

                ((MemoryStream)writer.BaseStream).Position = 0;

                result = deserialize.Invoke(_dataSerializer, new[] { writer.BaseStream as MemoryStream });
            }
            finally
            {
                stream?.Dispose();
            }

            return(result);
        }
Пример #3
0
        public static TypeDef FromJson(DeserializationDomain domain, Json.Expression expression)
        {
            if (expression is not Json.ArrayExpression type)
            {
                throw new BonsaiParseException("Expected a JSON array containing a type definition.", expression);
            }

            if (type.ElementCount == 0)
            {
                throw new BonsaiParseException("Expected at least one JSON array element containing a type discriminator.", expression);
            }

            var kind = type.GetElement(0);

            if (kind.NodeType != Json.ExpressionType.String)
            {
                throw new BonsaiParseException("Expected a JSON string at 'node[0]' containing a type discriminator.", expression);
            }

            var typeDiscriminator = (string)((Json.ConstantExpression)kind).Value;

            return(typeDiscriminator switch
            {
                Discriminators.Type.Simple => SimpleTypeDef.FromJson(type),
                Discriminators.Type.Generic => GenericTypeDef.FromJson(type),
                Discriminators.Type.Array => ArrayTypeDef.FromJson(type),
                Discriminators.Type.Anonymous => AnonymousStructuralTypeDef.FromJson(type),
                Discriminators.Type.Record => RecordStructuralTypeDef.FromJson(domain, type),
                _ => throw new BonsaiParseException(string.Format(CultureInfo.InvariantCulture, "Unexpected type discriminator '{0}' at 'node[0]'.", typeDiscriminator), expression),
            });
Пример #4
0
        public static RecordStructuralTypeMember FromJson(Json.Expression expression)
        {
            if (expression is not Json.ArrayExpression array)
            {
                throw new BonsaiParseException("Expected a JSON array for a record structural type member definition.", expression);
            }

            if (array.ElementCount != 2)
            {
                throw new BonsaiParseException("Expected 2 JSON array elements for a record structural type member definition.", expression);
            }

            var nameExpr = array.GetElement(0);

            if (nameExpr.NodeType != Json.ExpressionType.String)
            {
                throw new BonsaiParseException("Expected a JSON string in 'node[0]' for the name of a record structural type member definition.", expression);
            }

            var name = (string)((Json.ConstantExpression)nameExpr).Value;
            var type = TypeRef.FromJson(array.GetElement(1));

            return(new RecordStructuralTypeMember {
                Name = name, Type = type
            });
        }
Пример #5
0
        private Json.Expression[] EnumerateLabelTargets()
        {
            var labels = new Json.Expression[_labelTargetsDef.Count];

            var i = 0;

            foreach (var labelTarget in _labelTargetsDef)
            {
                if (labelTarget.Name == null)
                {
                    labels[i] = Json.Expression.Array(
                        _domain.AddType(labelTarget.Type).ToJson()
                        );
                }
                else
                {
                    labels[i] = Json.Expression.Array(
                        _domain.AddType(labelTarget.Type).ToJson(),
                        Json.Expression.String(labelTarget.Name)
                        );
                }

                i++;
            }

            return(labels);
        }
Пример #6
0
        public DeserializationDomain(Json.Expression json)
        {
            if (json is not Json.ObjectExpression obj)
            {
                throw new BonsaiParseException("Expected a JSON object containing the context object used by the Bonsai representation of an expression.", json);
            }

            if (obj.Members.TryGetValue("Version", out Json.Expression version))
            {
                Version = DeserializeVersion(version);
            }

            if (!obj.Members.TryGetValue("Assemblies", out Json.Expression assemblies))
            {
                throw new BonsaiParseException("Expected a JSON object property 'node.Assemblies' containing the assembly table.", json);
            }

            DeserializeAssemblies(assemblies, ref _assemblyDefs);

            if (!obj.Members.TryGetValue("Types", out Json.Expression types))
            {
                throw new BonsaiParseException("Expected a JSON object property 'node.Types' containing the type table.", json);
            }

            DeserializeTypes(types, ref _typeDefs);

            if (obj.Members.TryGetValue("Members", out Json.Expression members))
            {
                DeserializeMembers(members, ref _memberDefs);
            }
            else
            {
                _memberDefs = Array.Empty <MemberDef>();
            }
        }
Пример #7
0
        public TypeSlim GetType(Json.Expression expression, params TypeSlim[] genericArguments)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            if (expression.NodeType != Json.ExpressionType.Number)
            {
                throw new BonsaiParseException("Expected a JSON number for the type table index of the type to look up.", expression);
            }

            var index = Helpers.ParseInt32((string)((Json.ConstantExpression)expression).Value);

            if (index < 0)
            {
                return(genericArguments[-index - 1]);
            }

            if (index >= _typeDefs.Length)
            {
                throw new BonsaiParseException(string.Format(CultureInfo.InvariantCulture, "A type with index {0} was not found in the type table.", index), expression);
            }

            var def = _typeDefs[index];

            return(def.ToType(this, genericArguments));
        }
        /// <summary>
        /// Deserializes a Bonsai expression.
        /// </summary>
        /// <param name="expression">Bonsai expression to deserialize.</param>
        /// <returns>Slim expression represented by the given Bonsai.</returns>
        private ExpressionSlim JsonDeserialize(Json.Expression expression)
        {
            if (expression.NodeType == Json.ExpressionType.Null)
            {
                return(null);
            }


            if (expression is not Json.ObjectExpression obj)
            {
                throw new InvalidOperationException("Expected JSON object expression.");
            }

            if (!obj.Members.TryGetValue("Context", out Json.Expression context))
            {
                throw new InvalidOperationException("Context not found.");
            }

            if (!obj.Members.TryGetValue("Expression", out Json.Expression expr))
            {
                throw new InvalidOperationException("Expression not found.");
            }

            if (expr.NodeType == Json.ExpressionType.Null)
            {
                return(null);
            }

            var deserializationState = new DeserializationState(context, _version);

            var visitor = new DeserializerImpl(deserializationState, GetConstantDeserializerDelegate);

            return(visitor.Visit(expr));
        }
Пример #9
0
        public override Json.Expression ToJson(SerializationDomain domain)
        {
            if (domain.IsV08)
            {
                throw new NotSupportedException("Record types can only be serialized in Bonsai v0.9 or later.");
            }

            var count = _members.Length;

            var members = new Json.Expression[count];

            for (var i = 0; i < count; i++)
            {
                members[i] = _members[i].ToJson(domain);
            }

            if (!_hasValueEqualitySemantics)
            {
                return(Json.Expression.Array(
                           Discriminators.Type.RecordDiscriminator,
                           Json.Expression.Array(members),
                           Json.Expression.Boolean(false)
                           ));
            }
            else
            {
                return(Json.Expression.Array(
                           Discriminators.Type.RecordDiscriminator,
                           Json.Expression.Array(members)
                           ));
            }
        }
Пример #10
0
        private static void DeserializeAssemblies(Json.Expression assemblies, ref AssemblySlim[] assemblyDefs)
        {
            //
            // TODO: confirm this behavior, technically "optional" in Bonsai spec, so value could be null.
            //
            if (assemblies is not Json.ArrayExpression assemblyTable)
            {
                throw new BonsaiParseException("Expected a JSON array containing the assembly table.", assemblies);
            }

            var n = assemblyTable.ElementCount;

            assemblyDefs = new AssemblySlim[n];

            for (var i = 0; i < n; i++)
            {
                var assembly = assemblyTable.GetElement(i);

                if (assembly.NodeType != Json.ExpressionType.String)
                {
                    throw new BonsaiParseException("Expected a JSON string containing the an assembly name.", assembly);
                }

                var asm = new AssemblySlim((string)((Json.ConstantExpression)assembly).Value);
                assemblyDefs[i] = asm;
            }
        }
Пример #11
0
        private Json.Expression[] EnumerateGlobals()
        {
            var globals = new Json.Expression[_globalsDef.Count];

            var i = 0;

            foreach (var global in _globalsDef)
            {
                if (global.Name == null)
                {
                    globals[i] = Json.Expression.Array(
                        _domain.AddType(global.Type).ToJson()
                        );
                }
                else
                {
                    globals[i] = Json.Expression.Array(
                        _domain.AddType(global.Type).ToJson(),
                        Json.Expression.String(global.Name)
                        );
                }

                i++;
            }

            return(globals);
        }
Пример #12
0
        public DeserializationState(Json.Expression state, Version version)
        {
            _domain      = new DeserializationDomain(state);
            _params      = new Stack <ParameterExpression[]>();
            _globals     = GetGlobals(state);
            _labelTagets = GetLabelTargets(state);

            Debug.Assert(_domain.SupportsVersion(version));
        }
Пример #13
0
        private static Version DeserializeVersion(Json.Expression version)
        {
            if (version.NodeType != Json.ExpressionType.String)
            {
                throw new BonsaiParseException("Expected a JSON string containing the Bonsai version.", version);
            }

            return(new Version((string)((Json.ConstantExpression)version).Value));
        }
Пример #14
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));
            }
Пример #15
0
        public static TypeRef FromJson(Json.Expression expression)
        {
            if (expression.NodeType != Json.ExpressionType.Number)
            {
                throw new BonsaiParseException("Expected a JSON number for a type table index used in a type reference.", expression);
            }

            var index = Helpers.ParseInt32((string)((Json.ConstantExpression)expression).Value);

            return(new SimpleTypeRef(index));
        }
Пример #16
0
        public LabelTarget GetLabelTarget(Json.Expression expression)
        {
            if (expression is not Json.ConstantExpression indexJson || !int.TryParse(indexJson.Value.ToString(), out int index))
            {
                throw new BonsaiParseException("Expected a JSON number containing a label target reference.", expression);
            }

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

            return(_labelTagets[index]);
        }
Пример #17
0
        private LabelTarget[] GetLabelTargets(Json.Expression state)
        {
            if (state is not Json.ObjectExpression obj)
            {
                throw new BonsaiParseException("Expected JSON object expression for the Context property of the Bonsai expression.", state);
            }

            if (obj.Members.TryGetValue("LabelTargets", out Json.Expression res))
            {
                return(DeserializeLabelTargets(res));
            }

            return(null);
        }
Пример #18
0
        public override Json.Expression ToJson(SerializationDomain domain)
        {
            var declType = DeclaringType.ToJson();

            if (!domain.IsV08)
            {
                var indexParameterTypes = _property.IndexParameterTypes;
                var indexParameterCount = indexParameterTypes.Count;

                var indexParameterList = new Json.Expression[indexParameterCount];

                for (var i = 0; i < indexParameterCount; i++)
                {
                    indexParameterList[i] = domain.AddType(indexParameterTypes[i]).ToJson();
                }

                var indexParameters = Json.Expression.Array(indexParameterList);

                if (_property.PropertyType != null)
                {
                    var propType = domain.AddType(_property.PropertyType).ToJson();

                    return(Json.Expression.Array(
                               Discriminators.MemberInfo.PropertyDiscriminator,
                               declType,
                               Json.Expression.String(_property.Name),
                               indexParameters,
                               propType
                               ));
                }
                else
                {
                    return(Json.Expression.Array(
                               Discriminators.MemberInfo.PropertyDiscriminator,
                               declType,
                               Json.Expression.String(_property.Name),
                               indexParameters
                               ));
                }
            }
            else
            {
                return(Json.Expression.Array(
                           Discriminators.MemberInfo.PropertyDiscriminator,
                           declType,
                           Json.Expression.String(_property.Name)
                           ));
            }
        }
        /// <summary>
        /// Deserializes a Bonsai expression.
        /// </summary>
        /// <param name="expression">Bonsai expression to deserialize.</param>
        /// <returns>Slim expression represented by the given Bonsai.</returns>
        public ExpressionSlim Deserialize(Json.Expression expression)
        {
            if (expression == null)
            {
                throw new ArgumentNullException(nameof(expression));
            }

            Json.Expression expr;

            if (_mergeContext && _deserializationState != null)
            {
                expr = expression;
            }
            else
            {
                if (expression.NodeType == Json.ExpressionType.Null)
                {
                    return(null);
                }

                if (expression is not Json.ObjectExpression obj)
                {
                    throw new BonsaiParseException("Expected a JSON object containing the Bonsai representation of an expression.", expression);
                }

                if (!obj.Members.TryGetValue("Context", out Json.Expression context))
                {
                    throw new BonsaiParseException("Expected a JSON object property 'node.Context' containing the context object.", expression);
                }

                if (!obj.Members.TryGetValue("Expression", out expr))
                {
                    throw new BonsaiParseException("Expected a JSON object property 'node.Expression' containing the expression tree.", expression);
                }

                _deserializationState = new DeserializationState(context, _version);
            }

            if (expr.NodeType == Json.ExpressionType.Null)
            {
                return(null);
            }

            var visitor = new DeserializerImpl(_deserializationState, _reduceFactory);

            return(visitor.Visit(expr));
        }
Пример #20
0
        public override Json.Expression ToJson(SerializationDomain domain)
        {
            var count = _genericArguments.Length;

            var arguments = new Json.Expression[count];

            for (var i = 0; i < count; i++)
            {
                arguments[i] = _genericArguments[i].ToJson();
            }

            return(Json.Expression.Array(
                       Discriminators.MemberInfo.ClosedGenericMethodDiscriminator,
                       _genericMethodDefinition,
                       Json.Expression.Array(arguments)
                       ));
        }
Пример #21
0
        public override Json.Expression ToJson(SerializationDomain domain)
        {
            var count = _parameters.Length;

            var parameters = new Json.Expression[count];

            for (var i = 0; i < count; i++)
            {
                parameters[i] = _parameters[i].ToJson();
            }

            return(Json.Expression.Array(
                       Discriminators.MemberInfo.ConstructorDiscriminator,
                       DeclaringType.ToJson(),
                       Json.Expression.Array(parameters)
                       ));
        }
Пример #22
0
        public override Json.Expression ToJson(SerializationDomain domain)
        {
            var n = _members.Length;

            var args = new Json.Expression[n + 1];

            args[0] = Discriminators.Type.AnonymousDiscriminator;

            for (var i = 0; i < n; i++)
            {
                args[i + 1] = _members[i].ToJson(domain);
            }

            return(Json.Expression.Array(
                       args
                       ));
        }
Пример #23
0
        public override Json.Expression ToJson(SerializationDomain domain)
        {
            var count = _genericTypeArguments.Length;

            var genericTypeArguments = new Json.Expression[count];

            for (var i = 0; i < count; i++)
            {
                genericTypeArguments[i] = _genericTypeArguments[i].ToJson();
            }

            return(Json.Expression.Array(
                       Discriminators.Type.GenericDiscriminator,
                       _genericTypeDefinition.ToJson(),
                       Json.Expression.Array(genericTypeArguments)
                       ));
        }
 protected override Json.Expression MakeBinary(BinaryExpression node, Json.Expression left, Json.Expression conversion, Json.Expression right)
 {
     return(node.NodeType switch
     {
         ExpressionType.Add => VisitBinarySimple(node, Discriminators.Expression.PlusDiscriminator, left, right),
         ExpressionType.AddChecked => VisitBinarySimple(node, Discriminators.Expression.PlusDollarDiscriminator, left, right),
         ExpressionType.Subtract => VisitBinarySimple(node, Discriminators.Expression.MinusDiscriminator, left, right),
         ExpressionType.SubtractChecked => VisitBinarySimple(node, Discriminators.Expression.MinusDollarDiscriminator, left, right),
         ExpressionType.Multiply => VisitBinarySimple(node, Discriminators.Expression.MultiplyDiscriminator, left, right),
         ExpressionType.MultiplyChecked => VisitBinarySimple(node, Discriminators.Expression.MultiplyCheckedDiscriminator, left, right),
         ExpressionType.Divide => VisitBinarySimple(node, Discriminators.Expression.DivideDiscriminator, left, right),
         ExpressionType.Modulo => VisitBinarySimple(node, Discriminators.Expression.ModuloDiscriminator, left, right),
         ExpressionType.Power => VisitBinarySimple(node, Discriminators.Expression.PowerDiscriminator, left, right),
         ExpressionType.RightShift => VisitBinarySimple(node, Discriminators.Expression.RightShiftDiscriminator, left, right),
         ExpressionType.LeftShift => VisitBinarySimple(node, Discriminators.Expression.LeftShiftDiscriminator, left, right),
         ExpressionType.LessThan => VisitBinaryComparison(node, Discriminators.Expression.LessThanDiscriminator, left, right),
         ExpressionType.LessThanOrEqual => VisitBinaryComparison(node, Discriminators.Expression.LessThanOrEqualDiscriminator, left, right),
         ExpressionType.GreaterThan => VisitBinaryComparison(node, Discriminators.Expression.GreaterThanDiscriminator, left, right),
         ExpressionType.GreaterThanOrEqual => VisitBinaryComparison(node, Discriminators.Expression.GreaterThanOrEqualDiscriminator, left, right),
         ExpressionType.Equal => VisitBinaryComparison(node, Discriminators.Expression.EqualDiscriminator, left, right),
         ExpressionType.NotEqual => VisitBinaryComparison(node, Discriminators.Expression.NotEqualDiscriminator, left, right),
         ExpressionType.And => VisitBinarySimple(node, Discriminators.Expression.AndDiscriminator, left, right),
         ExpressionType.AndAlso => VisitBinarySimple(node, Discriminators.Expression.AndAlsoDiscriminator, left, right),
         ExpressionType.Or => VisitBinarySimple(node, Discriminators.Expression.OrDiscriminator, left, right),
         ExpressionType.OrElse => VisitBinarySimple(node, Discriminators.Expression.OrElseDiscriminator, left, right),
         ExpressionType.ExclusiveOr => VisitBinarySimple(node, Discriminators.Expression.ExclusiveOrDiscriminator, left, right),
         ExpressionType.Coalesce => VisitBinaryCoalesce(node, left, conversion, right),
         ExpressionType.ArrayIndex => VisitBinarySimple(node, Discriminators.Expression.ArrayIndexDiscriminator, left, right),
         ExpressionType.Assign => VisitBinarySimple(node, Discriminators.Expression.AssignDiscriminator, left, right),
         ExpressionType.AddAssign => VisitBinaryOpAssign(node, Discriminators.Expression.AddAssignDiscriminator, left, conversion, right),
         ExpressionType.AddAssignChecked => VisitBinaryOpAssign(node, Discriminators.Expression.AddAssignCheckedDiscriminator, left, conversion, right),
         ExpressionType.AndAssign => VisitBinaryOpAssign(node, Discriminators.Expression.AndAssignDiscriminator, left, conversion, right),
         ExpressionType.DivideAssign => VisitBinaryOpAssign(node, Discriminators.Expression.DivideAssignDiscriminator, left, conversion, right),
         ExpressionType.ExclusiveOrAssign => VisitBinaryOpAssign(node, Discriminators.Expression.ExclusiveOrAssignDiscriminator, left, conversion, right),
         ExpressionType.LeftShiftAssign => VisitBinaryOpAssign(node, Discriminators.Expression.LeftShiftAssignDiscriminator, left, conversion, right),
         ExpressionType.ModuloAssign => VisitBinaryOpAssign(node, Discriminators.Expression.ModuloAssignDiscriminator, left, conversion, right),
         ExpressionType.MultiplyAssign => VisitBinaryOpAssign(node, Discriminators.Expression.MultiplyAssignDiscriminator, left, conversion, right),
         ExpressionType.MultiplyAssignChecked => VisitBinaryOpAssign(node, Discriminators.Expression.MultiplyAssignCheckedDiscriminator, left, conversion, right),
         ExpressionType.OrAssign => VisitBinaryOpAssign(node, Discriminators.Expression.OrAssignDiscriminator, left, conversion, right),
         ExpressionType.PowerAssign => VisitBinaryOpAssign(node, Discriminators.Expression.PowerAssignDiscriminator, left, conversion, right),
         ExpressionType.RightShiftAssign => VisitBinaryOpAssign(node, Discriminators.Expression.RightShiftAssignDiscriminator, left, conversion, right),
         ExpressionType.SubtractAssign => VisitBinaryOpAssign(node, Discriminators.Expression.SubtractAssignDiscriminator, left, conversion, right),
         ExpressionType.SubtractAssignChecked => VisitBinaryOpAssign(node, Discriminators.Expression.SubtractAssignCheckedDiscriminator, left, conversion, right),
         _ => throw new NotImplementedException(),
     });
Пример #25
0
        public override Json.Expression ToJson(SerializationDomain domain)
        {
            var count = Parameters.Length;

            var parameters = new Json.Expression[count];

            for (var i = 0; i < count; i++)
            {
                parameters[i] = Parameters[i].ToJson();
            }

            return(Json.Expression.Array(
                       Discriminators.MemberInfo.SimpleMethodDiscriminator,
                       DeclaringType.ToJson(),
                       Json.Expression.String(((SimpleMethodInfoSlim)Method).Name),
                       Json.Expression.Array(parameters),
                       ReturnType.ToJson()
                       ));
        }
Пример #26
0
        public static AnonymousStructuralTypeMember FromJson(Json.Expression expression)
        {
            if (expression is not Json.ArrayExpression array)
            {
                throw new BonsaiParseException("Expected a JSON array for an anonymous structural type member definition.", expression);
            }

            var count = array.ElementCount;

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

            var nameExpr = array.GetElement(0);

            if (nameExpr.NodeType != Json.ExpressionType.String)
            {
                throw new BonsaiParseException("Expected a JSON string in 'node[0]' for the name of an anonymous structural type member definition.", expression);
            }

            var name = (string)((Json.ConstantExpression)nameExpr).Value;
            var type = TypeRef.FromJson(array.GetElement(1));

            var isKey = true;

            if (count == 3)
            {
                var isKeyExpr = array.GetElement(2);

                if (isKeyExpr.NodeType != Json.ExpressionType.Boolean)
                {
                    throw new BonsaiParseException("Expected a JSON Boolean in 'node[2]' for IsKey flag of an anonymous structural type member definition.", expression);
                }

                isKey = (bool)((Json.ConstantExpression)isKeyExpr).Value;
            }

            return(new AnonymousStructuralTypeMember {
                Name = name, Type = type, IsKey = isKey
            });
        }
Пример #27
0
        private ParameterExpression[] GetScope(int index, Json.Expression expression)
        {
            if (index >= 0)
            {
                var idx = index;

                using var e = _params.GetEnumerator();

                while (e.MoveNext())
                {
                    if (idx == 0)
                    {
                        return(e.Current);
                    }

                    idx--;
                }
            }

            throw new BonsaiParseException(string.Format(CultureInfo.InvariantCulture, "A scope with index {0} is invalid at the current scope depth in the expression.", index), expression);
        }
Пример #28
0
        private ParameterExpression[] DeserializeGlobals(Json.Expression globals)
        {
            if (globals is not Json.ArrayExpression globalTable)
            {
                throw new BonsaiParseException("Expected JSON array expression for the Globals property of the Bonsai expression context.", globals);
            }

            var n = globalTable.ElementCount;

            var d = new ParameterExpression[n];

            for (var i = 0; i < n; i++)
            {
                var globalRow = globalTable.GetElement(i);

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

                var count = globalJson.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 global 'Parameter' expression node.", globalRow);
                }

                var parameterType = _domain.GetType(globalJson.GetElement(0));

                var parameterName = default(string);
                if (count == 2)
                {
                    parameterName = ((Json.ConstantExpression)globalJson.GetElement(1)).Value.ToString();
                }

                d[i] = Expression.Parameter(parameterType, parameterName);
            }

            return(d);
        }
Пример #29
0
        private LabelTarget[] DeserializeLabelTargets(Json.Expression labelTargets)
        {
            if (labelTargets is not Json.ArrayExpression labelTable)
            {
                throw new BonsaiParseException("Expected JSON array expression for the LabelTargets property of the Bonsai expression context.", labelTargets);
            }

            var n = labelTable.ElementCount;

            var d = new LabelTarget[n];

            for (var i = 0; i < n; i++)
            {
                var labelTargetRow = labelTable.GetElement(i);

                if (labelTargetRow is not Json.ArrayExpression labelTargetJson)
                {
                    throw new BonsaiParseException("Expected JSON array expression for the declaration of a 'LabelTarget' node.", labelTargetRow);
                }

                var count = labelTargetJson.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 'LabelTarget' node.", labelTargetRow);
                }

                var labelTargetType = _domain.GetType(labelTargetJson.GetElement(0));

                var labelTargetName = default(string);
                if (count == 2)
                {
                    labelTargetName = ((Json.ConstantExpression)labelTargetJson.GetElement(1)).Value.ToString();
                }

                d[i] = Expression.Label(labelTargetType, labelTargetName);
            }

            return(d);
        }
Пример #30
0
        private void DeserializeMembers(Json.Expression members, ref MemberDef[] memberDefs)
        {
            //
            // TODO: confirm this behavior, technically "optional" in Bonsai spec, so value could be null.
            //
            if (members is not Json.ArrayExpression memberTable)
            {
                throw new BonsaiParseException("Expected a JSON array containing the members table.", members);
            }

            var n = memberTable.ElementCount;

            memberDefs = new MemberDef[n];

            for (var i = 0; i < n; i++)
            {
                var member = memberTable.GetElement(i);

                var memberDef = MemberDef.FromJson(this, member);
                memberDefs[i] = memberDef;
            }
        }