Fix garbage collection bug
This commit is contained in:
parent
255843cb3b
commit
37fd722fa6
@ -2,7 +2,7 @@ data = json:parse(fs:read_file('examples/assets/jq_data.json'))
|
|||||||
|
|
||||||
new_data = []
|
new_data = []
|
||||||
|
|
||||||
for commit_data in data {
|
for commit_data in data as collection {
|
||||||
new_data += {
|
new_data += {
|
||||||
message = commit_data:commit:message
|
message = commit_data:commit:message
|
||||||
name = commit_data:commit:committer:name
|
name = commit_data:commit:committer:name
|
||||||
|
@ -37,9 +37,15 @@ impl AbstractTree for As {
|
|||||||
fn validate(&self, _source: &str, context: &Context) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, context: &Context) -> Result<(), ValidationError> {
|
||||||
let initial_type = self.expression.expected_type(context)?;
|
let initial_type = self.expression.expected_type(context)?;
|
||||||
|
|
||||||
|
if self.r#type.accepts(&initial_type) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
if let Type::ListOf(item_type) = &self.r#type {
|
if let Type::ListOf(item_type) = &self.r#type {
|
||||||
match &initial_type {
|
match &initial_type {
|
||||||
Type::ListOf(expected_item_type) => {
|
Type::ListOf(expected_item_type) => {
|
||||||
|
println!("{item_type} {expected_item_type}");
|
||||||
|
|
||||||
if !item_type.accepts(&expected_item_type) {
|
if !item_type.accepts(&expected_item_type) {
|
||||||
return Err(ValidationError::TypeCheck {
|
return Err(ValidationError::TypeCheck {
|
||||||
expected: self.r#type.clone(),
|
expected: self.r#type.clone(),
|
||||||
@ -77,7 +83,9 @@ impl AbstractTree for As {
|
|||||||
|
|
||||||
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
fn run(&self, source: &str, context: &Context) -> Result<Value, RuntimeError> {
|
||||||
let value = self.expression.run(source, context)?;
|
let value = self.expression.run(source, context)?;
|
||||||
let converted_value = if let Type::ListOf(_) = self.r#type {
|
let converted_value = if self.r#type.accepts(&value.r#type()?) {
|
||||||
|
return Ok(value);
|
||||||
|
} else if let Type::ListOf(_) = self.r#type {
|
||||||
match value {
|
match value {
|
||||||
Value::List(list) => Value::List(list),
|
Value::List(list) => Value::List(list),
|
||||||
Value::String(string) => {
|
Value::String(string) => {
|
||||||
|
@ -66,16 +66,22 @@ impl AbstractTree for For {
|
|||||||
self.collection.validate(_source, context)?;
|
self.collection.validate(_source, context)?;
|
||||||
|
|
||||||
let collection_type = self.collection.expected_type(context)?;
|
let collection_type = self.collection.expected_type(context)?;
|
||||||
let item_type = if let Type::ListOf(item_type) = collection_type {
|
let item_type = match collection_type {
|
||||||
item_type.as_ref().clone()
|
Type::Any => Type::Any,
|
||||||
} else if let Type::Range = collection_type {
|
Type::Collection => Type::Any,
|
||||||
Type::Integer
|
Type::List => Type::Any,
|
||||||
} else {
|
Type::ListOf(_) => todo!(),
|
||||||
|
Type::ListExact(_) => todo!(),
|
||||||
|
Type::Map(_) => todo!(),
|
||||||
|
Type::String => todo!(),
|
||||||
|
Type::Range => todo!(),
|
||||||
|
_ => {
|
||||||
return Err(ValidationError::TypeCheck {
|
return Err(ValidationError::TypeCheck {
|
||||||
expected: Type::Collection,
|
expected: Type::Collection,
|
||||||
actual: collection_type,
|
actual: collection_type,
|
||||||
position: self.source_position,
|
position: self.source_position,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let key = self.item_id.clone();
|
let key = self.item_id.clone();
|
||||||
|
|
||||||
@ -116,6 +122,7 @@ impl AbstractTree for For {
|
|||||||
})?;
|
})?;
|
||||||
} else {
|
} else {
|
||||||
for value in list.items()?.iter() {
|
for value in list.items()?.iter() {
|
||||||
|
self.context.add_allowance(key)?;
|
||||||
self.context.set_value(key.clone(), value.clone())?;
|
self.context.set_value(key.clone(), value.clone())?;
|
||||||
self.block.run(source, &self.context)?;
|
self.block.run(source, &self.context)?;
|
||||||
}
|
}
|
||||||
|
@ -57,13 +57,17 @@ impl AbstractTree for IndexExpression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(&self, _source: &str, _context: &Context) -> Result<(), ValidationError> {
|
fn validate(&self, _source: &str, context: &Context) -> Result<(), ValidationError> {
|
||||||
match self {
|
match self {
|
||||||
IndexExpression::Value(value_node) => value_node.validate(_source, _context),
|
IndexExpression::Value(value_node) => value_node.validate(_source, context),
|
||||||
IndexExpression::Identifier(identifier) => identifier.validate(_source, _context),
|
IndexExpression::Identifier(identifier) => {
|
||||||
IndexExpression::Index(index) => index.validate(_source, _context),
|
context.add_allowance(identifier)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
IndexExpression::Index(index) => index.validate(_source, context),
|
||||||
IndexExpression::FunctionCall(function_call) => {
|
IndexExpression::FunctionCall(function_call) => {
|
||||||
function_call.validate(_source, _context)
|
function_call.validate(_source, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,6 +210,15 @@ impl AbstractTree for Type {
|
|||||||
|
|
||||||
Type::ListOf(Box::new(item_type))
|
Type::ListOf(Box::new(item_type))
|
||||||
}
|
}
|
||||||
|
"list" => {
|
||||||
|
let item_type_node = node.child(1);
|
||||||
|
|
||||||
|
if let Some(child) = item_type_node {
|
||||||
|
Type::ListOf(Box::new(Type::from_syntax(child, _source, context)?))
|
||||||
|
} else {
|
||||||
|
Type::List
|
||||||
|
}
|
||||||
|
}
|
||||||
"any" => Type::Any,
|
"any" => Type::Any,
|
||||||
"bool" => Type::Boolean,
|
"bool" => Type::Boolean,
|
||||||
"collection" => Type::Collection,
|
"collection" => Type::Collection,
|
||||||
@ -247,7 +256,8 @@ impl AbstractTree for Type {
|
|||||||
"str" => Type::String,
|
"str" => Type::String,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(SyntaxError::UnexpectedSyntaxNode {
|
return Err(SyntaxError::UnexpectedSyntaxNode {
|
||||||
expected: "any, bool, float, int, num, str, custom type, (, [ or {".to_string(),
|
expected: "any, bool, float, int, num, str, list, map, custom type, (, [ or {"
|
||||||
|
.to_string(),
|
||||||
actual: type_node.kind().to_string(),
|
actual: type_node.kind().to_string(),
|
||||||
position: node.range().into(),
|
position: node.range().into(),
|
||||||
})
|
})
|
||||||
|
@ -104,7 +104,18 @@ impl Value {
|
|||||||
Value::Boolean(_) => Type::Boolean,
|
Value::Boolean(_) => Type::Boolean,
|
||||||
Value::Range(_) => todo!(),
|
Value::Range(_) => todo!(),
|
||||||
Value::Struct(_) => todo!(),
|
Value::Struct(_) => todo!(),
|
||||||
Value::Enum(_) => todo!(),
|
Value::Enum(enum_instance) => {
|
||||||
|
let arguments = if let Some(value) = enum_instance.value() {
|
||||||
|
vec![value.r#type()?]
|
||||||
|
} else {
|
||||||
|
Vec::with_capacity(0)
|
||||||
|
};
|
||||||
|
|
||||||
|
Type::Custom {
|
||||||
|
name: enum_instance.name().clone(),
|
||||||
|
arguments,
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(r#type)
|
Ok(r#type)
|
||||||
|
@ -11,6 +11,7 @@ fn override_built_ins() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my_option <Option> = Option::Some('foo')
|
my_option <Option> = Option::Some('foo')
|
||||||
|
my_option
|
||||||
"
|
"
|
||||||
),
|
),
|
||||||
Ok(Value::Enum(EnumInstance::new(
|
Ok(Value::Enum(EnumInstance::new(
|
||||||
|
@ -53,3 +53,30 @@ fn nested_enum() {
|
|||||||
)))
|
)))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn enum_with_argument() {
|
||||||
|
let result = interpret(
|
||||||
|
"
|
||||||
|
enum FooBar<T> {
|
||||||
|
Foo<T>,
|
||||||
|
Bar,
|
||||||
|
}
|
||||||
|
|
||||||
|
Foobar::Bar(Fizzbuzz::Fizz)
|
||||||
|
",
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
result,
|
||||||
|
Ok(Value::Enum(EnumInstance::new(
|
||||||
|
Identifier::new("Foobar"),
|
||||||
|
Identifier::new("Bar"),
|
||||||
|
Some(Value::Enum(EnumInstance::new(
|
||||||
|
Identifier::new("Fizzbuzz"),
|
||||||
|
Identifier::new("Fizz"),
|
||||||
|
Some(Value::none())
|
||||||
|
)))
|
||||||
|
)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user