Skip to content

Commit 8a9f0f8

Browse files
committed
fix: Function calls with parameters now work correctly
The issue was twofold: 1. Grammar bug: fn_params rule was using "get_child": { "index": 0 } which only captured the first parameter. Changed to "get_all_children" to capture all parameters. 2. Type tracking: create_param and create_primitive_type weren't storing actual type information. Added: - `types: HashMap<NodeHandle, Type>` to store type handles - `params: HashMap<NodeHandle, (String, Type)>` to store parameter info - Updated create_primitive_type to parse and store actual types - Updated create_param to look up and store parameter types - Updated create_function to use stored parameter info All Zig features now compile and execute correctly: - Arithmetic ✓ - If/Else ✓ - While Loop ✓ - Function Calls ✓ (fixed) - Struct ✓ - Enum ✓ - Boolean Operators ✓
1 parent ad14f3b commit 8a9f0f8

2 files changed

Lines changed: 49 additions & 13 deletions

File tree

crates/zyn_peg/grammars/zig.zyn

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ fn_decl_no_params = { "fn" ~ identifier ~ "(" ~ ")" ~ type_expr ~ block }
122122

123123
fn_params = { fn_param ~ ("," ~ fn_param)* }
124124
-> List {
125-
"get_child": { "index": 0 }
125+
"get_all_children": true
126126
}
127127

128128
// Children (non-silent): identifier, type_expr

crates/zyn_peg/src/runtime.rs

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -848,6 +848,10 @@ pub struct TypedAstBuilder {
848848
variants: HashMap<NodeHandle, TypedVariant>,
849849
/// Stored struct field initializers (name, value) by handle
850850
struct_field_inits: HashMap<NodeHandle, (String, NodeHandle)>,
851+
/// Stored function parameters (name, type) by handle
852+
params: HashMap<NodeHandle, (String, Type)>,
853+
/// Stored types by handle (for type resolution)
854+
types: HashMap<NodeHandle, Type>,
851855
/// Variable name to type mapping (for proper variable references)
852856
variable_types: HashMap<String, Type>,
853857
/// Enum type name to variant names (in order, for discriminant calculation)
@@ -874,6 +878,8 @@ impl TypedAstBuilder {
874878
fields: HashMap::new(),
875879
variants: HashMap::new(),
876880
struct_field_inits: HashMap::new(),
881+
params: HashMap::new(),
882+
types: HashMap::new(),
877883
variable_types: HashMap::new(),
878884
enum_types: HashMap::new(),
879885
program_decls: Vec::new(),
@@ -940,6 +946,11 @@ impl TypedAstBuilder {
940946
self.variants.get(&handle).cloned()
941947
}
942948

949+
/// Get a type from a handle
950+
fn get_type_from_handle(&self, handle: NodeHandle) -> Option<Type> {
951+
self.types.get(&handle).cloned()
952+
}
953+
943954
/// Get the default span for nodes
944955
fn default_span(&self) -> Span {
945956
self.inner.dummy_span()
@@ -1026,11 +1037,15 @@ impl AstHostFunctions for TypedAstBuilder {
10261037
) -> NodeHandle {
10271038
let span = self.default_span();
10281039

1029-
// Convert param handles to TypedParameter
1040+
// Convert param handles to TypedParameter using stored parameter info
10301041
let typed_params: Vec<_> = params.iter()
1031-
.map(|_h| {
1032-
// For now, create simple parameters
1033-
self.inner.parameter("arg", Type::Primitive(PrimitiveType::I32), Mutability::Immutable, span)
1042+
.map(|h| {
1043+
if let Some((name, ty)) = self.params.get(h) {
1044+
self.inner.parameter(name, ty.clone(), Mutability::Immutable, span)
1045+
} else {
1046+
// Fallback for unknown params
1047+
self.inner.parameter("arg", Type::Primitive(PrimitiveType::I32), Mutability::Immutable, span)
1048+
}
10341049
})
10351050
.collect();
10361051

@@ -1058,11 +1073,13 @@ impl AstHostFunctions for TypedAstBuilder {
10581073
self.store_decl(func)
10591074
}
10601075

1061-
fn create_param(&mut self, name: &str, _ty: NodeHandle) -> NodeHandle {
1062-
// Parameters are stored differently - just return a placeholder handle
1063-
// The actual TypedParameter is created in create_function
1064-
let _ = name;
1065-
self.alloc_handle()
1076+
fn create_param(&mut self, name: &str, ty: NodeHandle) -> NodeHandle {
1077+
// Store parameter name and type for later use in create_function
1078+
let handle = self.alloc_handle();
1079+
// Get the type from the type handle, default to i32 if not found
1080+
let param_type = self.get_type_from_handle(ty).unwrap_or(Type::Primitive(PrimitiveType::I32));
1081+
self.params.insert(handle, (name.to_string(), param_type));
1082+
handle
10661083
}
10671084

10681085
fn create_binary_op(&mut self, op: &str, left: NodeHandle, right: NodeHandle) -> NodeHandle {
@@ -1361,9 +1378,28 @@ impl AstHostFunctions for TypedAstBuilder {
13611378
self.store_stmt(stmt)
13621379
}
13631380

1364-
fn create_primitive_type(&mut self, _name: &str) -> NodeHandle {
1365-
// Types are handled inline - just return placeholder
1366-
self.alloc_handle()
1381+
fn create_primitive_type(&mut self, name: &str) -> NodeHandle {
1382+
// Parse the type name and store the actual type
1383+
let handle = self.alloc_handle();
1384+
let ty = match name {
1385+
"i8" => Type::Primitive(PrimitiveType::I8),
1386+
"i16" => Type::Primitive(PrimitiveType::I16),
1387+
"i32" => Type::Primitive(PrimitiveType::I32),
1388+
"i64" => Type::Primitive(PrimitiveType::I64),
1389+
"i128" => Type::Primitive(PrimitiveType::I128),
1390+
"u8" => Type::Primitive(PrimitiveType::U8),
1391+
"u16" => Type::Primitive(PrimitiveType::U16),
1392+
"u32" => Type::Primitive(PrimitiveType::U32),
1393+
"u64" => Type::Primitive(PrimitiveType::U64),
1394+
"u128" => Type::Primitive(PrimitiveType::U128),
1395+
"f32" => Type::Primitive(PrimitiveType::F32),
1396+
"f64" => Type::Primitive(PrimitiveType::F64),
1397+
"bool" => Type::Primitive(PrimitiveType::Bool),
1398+
"void" | "unit" => Type::Primitive(PrimitiveType::Unit),
1399+
_ => Type::Primitive(PrimitiveType::I32), // Default to i32
1400+
};
1401+
self.types.insert(handle, ty);
1402+
handle
13671403
}
13681404

13691405
fn create_pointer_type(&mut self, _pointee: NodeHandle) -> NodeHandle {

0 commit comments

Comments
 (0)