Merge worktree-agent: add struct literals, generics, print/log builtins

This commit is contained in:
Will Anderson
2026-04-28 11:51:02 -05:00
40 changed files with 4058 additions and 72 deletions
+7 -1
View File
@@ -16,13 +16,15 @@ pub enum Value {
Nil,
/// A list of values (used for `activate` results and array literals).
List(Vec<Value>),
/// A key-value map — used for struct instances and Map<K,V> literals.
/// A key-value map — used for Map<K,V> literals.
/// Stored as a Vec of pairs to keep ordering and remain Serialize-friendly.
Map(Vec<(String, Value)>),
/// A Result<T,E> value — Ok variant.
ResultOk(Box<Value>),
/// A Result<T,E> value — Err variant.
ResultErr(Box<Value>),
/// A struct instance: type name + ordered field name-value pairs.
Struct { type_name: String, fields: Vec<(String, Value)> },
}
impl std::fmt::Display for Value {
@@ -43,6 +45,10 @@ impl std::fmt::Display for Value {
}
Value::ResultOk(v) => write!(f, "Ok({v})"),
Value::ResultErr(e) => write!(f, "Err({e})"),
Value::Struct { type_name, fields } => {
let fs: Vec<_> = fields.iter().map(|(k, v)| format!("{k}: {v}")).collect();
write!(f, "{type_name} {{ {} }}", fs.join(", "))
}
}
}
}
+11
View File
@@ -357,6 +357,17 @@ impl Codegen {
self.gen_expr(index)?;
self.emit(Bytecode::GetIndex);
}
Expr::StructLit { type_name, fields, .. } => {
// Push each field value in declaration order
for (_, field_expr) in fields {
self.gen_expr(field_expr)?;
}
let field_names: Vec<String> = fields.iter().map(|(n, _)| n.clone()).collect();
self.emit(Bytecode::BuildStruct {
type_name: type_name.clone(),
fields: field_names,
});
}
// New expression kinds — push Nil as placeholder
_ => {
self.emit(Bytecode::Push(Value::Nil));