Skip to content
This repository was archived by the owner on Apr 30, 2026. It is now read-only.

Commit 440027e

Browse files
committed
fix: make print variadic to match println behavior
print was registered as a unary function (single argument), while println was variadic. This meant (print "%" expr) only received "%" as its argument — the second expression was evaluated separately. Changed print from register_unary to register_vary with the same format-string interpolation and multi-arg spacing as println, just without the trailing newline. Moved implementation from system.c to builtins.c alongside println/show to share fmt_interpolate.
1 parent 6cf5b16 commit 440027e

4 files changed

Lines changed: 30 additions & 7 deletions

File tree

src/lang/eval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2038,7 +2038,7 @@ static void ray_register_builtins(void) {
20382038
/* Eval, parse, print, meta */
20392039
register_unary("eval", RAY_FN_NONE, ray_eval_builtin_fn);
20402040
register_unary("parse", RAY_FN_NONE, ray_parse_builtin_fn);
2041-
register_unary("print", RAY_FN_NONE, ray_print_fn);
2041+
register_vary("print", RAY_FN_NONE, ray_print_fn);
20422042
register_unary("meta", RAY_FN_NONE, ray_meta_fn);
20432043

20442044
/* System builtins */

src/lang/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ void ray_dl_reset_rules(void);
410410
/* System builtins (formerly static in eval.c, now in system.c) */
411411
ray_t* ray_eval_builtin_fn(ray_t* x);
412412
ray_t* ray_parse_builtin_fn(ray_t* x);
413-
ray_t* ray_print_fn(ray_t* x);
413+
ray_t* ray_print_fn(ray_t** args, int64_t n);
414414
ray_t* ray_meta_fn(ray_t* x);
415415
ray_t* ray_gc_fn(ray_t* x);
416416
ray_t* ray_system_fn(ray_t* x);

src/ops/builtins.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,33 @@ ray_t* ray_println_fn(ray_t** args, int64_t n) {
242242
return RAY_NULL_OBJ;
243243
}
244244

245+
/* (print val1 val2 ...) — like println but without trailing newline */
246+
ray_t* ray_print_fn(ray_t** args, int64_t n) {
247+
for (int64_t i = 0; i < n; i++)
248+
if (ray_is_lazy(args[i])) args[i] = ray_lazy_materialize(args[i]);
249+
250+
/* Format string mode: first arg is a string with % placeholders */
251+
if (n >= 2 && args[0] && args[0]->type == -RAY_STR) {
252+
const char* fmt = ray_str_ptr(args[0]);
253+
size_t flen = ray_str_len(args[0]);
254+
size_t out_len = 0;
255+
char* result = fmt_interpolate(fmt, flen, args, n, 1, &out_len);
256+
if (result) {
257+
fwrite(result, 1, out_len, stdout);
258+
fflush(stdout);
259+
ray_sys_free(result);
260+
return RAY_NULL_OBJ;
261+
}
262+
}
263+
264+
for (int64_t i = 0; i < n; i++) {
265+
if (i > 0) fputc(' ', stdout);
266+
ray_lang_print(stdout, args[i]);
267+
}
268+
fflush(stdout);
269+
return RAY_NULL_OBJ;
270+
}
271+
245272
/* (show val1 val2 ...) — print values to stdout using ray_fmt, newline at end */
246273
ray_t* ray_show_fn(ray_t** args, int64_t n) {
247274
for (int64_t i = 0; i < n; i++) {

src/ops/system.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,7 @@ ray_t* ray_parse_builtin_fn(ray_t* x) {
169169
}
170170

171171
/* (print val) -- print without newline, return the value */
172-
ray_t* ray_print_fn(ray_t* x) {
173-
ray_fmt_print(stdout, x, 0);
174-
fflush(stdout);
175-
return x;
176-
}
172+
/* print moved to builtins.c alongside println/show */
177173

178174
/* (meta x) -- return metadata about an object as a dict */
179175
ray_t* ray_meta_fn(ray_t* x) {

0 commit comments

Comments
 (0)