-
Notifications
You must be signed in to change notification settings - Fork 204
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- move value into its own module - remove _ from match clause
- Loading branch information
1 parent
846a24a
commit cd78b1b
Showing
3 changed files
with
117 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,4 @@ pub mod mem; | |
pub mod node; | ||
pub mod optimizations; | ||
pub mod ssa_form; | ||
mod value; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
use crate::ssa::node::NodeId; | ||
use iter_extended::vecmap; | ||
use noirc_frontend::monomorphization::ast::Type; | ||
|
||
/// A `Value` is the descriptor used for items in the SSA IR. | ||
/// A `Value` can hold a `NodeId` which by proxy means that | ||
/// it represents Variables, Constants, Functions and Instructions. | ||
#[derive(Debug, Clone)] | ||
pub enum Value { | ||
Single(NodeId), | ||
Tuple(Vec<Value>), | ||
} | ||
|
||
impl Value { | ||
/// Returns a single NodeId. | ||
/// Panics: If `Value` holds multiple Values | ||
pub fn unwrap_id(&self) -> NodeId { | ||
match self { | ||
Value::Single(id) => *id, | ||
Value::Tuple(_) => panic!("Tried to unwrap a struct into a single value"), | ||
} | ||
} | ||
|
||
/// Returns a placeholder NodeId that can | ||
/// be used to represent the absence of a value. | ||
pub fn dummy() -> Value { | ||
Value::Single(NodeId::dummy()) | ||
} | ||
|
||
/// Checks if the `Value` corresponds to | ||
/// `Option::None` or no value. | ||
pub fn is_dummy(&self) -> bool { | ||
match self { | ||
Value::Single(id) => *id == NodeId::dummy(), | ||
_ => false, | ||
} | ||
} | ||
|
||
/// Converts `Value` into a vector of NodeId's | ||
pub fn to_node_ids(&self) -> Vec<NodeId> { | ||
match self { | ||
Value::Single(id) => vec![*id], | ||
Value::Tuple(v) => v.iter().flat_map(|i| i.to_node_ids()).collect(), | ||
} | ||
} | ||
|
||
/// Calls the function `f` on `self` and the given `Value` | ||
/// Panics: If `self` and the given value are not the same | ||
/// enum variant | ||
pub fn zip<F>(&self, rhs_value: &Value, f: &mut F) -> Value | ||
where | ||
F: FnMut(NodeId, NodeId) -> NodeId, | ||
{ | ||
if self.is_dummy() || rhs_value.is_dummy() { | ||
return Value::dummy(); | ||
} | ||
|
||
match (self, rhs_value) { | ||
(Value::Single(lhs), Value::Single(rhs)) => Value::Single(f(*lhs, *rhs)), | ||
(Value::Tuple(lhs), Value::Tuple(rhs)) => { | ||
Value::Tuple(vecmap(lhs.iter().zip(rhs), |(lhs_value, rhs_value)| { | ||
lhs_value.zip(rhs_value, f) | ||
})) | ||
} | ||
_ => { | ||
unreachable!("ICE: expected both `Value` instances to be of the same enum variant") | ||
} | ||
} | ||
} | ||
|
||
/// Returns the `Value` at position `field_index` in the | ||
/// Tuple Variant. | ||
/// Panics: If the `self` is not the `Tuple` Variant. | ||
pub fn into_field_member(self, field_index: usize) -> Value { | ||
match self { | ||
Value::Single(_) => { | ||
unreachable!("Runtime type error, expected struct but found a single value") | ||
} | ||
Value::Tuple(mut fields) => fields.remove(field_index), | ||
} | ||
} | ||
pub fn get_field_member(&self, field_index: usize) -> &Value { | ||
match self { | ||
Value::Single(_) => { | ||
unreachable!("Runtime type error, expected struct but found a single value") | ||
} | ||
Value::Tuple(fields) => &fields[field_index], | ||
} | ||
} | ||
|
||
/// Reconstruct a `Value` instance whose type is `value_type` | ||
fn reshape(value_type: &Type, iter: &mut core::slice::Iter<NodeId>) -> Value { | ||
match value_type { | ||
Type::Tuple(tup) => { | ||
let values = vecmap(tup, |v| Self::reshape(v, iter)); | ||
Value::Tuple(values) | ||
} | ||
Type::Unit | ||
| Type::Function(..) | ||
| Type::Array(..) | ||
| Type::String(..) | ||
| Type::Integer(..) | ||
| Type::Bool | ||
| Type::Field => Value::Single(*iter.next().unwrap()), | ||
} | ||
} | ||
|
||
/// Reconstruct a `Value` instance from a slice of NodeId's | ||
pub(crate) fn from_slice(value_type: &Type, slice: &[NodeId]) -> Value { | ||
let mut iter = slice.iter(); | ||
let result = Value::reshape(value_type, &mut iter); | ||
assert!(iter.next().is_none()); | ||
result | ||
} | ||
} |