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