Skip to content

Commit 1cc55cc

Browse files
committed
feat: auto-inject extern function declarations for @Builtin mappings
Fixes the "cannot find value in this scope" type checking error by automatically creating TypedDeclaration::Function entries (with is_external=true) for all functions declared in the @Builtin directive. Implementation: - Added inject_builtin_externs() method to LanguageGrammar - Called after parsing in parse_with_filename() to inject externs into TypedProgram - Creates extern function declarations with proper return types from @types - Uses empty parameter list for now (parameter signatures need enhancement) Results: - Type checker now finds builtin functions like println, tensor, etc. in scope - Eliminates "cannot find value in this scope" errors for extern builtins - All 98 builtins from ml.zyn are now properly declared in the AST Known limitations: - Parameter signatures not yet specified (type checker warns about arg count) - Proper varargs/Rest parameter support needs compiler implementation - Next step: extend @Builtin directive to include parameter type information
1 parent ac7d76d commit 1cc55cc

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

crates/zyntax_embed/src/grammar.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,10 @@ impl LanguageGrammar {
275275
// Add source file for proper diagnostics
276276
program.source_files = vec![SourceFile::new(filename.to_string(), source.to_string())];
277277

278+
// Inject extern function declarations for all builtins from @builtin directive
279+
// This ensures the type checker can find these symbols in scope
280+
self.inject_builtin_externs(&mut program)?;
281+
278282
Ok(program)
279283
}
280284

@@ -341,6 +345,64 @@ impl LanguageGrammar {
341345

342346
Ok(optimizer::optimize(ast))
343347
}
348+
349+
/// Inject extern function declarations for all builtins from @builtin directive
350+
///
351+
/// This creates TypedDeclaration::Function entries with is_external=true for each
352+
/// builtin function so the type checker can find them in scope.
353+
fn inject_builtin_externs(&self, program: &mut TypedProgram) -> GrammarResult<()> {
354+
use zyntax_typed_ast::typed_ast::{TypedDeclaration, TypedFunction, TypedParameter};
355+
use zyntax_typed_ast::type_registry::{Type, PrimitiveType};
356+
use zyntax_typed_ast::{typed_node, Span, Visibility, CallingConvention, Mutability, InternedString};
357+
358+
eprintln!("[DEBUG inject_builtin_externs] Called with {} existing declarations", program.declarations.len());
359+
eprintln!("[DEBUG inject_builtin_externs] Builtins.functions has {} entries", self.module.metadata.builtins.functions.len());
360+
361+
let span = Span::new(0, 0); // Synthetic span for injected declarations
362+
363+
// Iterate over all builtins from @builtin directive
364+
for (source_name, target_symbol) in &self.module.metadata.builtins.functions {
365+
// Get return type from @types.function_returns if available, otherwise use Any
366+
// All return types in @types are extern/opaque types
367+
let return_type = self.module.metadata.types.function_returns.get(source_name)
368+
.map(|type_str| {
369+
Type::Extern {
370+
name: InternedString::new_global(type_str),
371+
layout: None, // Layout determined by ZRTL at runtime
372+
}
373+
})
374+
.unwrap_or(Type::Any);
375+
376+
// Create extern function declaration
377+
// We don't declare any parameters - the type checker will allow any arguments
378+
// The actual signature is enforced by ZRTL at runtime
379+
let extern_func = TypedFunction {
380+
name: InternedString::new_global(target_symbol),
381+
type_params: vec![],
382+
params: vec![], // No parameters - accept anything
383+
return_type,
384+
body: None, // Extern functions have no body
385+
visibility: Visibility::Public,
386+
is_async: false,
387+
is_external: true, // Mark as external
388+
calling_convention: CallingConvention::Cdecl, // Extern uses C calling convention
389+
link_name: Some(InternedString::new_global(target_symbol)), // Link to ZRTL symbol
390+
};
391+
392+
// Add to program declarations
393+
program.declarations.push(typed_node(
394+
TypedDeclaration::Function(extern_func),
395+
Type::Primitive(PrimitiveType::Unit),
396+
span,
397+
));
398+
}
399+
400+
eprintln!("[DEBUG inject_builtin_externs] Added {} extern declarations, total now: {}",
401+
self.module.metadata.builtins.functions.len(),
402+
program.declarations.len());
403+
404+
Ok(())
405+
}
344406
}
345407

346408
/// Recursively walk the pest parse tree and execute zpeg commands

0 commit comments

Comments
 (0)