deal with unknown types at the syntax phase
This commit is contained in:
@@ -106,6 +106,7 @@ impl<IR: Clone> Value<IR> {
|
|||||||
match left {
|
match left {
|
||||||
Value::I8(x) => match right {
|
Value::I8(x) => match right {
|
||||||
Value::I8(y) => run_op!(operation, x, *y),
|
Value::I8(y) => run_op!(operation, x, *y),
|
||||||
|
Value::Number(y) => run_op!(operation, x, *y as i8),
|
||||||
_ => Err(PrimOpError::TypeMismatch(
|
_ => Err(PrimOpError::TypeMismatch(
|
||||||
operation.to_string(),
|
operation.to_string(),
|
||||||
left.clone(),
|
left.clone(),
|
||||||
@@ -114,6 +115,7 @@ impl<IR: Clone> Value<IR> {
|
|||||||
},
|
},
|
||||||
Value::I16(x) => match right {
|
Value::I16(x) => match right {
|
||||||
Value::I16(y) => run_op!(operation, x, *y),
|
Value::I16(y) => run_op!(operation, x, *y),
|
||||||
|
Value::Number(y) => run_op!(operation, x, *y as i16),
|
||||||
_ => Err(PrimOpError::TypeMismatch(
|
_ => Err(PrimOpError::TypeMismatch(
|
||||||
operation.to_string(),
|
operation.to_string(),
|
||||||
left.clone(),
|
left.clone(),
|
||||||
@@ -122,6 +124,7 @@ impl<IR: Clone> Value<IR> {
|
|||||||
},
|
},
|
||||||
Value::I32(x) => match right {
|
Value::I32(x) => match right {
|
||||||
Value::I32(y) => run_op!(operation, x, *y),
|
Value::I32(y) => run_op!(operation, x, *y),
|
||||||
|
Value::Number(y) => run_op!(operation, x, *y as i32),
|
||||||
_ => Err(PrimOpError::TypeMismatch(
|
_ => Err(PrimOpError::TypeMismatch(
|
||||||
operation.to_string(),
|
operation.to_string(),
|
||||||
left.clone(),
|
left.clone(),
|
||||||
@@ -130,6 +133,7 @@ impl<IR: Clone> Value<IR> {
|
|||||||
},
|
},
|
||||||
Value::I64(x) => match right {
|
Value::I64(x) => match right {
|
||||||
Value::I64(y) => run_op!(operation, x, *y),
|
Value::I64(y) => run_op!(operation, x, *y),
|
||||||
|
Value::Number(y) => run_op!(operation, x, *y as i64),
|
||||||
_ => Err(PrimOpError::TypeMismatch(
|
_ => Err(PrimOpError::TypeMismatch(
|
||||||
operation.to_string(),
|
operation.to_string(),
|
||||||
left.clone(),
|
left.clone(),
|
||||||
@@ -138,6 +142,7 @@ impl<IR: Clone> Value<IR> {
|
|||||||
},
|
},
|
||||||
Value::U8(x) => match right {
|
Value::U8(x) => match right {
|
||||||
Value::U8(y) => run_op!(operation, x, *y),
|
Value::U8(y) => run_op!(operation, x, *y),
|
||||||
|
Value::Number(y) => run_op!(operation, x, *y as u8),
|
||||||
_ => Err(PrimOpError::TypeMismatch(
|
_ => Err(PrimOpError::TypeMismatch(
|
||||||
operation.to_string(),
|
operation.to_string(),
|
||||||
left.clone(),
|
left.clone(),
|
||||||
@@ -146,6 +151,7 @@ impl<IR: Clone> Value<IR> {
|
|||||||
},
|
},
|
||||||
Value::U16(x) => match right {
|
Value::U16(x) => match right {
|
||||||
Value::U16(y) => run_op!(operation, x, *y),
|
Value::U16(y) => run_op!(operation, x, *y),
|
||||||
|
Value::Number(y) => run_op!(operation, x, *y as u16),
|
||||||
_ => Err(PrimOpError::TypeMismatch(
|
_ => Err(PrimOpError::TypeMismatch(
|
||||||
operation.to_string(),
|
operation.to_string(),
|
||||||
left.clone(),
|
left.clone(),
|
||||||
@@ -154,6 +160,7 @@ impl<IR: Clone> Value<IR> {
|
|||||||
},
|
},
|
||||||
Value::U32(x) => match right {
|
Value::U32(x) => match right {
|
||||||
Value::U32(y) => run_op!(operation, x, *y),
|
Value::U32(y) => run_op!(operation, x, *y),
|
||||||
|
Value::Number(y) => run_op!(operation, x, *y as u32),
|
||||||
_ => Err(PrimOpError::TypeMismatch(
|
_ => Err(PrimOpError::TypeMismatch(
|
||||||
operation.to_string(),
|
operation.to_string(),
|
||||||
left.clone(),
|
left.clone(),
|
||||||
@@ -162,12 +169,29 @@ impl<IR: Clone> Value<IR> {
|
|||||||
},
|
},
|
||||||
Value::U64(x) => match right {
|
Value::U64(x) => match right {
|
||||||
Value::U64(y) => run_op!(operation, x, *y),
|
Value::U64(y) => run_op!(operation, x, *y),
|
||||||
|
Value::Number(y) => run_op!(operation, x, *y),
|
||||||
_ => Err(PrimOpError::TypeMismatch(
|
_ => Err(PrimOpError::TypeMismatch(
|
||||||
operation.to_string(),
|
operation.to_string(),
|
||||||
left.clone(),
|
left.clone(),
|
||||||
right.clone(),
|
right.clone(),
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
|
Value::Number(x) => match right {
|
||||||
|
Value::Number(y) => run_op!(operation, x, *y),
|
||||||
|
Value::U8(y) => run_op!(operation, (*x as u8), *y),
|
||||||
|
Value::U16(y) => run_op!(operation, (*x as u16), *y),
|
||||||
|
Value::U32(y) => run_op!(operation, (*x as u32), *y),
|
||||||
|
Value::U64(y) => run_op!(operation, x, *y),
|
||||||
|
Value::I8(y) => run_op!(operation, (*x as i8), *y),
|
||||||
|
Value::I16(y) => run_op!(operation, (*x as i16), *y),
|
||||||
|
Value::I32(y) => run_op!(operation, (*x as i32), *y),
|
||||||
|
Value::I64(y) => run_op!(operation, (*x as i64), *y),
|
||||||
|
_ => Err(PrimOpError::TypeMismatch(
|
||||||
|
operation.to_string(),
|
||||||
|
left.clone(),
|
||||||
|
right.clone(),
|
||||||
|
)),
|
||||||
|
}
|
||||||
Value::Closure(_, _, _, _) | Value::Void => {
|
Value::Closure(_, _, _, _) | Value::Void => {
|
||||||
Err(PrimOpError::BadTypeFor(operation.to_string(), left.clone()))
|
Err(PrimOpError::BadTypeFor(operation.to_string(), left.clone()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ impl<'a, IR> TryFrom<&'a Value<IR>> for PrimitiveType {
|
|||||||
Value::U16(_) => Ok(PrimitiveType::U16),
|
Value::U16(_) => Ok(PrimitiveType::U16),
|
||||||
Value::U32(_) => Ok(PrimitiveType::U32),
|
Value::U32(_) => Ok(PrimitiveType::U32),
|
||||||
Value::U64(_) => Ok(PrimitiveType::U64),
|
Value::U64(_) => Ok(PrimitiveType::U64),
|
||||||
|
// not sure this is the right call
|
||||||
|
Value::Number(_) => Ok(PrimitiveType::U64),
|
||||||
Value::Closure(name, _, _, _) => Err(ValuePrimitiveTypeError::CannotConvertFunction(
|
Value::Closure(name, _, _, _) => Err(ValuePrimitiveTypeError::CannotConvertFunction(
|
||||||
name.as_ref().map(|x| (**x).clone()),
|
name.as_ref().map(|x| (**x).clone()),
|
||||||
)),
|
)),
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ pub enum Value<IR> {
|
|||||||
U16(u16),
|
U16(u16),
|
||||||
U32(u32),
|
U32(u32),
|
||||||
U64(u64),
|
U64(u64),
|
||||||
|
// a number of unknown type
|
||||||
|
Number(u64),
|
||||||
Closure(
|
Closure(
|
||||||
Option<ArcIntern<String>>,
|
Option<ArcIntern<String>>,
|
||||||
ScopedMap<ArcIntern<String>, Value<IR>>,
|
ScopedMap<ArcIntern<String>, Value<IR>>,
|
||||||
@@ -43,6 +45,7 @@ impl<IR: Clone> Value<IR> {
|
|||||||
Value::I16(x) => Value::I16(*x),
|
Value::I16(x) => Value::I16(*x),
|
||||||
Value::I32(x) => Value::I32(*x),
|
Value::I32(x) => Value::I32(*x),
|
||||||
Value::I64(x) => Value::I64(*x),
|
Value::I64(x) => Value::I64(*x),
|
||||||
|
Value::Number(x) => Value::Number(*x),
|
||||||
Value::Closure(name, env, args, _) => {
|
Value::Closure(name, env, args, _) => {
|
||||||
let new_env = env.clone().map_values(|x| x.strip());
|
let new_env = env.clone().map_values(|x| x.strip());
|
||||||
Value::Closure(name.clone(), new_env, args.clone(), ())
|
Value::Closure(name.clone(), new_env, args.clone(), ())
|
||||||
@@ -62,6 +65,7 @@ fn format_value<IR>(value: &Value<IR>, f: &mut fmt::Formatter<'_>) -> fmt::Resul
|
|||||||
Value::U16(x) => write!(f, "{}u16", x),
|
Value::U16(x) => write!(f, "{}u16", x),
|
||||||
Value::U32(x) => write!(f, "{}u32", x),
|
Value::U32(x) => write!(f, "{}u32", x),
|
||||||
Value::U64(x) => write!(f, "{}u64", x),
|
Value::U64(x) => write!(f, "{}u64", x),
|
||||||
|
Value::Number(x) => write!(f, "{}", x),
|
||||||
Value::Closure(Some(name), _, _, _) => write!(f, "<function {}>", name),
|
Value::Closure(Some(name), _, _, _) => write!(f, "<function {}>", name),
|
||||||
Value::Closure(None, _, _, _) => write!(f, "<function>"),
|
Value::Closure(None, _, _, _) => write!(f, "<function>"),
|
||||||
}
|
}
|
||||||
@@ -115,6 +119,18 @@ impl<IR1, IR2> PartialEq<Value<IR2>> for Value<IR1> {
|
|||||||
Value::U64(y) => x == y,
|
Value::U64(y) => x == y,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
|
Value::Number(x) => match other {
|
||||||
|
Value::I8(y) => (*x as i8) == *y,
|
||||||
|
Value::I16(y) => (*x as i16) == *y,
|
||||||
|
Value::I32(y) => (*x as i32) == *y,
|
||||||
|
Value::I64(y) => (*x as i64) == *y,
|
||||||
|
Value::U8(y) => (*x as u8) == *y,
|
||||||
|
Value::U16(y) => (*x as u16) == *y,
|
||||||
|
Value::U32(y) => (*x as u32) == *y,
|
||||||
|
Value::U64(y) => x == y,
|
||||||
|
Value::Number(y) => x == y,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
Value::Closure(_, _, _, _) => false,
|
Value::Closure(_, _, _, _) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ impl Program {
|
|||||||
let value = env
|
let value = env
|
||||||
.get(&name.clone().intern())
|
.get(&name.clone().intern())
|
||||||
.ok_or_else(|| EvalError::LookupFailed(loc.clone(), name.name.clone()))?;
|
.ok_or_else(|| EvalError::LookupFailed(loc.clone(), name.name.clone()))?;
|
||||||
|
let value = if let Value::Number(x) = value {
|
||||||
|
Value::U64(*x)
|
||||||
|
} else {
|
||||||
|
value.clone()
|
||||||
|
};
|
||||||
let line = format!("{} = {}\n", name, value);
|
let line = format!("{} = {}\n", name, value);
|
||||||
stdout.push_str(&line);
|
stdout.push_str(&line);
|
||||||
last_result = Value::Void;
|
last_result = Value::Void;
|
||||||
@@ -64,7 +69,7 @@ impl Expression {
|
|||||||
match self {
|
match self {
|
||||||
Expression::Value(_, v) => match v {
|
Expression::Value(_, v) => match v {
|
||||||
super::Value::Number(_, ty, v) => match ty {
|
super::Value::Number(_, ty, v) => match ty {
|
||||||
None => Ok(Value::U64(*v)),
|
None => Ok(Value::Number(*v)),
|
||||||
// FIXME: make these types validate their input size
|
// FIXME: make these types validate their input size
|
||||||
Some(ConstantType::Void) => Ok(Value::Void),
|
Some(ConstantType::Void) => Ok(Value::Void),
|
||||||
Some(ConstantType::I8) => Ok(Value::I8(*v as i8)),
|
Some(ConstantType::I8) => Ok(Value::I8(*v as i8)),
|
||||||
|
|||||||
Reference in New Issue
Block a user