Clean up
This commit is contained in:
parent
e1e40cf931
commit
956def5ec6
@ -17,8 +17,8 @@ use crate::{
|
||||
PrimitiveValueExpression, RangeExpression, Span, Statement, StructDefinition,
|
||||
StructExpression, TupleAccessExpression,
|
||||
},
|
||||
core_library, parse, Context, ContextError, DustError, Expression, Identifier, StructType,
|
||||
Type,
|
||||
core_library, parse, Context, ContextError, DustError, Expression, Identifier, Rangeable,
|
||||
RangeableType, StructType, Type,
|
||||
};
|
||||
|
||||
/// Analyzes the abstract syntax tree for errors.
|
||||
@ -255,6 +255,18 @@ impl<'recovered, 'a: 'recovered> Analyzer<'a> {
|
||||
list: list.clone(),
|
||||
});
|
||||
}
|
||||
} else if let Type::Range { r#type } = &index_type {
|
||||
if let RangeableType::Integer = r#type {
|
||||
// Ok
|
||||
} else {
|
||||
return Err(AnalysisError::ExpectedType {
|
||||
expected: Type::Range {
|
||||
r#type: RangeableType::Integer,
|
||||
},
|
||||
actual: index_type,
|
||||
actual_expression: index.clone(),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return Err(AnalysisError::ExpectedType {
|
||||
expected: Type::Integer,
|
||||
|
@ -16,24 +16,6 @@ pub fn core_library<'a>() -> &'a Context {
|
||||
(0, 0),
|
||||
),
|
||||
),
|
||||
(
|
||||
Identifier::new("is_even"),
|
||||
(
|
||||
ContextData::VariableValue(Value::Function(Function::BuiltIn(
|
||||
BuiltInFunction::IsEven,
|
||||
))),
|
||||
(0, 0),
|
||||
),
|
||||
),
|
||||
(
|
||||
Identifier::new("is_odd"),
|
||||
(
|
||||
ContextData::VariableValue(Value::Function(Function::BuiltIn(
|
||||
BuiltInFunction::IsOdd,
|
||||
))),
|
||||
(0, 0),
|
||||
),
|
||||
),
|
||||
(
|
||||
Identifier::new("read_line"),
|
||||
(
|
||||
|
@ -234,27 +234,36 @@ impl Value {
|
||||
}
|
||||
|
||||
pub fn get_field(&self, field: &Identifier) -> Option<Value> {
|
||||
let built_in_function = match field.as_str() {
|
||||
"to_string" => BuiltInFunction::ToString,
|
||||
"length" => {
|
||||
return match self {
|
||||
Value::List(values) => Some(Value::Integer(values.len() as i64)),
|
||||
Value::String(string) => Some(Value::Integer(string.len() as i64)),
|
||||
Value::Map(map) => Some(Value::Integer(map.len() as i64)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return match self {
|
||||
Value::Mutable(inner) => inner.read().unwrap().get_field(field),
|
||||
Value::Struct(Struct::Fields { fields, .. }) => fields.get(field).cloned(),
|
||||
Value::Map(pairs) => pairs.get(field).cloned(),
|
||||
_ => None,
|
||||
};
|
||||
}
|
||||
};
|
||||
if let Value::Mutable(locked) = self {
|
||||
return locked.read().unwrap().get_field(field);
|
||||
}
|
||||
|
||||
Some(Value::Function(Function::BuiltIn(built_in_function)))
|
||||
match field.as_str() {
|
||||
"is_even" => match self {
|
||||
Value::Integer(integer) => Some(Value::Boolean(integer % 2 == 0)),
|
||||
Value::Float(float) => Some(Value::Boolean(float % 2.0 == 0.0)),
|
||||
_ => None,
|
||||
},
|
||||
"is_odd" => match self {
|
||||
Value::Integer(integer) => Some(Value::Boolean(integer % 2 != 0)),
|
||||
Value::Float(float) => Some(Value::Boolean(float % 2.0 != 0.0)),
|
||||
_ => None,
|
||||
},
|
||||
"to_string" => Some(Value::Function(Function::BuiltIn(
|
||||
BuiltInFunction::ToString,
|
||||
))),
|
||||
"length" => match self {
|
||||
Value::List(values) => Some(Value::Integer(values.len() as i64)),
|
||||
Value::String(string) => Some(Value::Integer(string.len() as i64)),
|
||||
Value::Map(map) => Some(Value::Integer(map.len() as i64)),
|
||||
_ => None,
|
||||
},
|
||||
_ => match self {
|
||||
Value::Struct(Struct::Fields { fields, .. }) => fields.get(field).cloned(),
|
||||
Value::Map(pairs) => pairs.get(field).cloned(),
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_index(&self, index: Value) -> Result<Option<Value>, ValueError> {
|
||||
|
@ -737,7 +737,7 @@ impl Vm {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
return Err(RuntimeError::UndefinedProperty {
|
||||
return Err(RuntimeError::UndefinedField {
|
||||
value: container_value,
|
||||
value_position: container_position,
|
||||
property: field.inner,
|
||||
@ -1130,7 +1130,7 @@ pub enum RuntimeError {
|
||||
identifier: Identifier,
|
||||
position: Span,
|
||||
},
|
||||
UndefinedProperty {
|
||||
UndefinedField {
|
||||
value: Value,
|
||||
value_position: Span,
|
||||
property: Identifier,
|
||||
@ -1175,7 +1175,7 @@ impl RuntimeError {
|
||||
} => (start_position.0, end_position.1),
|
||||
|
||||
Self::UndefinedType { position, .. } => *position,
|
||||
Self::UndefinedProperty {
|
||||
Self::UndefinedField {
|
||||
property_position, ..
|
||||
} => *property_position,
|
||||
}
|
||||
@ -1326,7 +1326,7 @@ impl Display for RuntimeError {
|
||||
"Identifier \"{identifier}\" is not associated with a value or constructor"
|
||||
)
|
||||
}
|
||||
Self::UndefinedProperty {
|
||||
Self::UndefinedField {
|
||||
value, property, ..
|
||||
} => {
|
||||
write!(f, "Value {} does not have the property {}", value, property)
|
||||
@ -1672,14 +1672,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn is_even() {
|
||||
let input = "is_even(42)";
|
||||
let input = "42.is_even";
|
||||
|
||||
assert_eq!(run(input), Ok(Some(Value::Boolean(true))));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_odd() {
|
||||
let input = "is_odd(42)";
|
||||
let input = "42.is_odd";
|
||||
|
||||
assert_eq!(run(input), Ok(Some(Value::Boolean(false))));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user