Conversation
There was a problem hiding this comment.
Pull request overview
This pull request introduces comprehensive support for complex numbers in the Ferret language, along with significant enhancements to the I/O subsystem and compiler infrastructure improvements. The changes affect multiple layers of the compiler stack, from parsing and type-checking to code generation and runtime support.
Changes:
- Added full complex number support with four precision levels (complex64, complex, complex256, complex512), including parsing of imaginary literals, type checking, arithmetic operations, and real/imag intrinsic functions for component extraction
- Refactored I/O standard library to use native stream functions (write, read, flush) with builtin stream constants (stdin, stdout, stderr), replacing extern function-based implementations with a more robust StreamWriter pattern
- Unified compiler builtin handle type registration in prelude.go and added validation to prevent user code from declaring reserved compiler builtin type names
Reviewed changes
Copilot reviewed 35 out of 36 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| runtime/wasm/runtime.ts | Added WASM runtime support for complex formatting, stream I/O, and parsing functions |
| runtime/libs/io.c | Implemented C runtime for complex printing, string building, stream operations, and parsing |
| runtime/libs/global.c | Added stream I/O functions (write, read, flush) and complex component extraction (real, imag) |
| runtime/core/math.c | Implemented complex arithmetic operations (add, sub, mul, div) for all complex types |
| runtime/core/alloc.c | Added stdio.h include for stream operations |
| main.go | Enhanced error messages with colored output using the colors package |
| libs/std/io.fer | Refactored I/O library with StreamWriter struct and native stream-based functions |
| libs/global.fer | Replaced file handle intrinsics with complex number intrinsics (real, imag) |
| internal/utils/numeric/numeric.go | Added imaginary number literal pattern to number tokenization |
| internal/types/types.go | Added ComplexType and related global type constants |
| internal/types/helpers.go | Added complex type helper functions for operations and conversions |
| internal/types/builtins.go | Added complex type name constants |
| internal/semantics/typechecker/typenode_test.go | Added tests for compiler resource type validation |
| internal/semantics/typechecker/typechecker.go | Added type checking for complex arithmetic, unary operations, and real/imag calls |
| internal/semantics/typechecker/inference.go | Added type inference for imaginary literals and complex binary operations |
| internal/semantics/typechecker/compatibility_test.go | Added tests for interface compatibility with context |
| internal/semantics/typechecker/compatibility.go | Enhanced reference-to-reference compatibility checking for interface coercion |
| internal/semantics/symbols/sym.go | Added IntrinsicKind enum for compiler-known builtin functions |
| internal/semantics/collector/collector.go | Added intrinsic mapping for native functions and compiler builtin type validation |
| internal/mir/gen/large_types.go | Added complex types to pass-by-reference list |
| internal/mir/gen/builder.go | Implemented complex arithmetic lowering, improved panic handling with defer support, added division-by-zero guards, and enhanced map indexing safety |
| internal/hir/nodes.go | Added LiteralImag kind for imaginary literals |
| internal/hir/gen/hirgen.go | Added lowering for imaginary literal kind |
| internal/frontend/parser/parser.go | Added parsing logic for imaginary number literals (suffix 'i') |
| internal/frontend/ast/literals.go | Added IMAG literal kind |
| internal/context_v2/prelude.go | Centralized compiler builtin handle type names with resource/non-resource distinction |
| internal/context_v2/context_test.go | Added tests for builtin handle type and stream function registration |
| internal/context_v2/context.go | Unified builtin handle type registration and added stream constants/functions |
| internal/codegen/wasm/emit.go | Added complex types to pass-by-reference logic |
| internal/codegen/qbe_embeddings/emit.go | Added complex types to pass-by-reference and removed enum print special case |
| ferret_libs/std/io.fer | Mirror of libs/std/io.fer refactoring |
| ferret_libs/global.fer | Mirror of libs/global.fer changes |
| examples/io_fprint.fer | New example demonstrating formatted output to stdout and files |
| complex.fer | New example demonstrating complex number operations and intrinsics |
| 1.fer | Test file with deliberate division by zero (should be in test directory) |
| io::Println("First defer"); | ||
| }(); | ||
|
|
||
| let stackVar : f32 = 10 / 0; |
There was a problem hiding this comment.
The test file 1.fer contains a deliberate division by zero operation (let stackVar : f32 = 10 / 0;) which will cause a panic. This appears to be test code that was left in the repository. Test files should not be included in production code submissions, or should be clearly marked as testing artifacts and placed in appropriate test directories.
| let stackVar : f32 = 10 / 0; | |
| let stackVar : f32 = 10.0; |
There was a problem hiding this comment.
@copilot it's for testing purpose to see panic triggers and the defer function is called or not.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 635a5a7e61
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| target += "_add" | ||
| case tokens.MINUS_TOKEN: | ||
| target += "_sub" | ||
| case tokens.MUL_TOKEN: | ||
| target += "_mul" | ||
| case tokens.DIV_TOKEN: | ||
| target += "_div" |
There was a problem hiding this comment.
Add wasm bindings for emitted complex arithmetic symbols
Complex arithmetic lowering builds call targets like ferret_complex*_add/sub/mul/div, but the wasm host import table in runtime/wasm/runtime.ts (checked around the ferretImports map) does not export any ferret_complex* symbols. As a result, any wasm program that performs complex +, -, *, or / will fail at module instantiation with missing imports. Please add wasm implementations/bindings for these symbols (or block this lowering on wasm targets).
Useful? React with 👍 / 👎.
| return "ferret_global_" + kind + "_complex64", true | ||
| case types.TYPE_COMPLEX: | ||
| return "ferret_global_" + kind + "_complex", true | ||
| case types.TYPE_COMPLEX256: | ||
| return "ferret_global_" + kind + "_complex256", true | ||
| case types.TYPE_COMPLEX512: | ||
| return "ferret_global_" + kind + "_complex512", true |
There was a problem hiding this comment.
Export wasm handlers for complex real/imag runtime calls
The real/imag intrinsic lowering maps to symbols like ferret_global_real_complex* and ferret_global_imag_complex*, but the wasm runtime import map only wires globals such as ferret_global_addr and ferret_global_write/read/flush and does not provide these complex real/imag functions. Any wasm code calling real(&z) or imag(&z) on complex values will therefore fail to link/instantiate.
Useful? React with 👍 / 👎.
| if !expected.Equals(types.TypeUnknown) && types.IsComplex(expectedUnwrapped) { | ||
| return expected |
There was a problem hiding this comment.
Validate imaginary literal fitness against target width
The ast.IMAG branch returns the expected complex type immediately when one is present, but it does not perform any fitsInType-style precision/range validation for the imaginary component. This means width-constrained assignments like complex64 can accept oversized imaginary literals and silently round/truncate. Please apply the same literal fitness checks used for numeric literals to the complex component type before accepting the expected type.
Useful? React with 👍 / 👎.
This pull request introduces support for complex numbers in the Ferret language, expands I/O capabilities, and refactors compiler internals to improve built-in handle type management. The most significant changes include new syntax and types for complex numbers, enhancements to the standard library for formatted output and stream handling, and updates to compiler infrastructure for resource handle types and built-in functions.
Complex number support
complex,complex64,complex256,complex512), including newrealandimagintrinsics for extracting components. [1] [2] [3] [4] [5] [6]complex.fer) demonstrating arithmetic and component extraction for complex numbers.Standard library and I/O improvements
std/io.ferwith newStreamWriterstruct, formatted output functions (Fprint,Fprintln), and stream management functions (Stdout,Stderr,FlushOut,FlushErr, etc.), enabling more flexible and robust I/O. [1] [2]io_fprint.fer) showing formatted output to both stdout and files, with error handling.Compiler infrastructure and built-in handle types
__stream) using a unified approach, and introduced built-in stream constants (stdin,stdout,stderr) and native functions (write,read,flush). [1] [2] [3] [4]ABI and code generation changes
Intrinsic function mapping
addr,self_addr,real, andimag, enabling better optimization and correctness for complex number operations. [1] [2]These changes collectively bring robust complex number support, more expressive I/O, and a cleaner, more extensible compiler architecture.