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)); }
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 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]); } }
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)); }
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)); }
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); }
/// <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()); }