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
|
// file I/O
|
||||||
OP_READ_FILE, // pops path string; pushes content string (or "")
|
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;
|
} OpCode;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
|
|
@ -663,6 +663,14 @@ static int emit_primary(Bytecode *bc, const char *src, size_t len, size_t *pos)
|
||||||
free(name);
|
free(name);
|
||||||
return 1;
|
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 */
|
/* string ops */
|
||||||
if (strcmp(name, "split") == 0) {
|
if (strcmp(name, "split") == 0) {
|
||||||
(*pos)++; /* '(' */
|
(*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/read_file.c"
|
||||||
#include "vm/io/write_file.c"
|
#include "vm/io/write_file.c"
|
||||||
|
#include "vm/os/env.c"
|
||||||
|
|
||||||
#include "vm/logic/and.c"
|
#include "vm/logic/and.c"
|
||||||
#include "vm/logic/eq.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",
|
"ENUMERATE","ZIP",
|
||||||
"MIN","MAX","CLAMP","ABS","POW","RANDOM_SEED","RANDOM_INT",
|
"MIN","MAX","CLAMP","ABS","POW","RANDOM_SEED","RANDOM_INT",
|
||||||
"MAKE_MAP","KEYS","VALUES","HAS_KEY",
|
"MAKE_MAP","KEYS","VALUES","HAS_KEY",
|
||||||
"READ_FILE","WRITE_FILE"
|
"READ_FILE","WRITE_FILE","ENV"
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -76,7 +76,7 @@ void vm_dump_globals(VM *vm);
|
||||||
void vm_run(VM *vm, Bytecode *entry);
|
void vm_run(VM *vm, Bytecode *entry);
|
||||||
|
|
||||||
static inline int opcode_is_valid(int op) {
|
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
|
#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