Add environment variable access with $NAME syntax

Lexes $NAME as TK_ENVVAR, compiles reads as __getenv("NAME") calls
and writes ($NAME = expr) as __setenv("NAME", expr) calls. Runtime
functions wrap getenv/setenv/unsetenv with automatic tostring coercion.
This commit is contained in:
Cormac Shannon
2026-02-28 18:08:09 +00:00
parent a773398cab
commit 882a90be48
4 changed files with 94 additions and 17 deletions

39
linit.c
View File

@@ -13,12 +13,14 @@
#include <stddef.h>
#include <stdlib.h>
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
#include "llimits.h"
#include "lcmd.h"
/*
@@ -40,30 +42,39 @@ static const luaL_Reg stdlibs[] = {
};
/*
** Stub __command function for backtick command syntax.
** Returns a table {code=0, stdout=cmdstring, stderr=""}.
** The real implementation will be provided by issue #03.
*/
static int luaB_command (lua_State *L) {
const char *cmd = luaL_checkstring(L, 1);
lua_createtable(L, 0, 3);
lua_pushinteger(L, 0);
lua_setfield(L, -2, "code");
lua_pushstring(L, cmd);
lua_setfield(L, -2, "stdout");
lua_pushliteral(L, "");
lua_setfield(L, -2, "stderr");
static int luaB_getenv (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
const char *val = getenv(name);
if (val == NULL)
lua_pushnil(L);
else
lua_pushstring(L, val);
return 1;
}
static int luaB_setenv (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
if (lua_isnoneornil(L, 2))
unsetenv(name);
else {
const char *val = luaL_tolstring(L, 2, NULL);
setenv(name, val, 1);
}
return 0;
}
/*
** Register shell built-in globals (called after standard libraries).
*/
static void opencommand (lua_State *L) {
lua_pushcfunction(L, luaB_command);
lua_setglobal(L, "__command");
lua_pushcfunction(L, luaB_getenv);
lua_setglobal(L, "__getenv");
lua_pushcfunction(L, luaB_setenv);
lua_setglobal(L, "__setenv");
}