Skip to content

Commit f6363bc

Browse files
committed
feat: Add enum variant access resolution for zig.zyn grammar
- Add enum_types HashMap to TypedAstBuilder to track enum types and their variants - Register enum variants in create_enum for later lookup - In create_field_access, check if object is an enum type name and resolve variant access to integer literal discriminants This enables Zig-style enum access syntax like: const Color = enum { Red, Green, Blue }; return Color.Green; // Returns 1
1 parent 651981b commit f6363bc

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

crates/zyn_peg/src/runtime.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,8 @@ pub struct TypedAstBuilder {
850850
struct_field_inits: HashMap<NodeHandle, (String, NodeHandle)>,
851851
/// Variable name to type mapping (for proper variable references)
852852
variable_types: HashMap<String, Type>,
853+
/// Enum type name to variant names (in order, for discriminant calculation)
854+
enum_types: HashMap<String, Vec<String>>,
853855
/// Program declaration handles (in order)
854856
program_decls: Vec<NodeHandle>,
855857
}
@@ -873,6 +875,7 @@ impl TypedAstBuilder {
873875
variants: HashMap::new(),
874876
struct_field_inits: HashMap::new(),
875877
variable_types: HashMap::new(),
878+
enum_types: HashMap::new(),
876879
program_decls: Vec::new(),
877880
}
878881
}
@@ -1151,6 +1154,19 @@ impl AstHostFunctions for TypedAstBuilder {
11511154
let object_expr = self.get_expr(object)
11521155
.unwrap_or_else(|| self.inner.variable("object", Type::Primitive(PrimitiveType::I32), span));
11531156

1157+
// Check if this is an enum variant access (EnumType.Variant)
1158+
if let TypedExpression::Variable(var_name) = &object_expr.node {
1159+
let type_name = var_name.resolve_global().unwrap_or_default();
1160+
if let Some(variants) = self.enum_types.get(&type_name) {
1161+
// This is an enum variant access - find the discriminant
1162+
if let Some(discriminant) = variants.iter().position(|v| v == field) {
1163+
// Return an integer literal representing the enum variant
1164+
let expr = self.inner.int_literal(discriminant as i128, span);
1165+
return self.store_expr(expr);
1166+
}
1167+
}
1168+
}
1169+
11541170
// Infer field type from object's struct type
11551171
let field_type = match &object_expr.ty {
11561172
Type::Struct { fields, .. } => {
@@ -1411,6 +1427,13 @@ impl AstHostFunctions for TypedAstBuilder {
14111427
.filter_map(|h| self.get_variant(*h))
14121428
.collect();
14131429

1430+
// Register enum type with variant names for later lookup
1431+
let variant_names: Vec<String> = variants
1432+
.iter()
1433+
.filter_map(|v| v.name.resolve_global())
1434+
.collect();
1435+
self.enum_types.insert(name.to_string(), variant_names);
1436+
14141437
let enum_decl = TypedEnum {
14151438
name: InternedString::new_global(name),
14161439
type_params: Vec::new(),

0 commit comments

Comments
 (0)