Added new opcode OP_ENV to provide an env() function to get environment variables from your OS.
This commit is contained in:
parent
f3b979c07f
commit
4345fc6f0c
6 changed files with 47 additions and 3 deletions
18
examples/os_env.fun
Normal file
18
examples/os_env.fun
Normal 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()
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)++; /* '(' */
|
||||
|
|
|
|||
1
src/vm.c
1
src/vm.c
|
|
@ -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"
|
||||
|
|
|
|||
4
src/vm.h
4
src/vm.h
|
|
@ -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
14
src/vm/os/env.c
Normal 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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue