1
0

Add index expressions to fix parsing bug

This commit is contained in:
Jeff 2023-12-31 23:38:09 -05:00
parent 346ff1c0da
commit 2f0ec91c08
18 changed files with 21644 additions and 17757 deletions

View File

@ -30,10 +30,6 @@ impl AbstractTree for Identifier {
let text = &source[node.byte_range()]; let text = &source[node.byte_range()];
if text.is_empty() {
println!("{node:?}");
}
debug_assert!(!text.is_empty()); debug_assert!(!text.is_empty());
Ok(Identifier(text.to_string())) Ok(Identifier(text.to_string()))

View File

@ -1,16 +1,16 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Error, Expression, List, Map, Result, Type, Value}; use crate::{AbstractTree, Error, IndexExpression, List, Map, Result, Type, Value};
/// Abstract representation of an index expression. /// Abstract representation of an index expression.
/// ///
/// An index is a means of accessing values stored in list, maps and strings. /// An index is a means of accessing values stored in list, maps and strings.
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Index { pub struct Index {
pub collection: Expression, pub collection: IndexExpression,
pub index: Expression, pub index: IndexExpression,
pub index_end: Option<Expression>, pub index_end: Option<IndexExpression>,
} }
impl AbstractTree for Index { impl AbstractTree for Index {
@ -18,14 +18,14 @@ impl AbstractTree for Index {
Error::expect_syntax_node(source, "index", node)?; Error::expect_syntax_node(source, "index", node)?;
let collection_node = node.child(0).unwrap(); let collection_node = node.child(0).unwrap();
let collection = Expression::from_syntax_node(source, collection_node, context)?; let collection = IndexExpression::from_syntax_node(source, collection_node, context)?;
let index_node = node.child(2).unwrap(); let index_node = node.child(2).unwrap();
let index = Expression::from_syntax_node(source, index_node, context)?; let index = IndexExpression::from_syntax_node(source, index_node, context)?;
let index_end_node = node.child(4); let index_end_node = node.child(4);
let index_end = if let Some(index_end_node) = index_end_node { let index_end = if let Some(index_end_node) = index_end_node {
Some(Expression::from_syntax_node( Some(IndexExpression::from_syntax_node(
source, source,
index_end_node, index_end_node,
context, context,
@ -60,7 +60,7 @@ impl AbstractTree for Index {
Ok(item) Ok(item)
} }
Value::Map(map) => { Value::Map(map) => {
let value = if let Expression::Identifier(identifier) = &self.index { let value = if let IndexExpression::Identifier(identifier) = &self.index {
let key = identifier.inner(); let key = identifier.inner();
map.variables()? map.variables()?

View File

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Error, Index, Map, Result, Statement, Type, Value}; use crate::{AbstractTree, Error, Index, IndexExpression, Map, Result, Statement, Type, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct IndexAssignment { pub struct IndexAssignment {
@ -52,7 +52,7 @@ impl AbstractTree for IndexAssignment {
fn run(&self, source: &str, context: &Map) -> Result<Value> { fn run(&self, source: &str, context: &Map) -> Result<Value> {
let index_collection = self.index.collection.run(source, context)?; let index_collection = self.index.collection.run(source, context)?;
let index_context = index_collection.as_map().unwrap_or(context); let index_context = index_collection.as_map().unwrap_or(context);
let index_key = if let crate::Expression::Identifier(identifier) = &self.index.index { let index_key = if let IndexExpression::Identifier(identifier) = &self.index.index {
identifier.inner() identifier.inner()
} else { } else {
return Err(Error::VariableIdentifierNotFound( return Err(Error::VariableIdentifierNotFound(

View File

@ -0,0 +1,68 @@
use serde::{Deserialize, Serialize};
use crate::{
value_node::ValueNode, AbstractTree, Error, FunctionCall, Identifier, Index, Map, Result, Type,
Value,
};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub enum IndexExpression {
Value(ValueNode),
Identifier(Identifier),
Index(Box<Index>),
FunctionCall(Box<FunctionCall>),
}
impl AbstractTree for IndexExpression {
fn from_syntax_node(source: &str, node: tree_sitter::Node, context: &Map) -> Result<Self> {
Error::expect_syntax_node(source, "index_expression", node)?;
let first_child = node.child(0).unwrap();
let child = if first_child.is_named() {
first_child
} else {
node.child(1).unwrap()
};
let abstract_node = match child.kind() {
"value" => IndexExpression::Value(ValueNode::from_syntax_node(source, child, context)?),
"identifier" => {
IndexExpression::Identifier(Identifier::from_syntax_node(source, child, context)?)
}
"index" => {
IndexExpression::Index(Box::new(Index::from_syntax_node(source, child, context)?))
}
"function_call" => IndexExpression::FunctionCall(Box::new(
FunctionCall::from_syntax_node(source, child, context)?,
)),
_ => {
return Err(Error::UnexpectedSyntaxNode {
expected: "value, identifier, index or function call".to_string(),
actual: child.kind().to_string(),
location: child.start_position(),
relevant_source: source[child.byte_range()].to_string(),
})
}
};
Ok(abstract_node)
}
fn run(&self, source: &str, context: &Map) -> Result<Value> {
match self {
IndexExpression::Value(value_node) => value_node.run(source, context),
IndexExpression::Identifier(identifier) => identifier.run(source, context),
IndexExpression::Index(index) => index.run(source, context),
IndexExpression::FunctionCall(function_call) => function_call.run(source, context),
}
}
fn expected_type(&self, context: &Map) -> Result<Type> {
match self {
IndexExpression::Value(value_node) => value_node.expected_type(context),
IndexExpression::Identifier(identifier) => identifier.expected_type(context),
IndexExpression::Index(index) => index.expected_type(context),
IndexExpression::FunctionCall(function_call) => function_call.expected_type(context),
}
}
}

View File

@ -16,6 +16,7 @@ pub mod identifier;
pub mod if_else; pub mod if_else;
pub mod index; pub mod index;
pub mod index_assignment; pub mod index_assignment;
pub mod index_expression;
pub mod logic; pub mod logic;
pub mod r#match; pub mod r#match;
pub mod math; pub mod math;
@ -27,8 +28,9 @@ pub mod r#yield;
pub use { pub use {
assignment::*, block::*, expression::*, function_call::*, function_expression::*, assignment::*, block::*, expression::*, function_call::*, function_expression::*,
identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, logic::*, math::*, identifier::*, if_else::*, index::*, index_assignment::IndexAssignment, index_expression::*,
r#for::*, r#match::*, r#while::*, r#yield::*, statement::*, type_definition::*, value_node::*, logic::*, math::*, r#for::*, r#match::*, r#while::*, r#yield::*, statement::*,
type_definition::*, value_node::*,
}; };
use tree_sitter::Node; use tree_sitter::Node;

View File

@ -4,8 +4,8 @@ use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{ use crate::{
AbstractTree, Block, Error, Expression, Function, Identifier, List, Map, Result, Statement, value::BuiltInValue, AbstractTree, Block, Error, Expression, Function, Identifier, List, Map,
Type, TypeDefinition, Value, Result, Statement, Type, TypeDefinition, Value,
}; };
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
@ -18,6 +18,7 @@ pub enum ValueNode {
List(Vec<Expression>), List(Vec<Expression>),
Option(Option<Box<Expression>>), Option(Option<Box<Expression>>),
Map(BTreeMap<String, (Statement, Option<Type>)>), Map(BTreeMap<String, (Statement, Option<Type>)>),
BuiltInValue(BuiltInValue),
} }
impl AbstractTree for ValueNode { impl AbstractTree for ValueNode {
@ -150,6 +151,15 @@ impl AbstractTree for ValueNode {
ValueNode::Option(Some(Box::new(expression))) ValueNode::Option(Some(Box::new(expression)))
} }
} }
"built_in_value" => {
let built_in_value_node = child.child(0).unwrap();
ValueNode::BuiltInValue(BuiltInValue::from_syntax_node(
source,
built_in_value_node,
context,
)?)
}
_ => { _ => {
return Err(Error::UnexpectedSyntaxNode { return Err(Error::UnexpectedSyntaxNode {
expected: "string, integer, float, boolean, list, map, or option".to_string(), expected: "string, integer, float, boolean, list, map, or option".to_string(),
@ -203,6 +213,7 @@ impl AbstractTree for ValueNode {
Value::Map(map) Value::Map(map)
} }
ValueNode::BuiltInValue(built_in_value) => built_in_value.run(source, context)?,
}; };
Ok(value) Ok(value)
@ -244,6 +255,7 @@ impl AbstractTree for ValueNode {
} }
} }
ValueNode::Map(_) => Type::Map, ValueNode::Map(_) => Type::Map,
ValueNode::BuiltInValue(built_in_value) => built_in_value.expected_type(context)?,
}; };
Ok(r#type) Ok(r#type)

View File

@ -223,5 +223,6 @@ fn display_value(value: &Value, ui: &mut egui::Ui) {
ui.label("none"); ui.label("none");
} }
}, },
Value::BuiltIn(_) => todo!(),
} }
} }

View File

@ -11,14 +11,13 @@ mod option;
mod output; mod output;
mod packages; mod packages;
mod random; mod random;
mod std;
mod r#type; mod r#type;
/// All built-in functions recognized by the interpreter. /// All built-in functions recognized by the interpreter.
/// ///
/// This is the public interface to access built-in functions by iterating over /// This is the public interface to access built-in functions by iterating over
/// the references it holds. /// the references it holds.
pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 22] = [ pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 21] = [
&assert::Assert, &assert::Assert,
&assert::AssertEqual, &assert::AssertEqual,
&collections::Length, &collections::Length,
@ -39,7 +38,6 @@ pub const BUILT_IN_FUNCTIONS: [&dyn BuiltInFunction; 22] = [
&random::RandomBoolean, &random::RandomBoolean,
&random::RandomFloat, &random::RandomFloat,
&random::RandomInteger, &random::RandomInteger,
&std::Std,
&r#type::TypeFunction, &r#type::TypeFunction,
]; ];

View File

@ -1,35 +0,0 @@
use std::sync::OnceLock;
use crate::{interpret_with_context, BuiltInFunction, Error, Map, Result, Type, Value};
static STD: OnceLock<Map> = OnceLock::new();
pub struct Std;
impl BuiltInFunction for Std {
fn name(&self) -> &'static str {
"std"
}
fn run(&self, arguments: &[Value], _context: &Map) -> Result<Value> {
Error::expect_argument_amount(self, 0, arguments.len())?;
let std_context = STD.get_or_init(|| {
let std_source = "say_hi = () <none> { output('hi') }";
let std_context = Map::new();
interpret_with_context(std_source, std_context.clone()).unwrap();
std_context
});
Ok(Value::Map(std_context.clone()))
}
fn r#type(&self) -> Type {
Type::Function {
parameter_types: vec![],
return_type: Box::new(Type::Map),
}
}
}

View File

@ -1,7 +1,7 @@
//! Types that represent runtime values. //! Types that represent runtime values.
use crate::{ use crate::{
error::{Error, Result}, error::{Error, Result},
Function, List, Map, Type, interpret_with_context, AbstractTree, Function, List, Map, Type,
}; };
use serde::{ use serde::{
@ -9,6 +9,7 @@ use serde::{
ser::SerializeTuple, ser::SerializeTuple,
Deserialize, Serialize, Serializer, Deserialize, Serialize, Serializer,
}; };
use tree_sitter::Node;
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
@ -16,12 +17,60 @@ use std::{
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
marker::PhantomData, marker::PhantomData,
ops::{Add, AddAssign, Div, Mul, Rem, Sub, SubAssign}, ops::{Add, AddAssign, Div, Mul, Rem, Sub, SubAssign},
sync::OnceLock,
}; };
pub mod function; pub mod function;
pub mod list; pub mod list;
pub mod map; pub mod map;
static STD: OnceLock<Value> = OnceLock::new();
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum BuiltInValue {
Std,
}
impl BuiltInValue {
fn r#type(&self) -> Type {
match self {
BuiltInValue::Std => Type::Map,
}
}
fn get(&self) -> &Value {
STD.get_or_init(|| {
let std_source = "foobar = () <str> { 'foobar' }";
let std_context = Map::new();
interpret_with_context(std_source, std_context.clone()).unwrap();
Value::Map(std_context)
})
}
}
impl AbstractTree for BuiltInValue {
fn from_syntax_node(_source: &str, node: Node, _context: &Map) -> Result<Self> {
let built_in_value = match node.kind() {
"std" => BuiltInValue::Std,
_ => todo!(),
};
Ok(built_in_value)
}
fn run(&self, _source: &str, _context: &Map) -> Result<Value> {
Ok(self.get().clone())
}
fn expected_type(&self, _context: &Map) -> Result<Type> {
match self {
BuiltInValue::Std => Ok(Type::Map),
}
}
}
/// Dust value representation. /// Dust value representation.
/// ///
/// Every dust variable has a key and a Value. Variables are represented by /// Every dust variable has a key and a Value. Variables are represented by
@ -37,6 +86,7 @@ pub enum Value {
Integer(i64), Integer(i64),
Boolean(bool), Boolean(bool),
Option(Option<Box<Value>>), Option(Option<Box<Value>>),
BuiltIn(BuiltInValue),
} }
impl Default for Value { impl Default for Value {
@ -82,6 +132,7 @@ impl Value {
Type::None Type::None
} }
} }
Value::BuiltIn(built_in_value) => built_in_value.r#type(),
}; };
r#type r#type
@ -420,6 +471,8 @@ impl PartialOrd for Value {
impl Ord for Value { impl Ord for Value {
fn cmp(&self, other: &Self) -> Ordering { fn cmp(&self, other: &Self) -> Ordering {
match (self, other) { match (self, other) {
(Value::BuiltIn(left), Value::BuiltIn(right)) => left.cmp(right),
(Value::BuiltIn(_), _) => Ordering::Greater,
(Value::String(left), Value::String(right)) => left.cmp(right), (Value::String(left), Value::String(right)) => left.cmp(right),
(Value::String(_), _) => Ordering::Greater, (Value::String(_), _) => Ordering::Greater,
(Value::Float(left), Value::Float(right)) => left.total_cmp(right), (Value::Float(left), Value::Float(right)) => left.total_cmp(right),
@ -471,6 +524,7 @@ impl Serialize for Value {
Value::Option(inner) => inner.serialize(serializer), Value::Option(inner) => inner.serialize(serializer),
Value::Map(inner) => inner.serialize(serializer), Value::Map(inner) => inner.serialize(serializer),
Value::Function(inner) => inner.serialize(serializer), Value::Function(inner) => inner.serialize(serializer),
Value::BuiltIn(inner) => inner.serialize(serializer),
} }
} }
} }
@ -498,6 +552,7 @@ impl Display for Value {
} }
Value::Map(map) => write!(f, "{map}"), Value::Map(map) => write!(f, "{map}"),
Value::Function(function) => write!(f, "{function}"), Value::Function(function) => write!(f, "{function}"),
Value::BuiltIn(_) => todo!(),
} }
} }
} }

View File

@ -344,7 +344,7 @@ mod index {
" "
x = [1 2 3] x = [1 2 3]
y = () <int> { 2 } y = () <int> { 2 }
x:y() x:(y())
", ",
), ),
Ok(Value::Integer(3)) Ok(Value::Integer(3))
@ -356,7 +356,7 @@ mod index {
x = { x = {
y = () <int> { 2 } y = () <int> { 2 }
} }
(x:y)() x:y()
", ",
), ),
Ok(Value::Integer(2)) Ok(Value::Integer(2))

View File

@ -46,9 +46,9 @@ x:y = 1
(statement (statement
(index_assignment (index_assignment
(index (index
(expression (index_expression
(identifier)) (identifier))
(expression (index_expression
(identifier))) (identifier)))
(assignment_operator) (assignment_operator)
(statement (statement
@ -68,9 +68,9 @@ x:9 = 'foobar'
(statement (statement
(index_assignment (index_assignment
(index (index
(expression (index_expression
(identifier)) (identifier))
(expression (index_expression
(value (value
(integer)))) (integer))))
(assignment_operator) (assignment_operator)

View File

@ -85,16 +85,16 @@ foo:bar("Hiya")
(root (root
(statement (statement
(expression (expression
(index (function_call
(expression (function_expression
(identifier)) (index
(expression (index_expression
(function_call
(function_expression
(identifier)) (identifier))
(expression (index_expression
(value (identifier))))
(string))))))))) (expression
(value
(string)))))))
================================================================================ ================================================================================
Double Function Call Double Function Call

View File

@ -14,33 +14,33 @@ foobar:1:42
(statement (statement
(expression (expression
(index (index
(expression (index_expression
(index (index
(expression (index_expression
(identifier)) (identifier))
(expression (index_expression
(value (value
(integer))))) (integer)))))
(expression (index_expression
(identifier))))) (identifier)))))
(statement (statement
(expression (expression
(index (index
(expression (index_expression
(identifier)) (identifier))
(expression (index_expression
(identifier))))) (identifier)))))
(statement (statement
(expression (expression
(index (index
(expression (index_expression
(index (index
(expression (index_expression
(identifier)) (identifier))
(expression (index_expression
(value (value
(integer))))) (integer)))))
(expression (index_expression
(value (value
(integer))))))) (integer)))))))
@ -56,11 +56,11 @@ Nested Indexes
(statement (statement
(expression (expression
(index (index
(expression (index_expression
(index (index
(expression (index_expression
(index (index
(expression (index_expression
(value (value
(list (list
(expression (expression
@ -78,13 +78,13 @@ Nested Indexes
(expression (expression
(value (value
(integer)))))) (integer))))))
(expression (index_expression
(value (value
(integer))))) (integer)))))
(expression (index_expression
(value (value
(integer))))) (integer)))))
(expression (index_expression
(value (value
(integer))) (integer)))
(expression (expression
@ -95,7 +95,7 @@ Nested Indexes
Function Call Index Function Call Index
================================================================================ ================================================================================
x:y():0 x:(y()):0
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -103,14 +103,14 @@ x:y():0
(statement (statement
(expression (expression
(index (index
(expression (index_expression
(index (index
(expression (index_expression
(identifier)) (identifier))
(expression (index_expression
(function_call (function_call
(function_expression (function_expression
(identifier)))))) (identifier))))))
(expression (index_expression
(value (value
(integer))))))) (integer)))))))

View File

@ -89,6 +89,7 @@ module.exports = grammar({
$.list, $.list,
$.map, $.map,
$.option, $.option,
$.built_in_value,
), ),
integer: $ => integer: $ =>
@ -202,15 +203,30 @@ module.exports = grammar({
prec.left( prec.left(
1, 1,
seq( seq(
$.expression, $.index_expression,
':', ':',
$.expression, $.index_expression,
optional( optional(
seq('..', $.expression), seq('..', $.expression),
), ),
), ),
), ),
index_expression: $ =>
prec(
1,
choice(
seq(
'(',
$.function_call,
')',
),
$.identifier,
$.index,
$.value,
),
),
math: $ => math: $ =>
prec.left( prec.left(
seq( seq(
@ -388,8 +404,9 @@ module.exports = grammar({
_function_expression_kind: $ => _function_expression_kind: $ =>
prec( prec(
1, 2,
choice( choice(
$.built_in_value,
$.function, $.function,
$.function_call, $.function_call,
$.identifier, $.identifier,
@ -397,6 +414,7 @@ module.exports = grammar({
$.yield, $.yield,
), ),
), ),
function_call: $ => function_call: $ =>
prec.right( prec.right(
seq( seq(
@ -447,5 +465,7 @@ module.exports = grammar({
'to_json', 'to_json',
'write', 'write',
), ),
built_in_value: $ => choice('std'),
}, },
}); });

View File

@ -253,6 +253,10 @@
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "option" "name": "option"
},
{
"type": "SYMBOL",
"name": "built_in_value"
} }
] ]
}, },
@ -605,7 +609,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expression" "name": "index_expression"
}, },
{ {
"type": "STRING", "type": "STRING",
@ -613,7 +617,7 @@
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "expression" "name": "index_expression"
}, },
{ {
"type": "CHOICE", "type": "CHOICE",
@ -639,6 +643,44 @@
] ]
} }
}, },
"index_expression": {
"type": "PREC",
"value": 1,
"content": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "("
},
{
"type": "SYMBOL",
"name": "function_call"
},
{
"type": "STRING",
"value": ")"
}
]
},
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "SYMBOL",
"name": "index"
},
{
"type": "SYMBOL",
"name": "value"
}
]
}
},
"math": { "math": {
"type": "PREC_LEFT", "type": "PREC_LEFT",
"value": 0, "value": 0,
@ -1258,10 +1300,14 @@
}, },
"_function_expression_kind": { "_function_expression_kind": {
"type": "PREC", "type": "PREC",
"value": 1, "value": 2,
"content": { "content": {
"type": "CHOICE", "type": "CHOICE",
"members": [ "members": [
{
"type": "SYMBOL",
"name": "built_in_value"
},
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "function" "name": "function"
@ -1448,6 +1494,15 @@
"value": "write" "value": "write"
} }
] ]
},
"built_in_value": {
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "std"
}
]
} }
}, },
"extras": [ "extras": [

View File

@ -56,6 +56,11 @@
"named": true, "named": true,
"fields": {} "fields": {}
}, },
{
"type": "built_in_value",
"named": true,
"fields": {}
},
{ {
"type": "else", "type": "else",
"named": true, "named": true,
@ -202,6 +207,10 @@
"multiple": false, "multiple": false,
"required": true, "required": true,
"types": [ "types": [
{
"type": "built_in_value",
"named": true
},
{ {
"type": "function", "type": "function",
"named": true "named": true
@ -293,6 +302,10 @@
{ {
"type": "expression", "type": "expression",
"named": true "named": true
},
{
"type": "index_expression",
"named": true
} }
] ]
} }
@ -320,6 +333,33 @@
] ]
} }
}, },
{
"type": "index_expression",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "function_call",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "index",
"named": true
},
{
"type": "value",
"named": true
}
]
}
},
{ {
"type": "list", "type": "list",
"named": true, "named": true,
@ -559,6 +599,10 @@
"type": "boolean", "type": "boolean",
"named": true "named": true
}, },
{
"type": "built_in_value",
"named": true
},
{ {
"type": "float", "type": "float",
"named": true "named": true
@ -884,6 +928,10 @@
"type": "some", "type": "some",
"named": false "named": false
}, },
{
"type": "std",
"named": false
},
{ {
"type": "str", "type": "str",
"named": false "named": false

File diff suppressed because it is too large Load Diff