added more experimental code for the cli mode
This commit is contained in:
parent
256472b2ea
commit
fe28d23307
62
lib/comp.c
62
lib/comp.c
@ -1566,28 +1566,58 @@ static HCL_INLINE int compile_symbol (hcl_t* hcl, hcl_oop_t obj)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check if a symbol is a local variable */
|
if (hcl->option.trait & HCL_CLI_MODE)
|
||||||
if (find_temporary_variable_backward(hcl, obj, &index) <= -1)
|
|
||||||
{
|
{
|
||||||
hcl_oop_t cons;
|
if (find_temporary_variable_backward(hcl, obj, &index) <= -1)
|
||||||
/* TODO: if i require all variables to be declared, this part is not needed and should handle it as an error */
|
|
||||||
/* TODO: change the scheme... allow declaration??? */
|
|
||||||
/* global variable */
|
|
||||||
cons = (hcl_oop_t)hcl_getatsysdic(hcl, obj);
|
|
||||||
if (!cons)
|
|
||||||
{
|
{
|
||||||
cons = (hcl_oop_t)hcl_putatsysdic(hcl, obj, hcl->_nil);
|
hcl_oop_t cons;
|
||||||
if (!cons) return -1;
|
|
||||||
|
cons = (hcl_oop_t)hcl_getatsysdic(hcl, obj);
|
||||||
|
if (cons)
|
||||||
|
{
|
||||||
|
if (add_literal(hcl, cons, &index) <= -1 ||
|
||||||
|
emit_single_param_instruction(hcl, HCL_CODE_PUSH_OBJECT_0, index) <= -1) return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* in the cli mode, a symbol is pushed as a normal literal if it is not resolved
|
||||||
|
* at the moment of compilation */
|
||||||
|
if (add_literal(hcl, obj, &index) <= -1 ||
|
||||||
|
emit_single_param_instruction(hcl, HCL_CODE_PUSH_LITERAL_0, index) <= -1) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return emit_indexed_variable_access(hcl, index, HCL_CODE_PUSH_CTXTEMPVAR_0, HCL_CODE_PUSH_TEMPVAR_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (add_literal(hcl, cons, &index) <= -1 ||
|
|
||||||
emit_single_param_instruction(hcl, HCL_CODE_PUSH_OBJECT_0, index) <= -1) return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return emit_indexed_variable_access(hcl, index, HCL_CODE_PUSH_CTXTEMPVAR_0, HCL_CODE_PUSH_TEMPVAR_0);
|
/* check if a symbol is a local variable */
|
||||||
|
if (find_temporary_variable_backward(hcl, obj, &index) <= -1)
|
||||||
|
{
|
||||||
|
hcl_oop_t cons;
|
||||||
|
/* TODO: if i require all variables to be declared, this part is not needed and should handle it as an error */
|
||||||
|
/* TODO: change the scheme... allow declaration??? */
|
||||||
|
/* global variable */
|
||||||
|
cons = (hcl_oop_t)hcl_getatsysdic(hcl, obj);
|
||||||
|
if (!cons)
|
||||||
|
{
|
||||||
|
cons = (hcl_oop_t)hcl_putatsysdic(hcl, obj, hcl->_nil);
|
||||||
|
if (!cons) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add_literal(hcl, cons, &index) <= -1 ||
|
||||||
|
emit_single_param_instruction(hcl, HCL_CODE_PUSH_OBJECT_0, index) <= -1) return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return emit_indexed_variable_access(hcl, index, HCL_CODE_PUSH_CTXTEMPVAR_0, HCL_CODE_PUSH_TEMPVAR_0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
#include "hcl-prv.h"
|
#include "hcl-prv.h"
|
||||||
|
|
||||||
#define SYMBOL_ONLY_KEY
|
#define SYMBOL_ONLY_KEY
|
||||||
|
|
||||||
static hcl_oop_oop_t expand_bucket (hcl_t* hcl, hcl_oop_oop_t oldbuc)
|
static hcl_oop_oop_t expand_bucket (hcl_t* hcl, hcl_oop_oop_t oldbuc)
|
||||||
{
|
{
|
||||||
|
62
lib/exec.c
62
lib/exec.c
@ -1015,9 +1015,9 @@ extern char **environ;
|
|||||||
|
|
||||||
static int is_regular_executable_file_by_me(const char *path)
|
static int is_regular_executable_file_by_me(const char *path)
|
||||||
{
|
{
|
||||||
struct stat path_stat;
|
struct stat st;
|
||||||
stat(path, &path_stat);
|
if (stat(path, &st) == -1) return 0;
|
||||||
return S_ISREG(path_stat.st_mode) && access(path, X_OK) == 0; //? use eaccess instead??
|
return S_ISREG(st.st_mode) && access(path, X_OK) == 0; //? use eaccess instead??
|
||||||
}
|
}
|
||||||
|
|
||||||
static char* find_exec (hcl_t* hcl, const char *name)
|
static char* find_exec (hcl_t* hcl, const char *name)
|
||||||
@ -1078,7 +1078,8 @@ done:
|
|||||||
static HCL_INLINE int exec_syscmd (hcl_t* hcl, hcl_ooi_t nargs)
|
static HCL_INLINE int exec_syscmd (hcl_t* hcl, hcl_ooi_t nargs)
|
||||||
{
|
{
|
||||||
hcl_oop_word_t rcv;
|
hcl_oop_word_t rcv;
|
||||||
hcl_bch_t* cmd, * xcmd;
|
hcl_bch_t* cmd = HCL_NULL;
|
||||||
|
hcl_bch_t* xcmd = HCL_NULL;
|
||||||
|
|
||||||
rcv = (hcl_oop_word_t)HCL_STACK_GETRCV(hcl, nargs);
|
rcv = (hcl_oop_word_t)HCL_STACK_GETRCV(hcl, nargs);
|
||||||
/*HCL_ASSERT (hcl, HCL_IS_STRING(hcl, rcv) || HCL_IS_SYMBOL(hcl, rcv));*/
|
/*HCL_ASSERT (hcl, HCL_IS_STRING(hcl, rcv) || HCL_IS_SYMBOL(hcl, rcv));*/
|
||||||
@ -1088,18 +1089,18 @@ static HCL_INLINE int exec_syscmd (hcl_t* hcl, hcl_ooi_t nargs)
|
|||||||
{
|
{
|
||||||
/* '\0' is contained in the middle */
|
/* '\0' is contained in the middle */
|
||||||
hcl_seterrbfmt (hcl, HCL_EINVAL, "invalid callable %O", rcv);
|
hcl_seterrbfmt (hcl, HCL_EINVAL, "invalid callable %O", rcv);
|
||||||
return -1;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd = hcl_dupootobcstr(hcl, HCL_OBJ_GET_CHAR_SLOT(rcv), HCL_NULL);
|
cmd = hcl_dupootobcstr(hcl, HCL_OBJ_GET_CHAR_SLOT(rcv), HCL_NULL);
|
||||||
if (!cmd) return -1;
|
if (!cmd) goto oops;
|
||||||
|
|
||||||
if (hcl_find_bchar_in_bcstr(cmd, '/'))
|
if (hcl_find_bchar_in_bcstr(cmd, '/'))
|
||||||
{
|
{
|
||||||
if (!is_regular_executable_file_by_me(cmd))
|
if (!is_regular_executable_file_by_me(cmd))
|
||||||
{
|
{
|
||||||
hcl_seterrbfmt (hcl, HCL_ECALL, "cannot execute %O", rcv);
|
hcl_seterrbfmt (hcl, HCL_ECALL, "cannot execute %O", rcv);
|
||||||
return -1;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
xcmd = cmd;
|
xcmd = cmd;
|
||||||
@ -1107,7 +1108,7 @@ static HCL_INLINE int exec_syscmd (hcl_t* hcl, hcl_ooi_t nargs)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
xcmd = find_exec(hcl, cmd);
|
xcmd = find_exec(hcl, cmd);
|
||||||
if (!xcmd) return -1;
|
if (!xcmd) goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
{ /* TODO: make it a callback ... */
|
{ /* TODO: make it a callback ... */
|
||||||
@ -1115,36 +1116,38 @@ static HCL_INLINE int exec_syscmd (hcl_t* hcl, hcl_ooi_t nargs)
|
|||||||
int status;
|
int status;
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid == -1) return -1;
|
if (pid == -1) goto oops;
|
||||||
|
|
||||||
/* TODO: set a new process group / session leader??? */
|
/* TODO: set a new process group / session leader??? */
|
||||||
|
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
{
|
{
|
||||||
|
hcl_bch_t** argv;
|
||||||
|
hcl_ooi_t i;
|
||||||
|
|
||||||
hcl_bch_t** argv;
|
/* TODO: close file descriptors??? */
|
||||||
hcl_ooi_t i;
|
argv = (hcl_bch_t**)hcl_allocmem(hcl, (nargs + 2) * HCL_SIZEOF(*argv));
|
||||||
|
if (argv)
|
||||||
/* TODO: close file descriptors??? */
|
{
|
||||||
argv = (hcl_bch_t**)hcl_allocmem(hcl, (nargs + 2) * HCL_SIZEOF(*argv));
|
argv[0] = cmd;
|
||||||
if (argv)
|
|
||||||
{
|
|
||||||
argv[0] = cmd;
|
|
||||||
HCL_DEBUG1 (hcl, "NARG %d\n", (int)nargs);
|
HCL_DEBUG1 (hcl, "NARG %d\n", (int)nargs);
|
||||||
for (i = 0; i < nargs;)
|
for (i = 0; i < nargs;)
|
||||||
{
|
{
|
||||||
hcl_oop_t ta = HCL_STACK_GETARG(hcl, nargs, i);
|
hcl_oop_t ta = HCL_STACK_GETARG(hcl, nargs, i);
|
||||||
/* TODO: check if an argument is a string or a symbol */
|
/* TODO: check if an argument is a string or a symbol */
|
||||||
argv[++i] = hcl_dupootobchars(hcl, HCL_OBJ_GET_CHAR_SLOT(ta), HCL_OBJ_GET_SIZE(ta), HCL_NULL);
|
argv[++i] = hcl_dupootobchars(hcl, HCL_OBJ_GET_CHAR_SLOT(ta), HCL_OBJ_GET_SIZE(ta), HCL_NULL);
|
||||||
HCL_DEBUG2 (hcl, "ARG %d -> %hs\n", (int)i - 1, argv[i]);
|
HCL_DEBUG2 (hcl, "ARG %d -> %hs\n", (int)i - 1, argv[i]);
|
||||||
}
|
|
||||||
argv[nargs + 1] = HCL_NULL;
|
|
||||||
execvp (xcmd, argv);
|
|
||||||
}
|
}
|
||||||
_exit (255);
|
argv[nargs + 1] = HCL_NULL;
|
||||||
|
execvp (xcmd, argv);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmd) hcl_freemem (hcl, cmd);
|
||||||
|
if (xcmd && xcmd != cmd) hcl_freemem (hcl, xcmd);
|
||||||
|
_exit (255);
|
||||||
}
|
}
|
||||||
|
|
||||||
waitpid (pid, &status, 0);
|
waitpid (pid, &status, 0); /* TOOD: enhance this waiting */
|
||||||
|
|
||||||
HCL_STACK_SETRET (hcl, nargs, HCL_SMOOI_TO_OOP(WEXITSTATUS(status)));
|
HCL_STACK_SETRET (hcl, nargs, HCL_SMOOI_TO_OOP(WEXITSTATUS(status)));
|
||||||
}
|
}
|
||||||
@ -1152,6 +1155,11 @@ HCL_DEBUG2 (hcl, "ARG %d -> %hs\n", (int)i - 1, argv[i]);
|
|||||||
hcl_freemem (hcl, cmd);
|
hcl_freemem (hcl, cmd);
|
||||||
if (xcmd != cmd) hcl_freemem (hcl, xcmd);
|
if (xcmd != cmd) hcl_freemem (hcl, xcmd);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
if (cmd) hcl_freemem (hcl, cmd);
|
||||||
|
if (xcmd && xcmd != cmd) hcl_freemem (hcl, xcmd);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
@ -1738,6 +1746,8 @@ static int execute (hcl_t* hcl)
|
|||||||
case HCL_BRAND_PRIM:
|
case HCL_BRAND_PRIM:
|
||||||
if (call_primitive(hcl, b1) <= -1) goto oops;
|
if (call_primitive(hcl, b1) <= -1) goto oops;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HCL_BRAND_SYMBOL:
|
||||||
case HCL_BRAND_STRING:
|
case HCL_BRAND_STRING:
|
||||||
if ((hcl->option.trait & HCL_CLI_MODE) && exec_syscmd(hcl, b1) >= 0) break;
|
if ((hcl->option.trait & HCL_CLI_MODE) && exec_syscmd(hcl, b1) >= 0) break;
|
||||||
/* fall thru */
|
/* fall thru */
|
||||||
|
@ -2405,8 +2405,12 @@ HCL_DEBUG0 (hcl, "22 LEAVING LIST\n");
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case HCL_IOTOK_STRLIT:
|
case HCL_IOTOK_STRLIT:
|
||||||
|
obj = hcl_makestring(hcl, TOKEN_NAME_PTR(hcl), TOKEN_NAME_LEN(hcl), 0);
|
||||||
|
break;
|
||||||
|
|
||||||
case HCL_IOTOK_IDENT:
|
case HCL_IOTOK_IDENT:
|
||||||
obj = hcl_makestring(hcl, TOKEN_NAME_PTR(hcl), TOKEN_NAME_LEN(hcl), 0);
|
obj = hcl_makestring(hcl, TOKEN_NAME_PTR(hcl), TOKEN_NAME_LEN(hcl), 0);
|
||||||
|
obj = hcl_makesymbol(hcl, TOKEN_NAME_PTR(hcl), TOKEN_NAME_LEN(hcl));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user