1
0
Fork 0
forked from fun/fun

Added new opcode OP_ENV to provide an env() function to get environment variables from your OS.

This commit is contained in:
Johannes Findeisen 2025-09-27 10:06:04 +02:00
commit 4345fc6f0c
6 changed files with 47 additions and 3 deletions

18
examples/os_env.fun Normal file
View file

@ -0,0 +1,18 @@
#!/usr/bin/env fun
// Environment variables via env(name):
// - Returns the value as a string.
// - If the variable is not set, returns an empty string.
print("HOME=" + env("HOME"))
print("SHELL=" + env("SHELL"))
print("FUN_NOT_SET=" + env("FUN_NOT_SET"))
// You can use it in scripts, e.g.:
fun greet()
user = env("USER")
if user == ""
print("Hello, mysterious friend!")
else
print("Hello, " + user + "!")
greet()

View file

@ -110,7 +110,10 @@ typedef enum {
// file I/O
OP_READ_FILE, // pops path string; pushes content string (or "")
OP_WRITE_FILE // pops data string, path string; pushes 1/0
OP_WRITE_FILE, // pops data string, path string; pushes 1/0
// OS
OP_ENV // pops name string; pushes value string (or "")
} OpCode;
typedef struct {

View file

@ -663,6 +663,14 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
free(name);
return 1;
}
if (strcmp(name, "env") == 0) {
(*pos)++; /* '(' */
if (!emit_expression(bc, src, len, pos)) { parser_fail(*pos, "env expects 1 argument"); free(name); return 0; }
if (!consume_char(src, len, pos, ')')) { parser_fail(*pos, "Expected ')' after env arg"); free(name); return 0; }
bytecode_add_instruction(bc, OP_ENV, 0);
free(name);
return 1;
}
/* string ops */
if (strcmp(name, "split") == 0) {
(*pos)++; /* '(' */

View file

@ -266,6 +266,7 @@ void vm_run(VM *vm, Bytecode *entry) {
#include "vm/io/read_file.c"
#include "vm/io/write_file.c"
#include "vm/os/env.c"
#include "vm/logic/and.c"
#include "vm/logic/eq.c"

View file

@ -33,7 +33,7 @@ static const char *opcode_names[] = {
"ENUMERATE","ZIP",
"MIN","MAX","CLAMP","ABS","POW","RANDOM_SEED","RANDOM_INT",
"MAKE_MAP","KEYS","VALUES","HAS_KEY",
"READ_FILE","WRITE_FILE"
"READ_FILE","WRITE_FILE","ENV"
};
typedef struct {
@ -76,7 +76,7 @@ void vm_dump_globals(VM *vm);
void vm_run(VM *vm, Bytecode *entry);
static inline int opcode_is_valid(int op) {
return op >= OP_NOP && op <= OP_WRITE_FILE; // all current opcodes
return op >= OP_NOP && op <= OP_ENV; // all current opcodes
}
#endif

14
src/vm/os/env.c Normal file
View file

@ -0,0 +1,14 @@
case OP_ENV: {
Value key = pop_value(vm);
if (key.type != VAL_STRING) {
fprintf(stderr, "Runtime type error: ENV expects string name\n");
free_value(key);
exit(1);
}
const char *name = key.s ? key.s : "";
const char *val = getenv(name);
/* Return empty string if not set (consistent with read_file fallback style) */
push_value(vm, make_string(val ? val : ""));
free_value(key);
break;
}