Refactor: Rename map to record
This commit renames `Map` to `Record` and updates all related AST nodes, binders, type checkers, and runtime values to reflect this change. This is a semantic change to better align with common programming language terminology.
This commit is contained in:
+56
-60
@@ -55,12 +55,12 @@ pub trait Object: fmt::Debug {
|
||||
fn as_any(&self) -> &dyn Any;
|
||||
}
|
||||
|
||||
/// Internal storage for Tuples (and Records) to allow sharing schema (keys) between instances.
|
||||
/// Internal storage for Records to allow sharing schema (keys) between instances.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TupleData {
|
||||
pub struct RecordData {
|
||||
/// Names for slots.
|
||||
pub keys: Rc<Vec<Keyword>>,
|
||||
pub values: Vec<Value>,
|
||||
/// Optional names for slots. If present, this is semantically a Record.
|
||||
pub keys: Option<Rc<Vec<Keyword>>>,
|
||||
}
|
||||
|
||||
/// Core data value in Myc Script (similar to TDataValue)
|
||||
@@ -73,7 +73,8 @@ pub enum Value {
|
||||
DateTime(i64),
|
||||
Text(Rc<str>),
|
||||
Keyword(Keyword),
|
||||
Tuple(Rc<TupleData>), // Replaces List and Record
|
||||
Tuple(Rc<Vec<Value>>),
|
||||
Record(Rc<RecordData>),
|
||||
Function(Rc<dyn Fn(Vec<Value>) -> Value>),
|
||||
Object(Rc<dyn Object>), // For compiled Closures and other opaque types
|
||||
Cell(Rc<RefCell<Value>>), // Boxed value for captures
|
||||
@@ -224,12 +225,12 @@ impl Value {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_list(values: Vec<Value>) -> Self {
|
||||
Value::Tuple(Rc::new(TupleData { values, keys: None }))
|
||||
pub fn make_tuple(values: Vec<Value>) -> Self {
|
||||
Value::Tuple(Rc::new(values))
|
||||
}
|
||||
|
||||
pub fn make_record(keys: Vec<Keyword>, values: Vec<Value>) -> Self {
|
||||
Value::Tuple(Rc::new(TupleData { values, keys: Some(Rc::new(keys)) }))
|
||||
Value::Record(Rc::new(RecordData { keys: Rc::new(keys), values }))
|
||||
}
|
||||
|
||||
pub fn static_type(&self) -> StaticType {
|
||||
@@ -241,44 +242,40 @@ impl Value {
|
||||
Value::DateTime(_) => StaticType::DateTime,
|
||||
Value::Text(_) => StaticType::Text,
|
||||
Value::Keyword(_) => StaticType::Keyword,
|
||||
Value::Tuple(t) => {
|
||||
if let Some(keys) = &t.keys {
|
||||
// It's a Record
|
||||
let mut fields = Vec::with_capacity(t.values.len());
|
||||
for (i, v) in t.values.iter().enumerate() {
|
||||
fields.push((keys[i], v.static_type()));
|
||||
}
|
||||
StaticType::Record(Rc::new(fields))
|
||||
} else {
|
||||
// It's a List/Tuple
|
||||
let l = &t.values;
|
||||
if l.is_empty() {
|
||||
return StaticType::Vector(Box::new(StaticType::Any), 0);
|
||||
}
|
||||
|
||||
let element_types: Vec<_> = l.iter().map(|v| v.static_type()).collect();
|
||||
|
||||
// Check for Homogeneity (Vector)
|
||||
let first_ty = &element_types[0];
|
||||
let all_same = element_types.iter().all(|t| t == first_ty);
|
||||
|
||||
if all_same {
|
||||
match first_ty {
|
||||
StaticType::Vector(inner, len) => {
|
||||
// Possible Matrix
|
||||
StaticType::Matrix(inner.clone(), vec![l.len(), *len])
|
||||
},
|
||||
StaticType::Matrix(inner, shape) => {
|
||||
let mut new_shape = vec![l.len()];
|
||||
new_shape.extend(shape);
|
||||
StaticType::Matrix(inner.clone(), new_shape)
|
||||
},
|
||||
_ => StaticType::Vector(Box::new(first_ty.clone()), l.len())
|
||||
}
|
||||
} else {
|
||||
StaticType::Tuple(element_types)
|
||||
}
|
||||
Value::Tuple(values) => {
|
||||
if values.is_empty() {
|
||||
return StaticType::Vector(Box::new(StaticType::Any), 0);
|
||||
}
|
||||
|
||||
let element_types: Vec<_> = values.iter().map(|v| v.static_type()).collect();
|
||||
|
||||
// Check for Homogeneity (Vector)
|
||||
let first_ty = &element_types[0];
|
||||
let all_same = element_types.iter().all(|t| t == first_ty);
|
||||
|
||||
if all_same {
|
||||
match first_ty {
|
||||
StaticType::Vector(inner, len) => {
|
||||
// Possible Matrix
|
||||
StaticType::Matrix(inner.clone(), vec![values.len(), *len])
|
||||
},
|
||||
StaticType::Matrix(inner, shape) => {
|
||||
let mut new_shape = vec![values.len()];
|
||||
new_shape.extend(shape);
|
||||
StaticType::Matrix(inner.clone(), new_shape)
|
||||
},
|
||||
_ => StaticType::Vector(Box::new(first_ty.clone()), values.len())
|
||||
}
|
||||
} else {
|
||||
StaticType::Tuple(element_types)
|
||||
}
|
||||
},
|
||||
Value::Record(r) => {
|
||||
let mut fields = Vec::with_capacity(r.values.len());
|
||||
for (i, v) in r.values.iter().enumerate() {
|
||||
fields.push((r.keys[i], v.static_type()));
|
||||
}
|
||||
StaticType::Record(Rc::new(fields))
|
||||
},
|
||||
Value::Function(_) => StaticType::Any, // Dynamic function
|
||||
Value::Object(o) => StaticType::Object(o.type_name()),
|
||||
@@ -303,22 +300,21 @@ impl fmt::Display for Value {
|
||||
},
|
||||
Value::Text(t) => write!(f, "\"{}\"", t),
|
||||
Value::Keyword(k) => write!(f, ":{}", k.name()),
|
||||
Value::Tuple(t) => {
|
||||
if let Some(keys) = &t.keys {
|
||||
write!(f, "{{")?;
|
||||
for i in 0..t.values.len() {
|
||||
if i > 0 { write!(f, ", ")?; }
|
||||
write!(f, ":{} {}", keys[i].name(), t.values[i])?;
|
||||
}
|
||||
write!(f, "}}")
|
||||
} else {
|
||||
write!(f, "[")?;
|
||||
for (i, val) in t.values.iter().enumerate() {
|
||||
if i > 0 { write!(f, " ")?; }
|
||||
write!(f, "{}", val)?;
|
||||
}
|
||||
write!(f, "]")
|
||||
Value::Tuple(values) => {
|
||||
write!(f, "[")?;
|
||||
for (i, val) in values.iter().enumerate() {
|
||||
if i > 0 { write!(f, " ")?; }
|
||||
write!(f, "{}", val)?;
|
||||
}
|
||||
write!(f, "]")
|
||||
},
|
||||
Value::Record(r) => {
|
||||
write!(f, "{{")?;
|
||||
for i in 0..r.values.len() {
|
||||
if i > 0 { write!(f, ", ")?; }
|
||||
write!(f, ":{} {}", r.keys[i].name(), r.values[i])?;
|
||||
}
|
||||
write!(f, "}}")
|
||||
},
|
||||
Value::Function(_) => write!(f, "<native fn>"),
|
||||
Value::Object(o) => write!(f, "<{}>", o.type_name()),
|
||||
|
||||
Reference in New Issue
Block a user