diff --git a/jumpforth.S b/jumpforth.S index df7a163..ce387b0 100644 --- a/jumpforth.S +++ b/jumpforth.S @@ -36,6 +36,11 @@ .globl _start _start: cld + mov (%esp),%eax + mov %eax,data_ARGC + lea 4(%esp),%eax + mov %eax,data_ARGV + sub $64,%esp mov %esp,data_S0 mov $return_stack_top,%ebp xor %ebx,%ebx @@ -208,6 +213,8 @@ defconst __F_LENMASK,F_LENMASK,"F_LENMASK" /* NOTE: These are initialized in _start and read-only thereafter. */ defvalue C0 /* first byte of the heap */ defvalue S0 /* initial (empty) data stack pointer */ +defvalue ARGC /* number of command-line arguments (including program name) */ +defvalue ARGV /* address of array of command-line arguments (C string pointers) */ /* STATE controls whether we are currently interpreting (0) or compiling (1) */ defvar STATE,0 /* default to interpreting */ diff --git a/startup.4th b/startup.4th index f1823cb..8890edb 100644 --- a/startup.4th +++ b/startup.4th @@ -2240,8 +2240,31 @@ REVERT { LOCAL-LOOKUP ?DUP 0= IF DEFERS FIND-HOOK THEN } IS FIND-HOOK +\ The environment consists of an array of pointers to "name=value" C strings +\ immediately following the NULL-terminated array of argument pointers +ARGV ARGC 1+ CELLS+ CONSTANT ENVIRON + >> FORTH +\ Convert a C string to a FORTH string by counting the characters +: CSTRING ( c-addr -- c-addr u ) 0 BEGIN 2DUP + C@ WHILE 1+ REPEAT ; + +\ Return the string value of the named environment variable +: GETENV ( c-addr u -- c-addr2 u2 TRUE | FALSE ) + 2>R ENVIRON BEGIN + DUP @ + DUP WHILE + 0 BEGIN 2DUP + C@ DUP WHILE DUP [[ CHAR = ]] <> WHILE DROP 1+ REPEAT + IF 2DUP + 1+ CSTRING ELSE 0 0 THEN 2SWAP + 2R@ COMPARE 0= IF 2RDROP ROT DROP TRUE EXIT THEN + 2DROP CELL+ + REPEAT ▪ NIP ▪ 2RDROP ; + +\ Return the string value of the numbered command-line argument +\ Argument 0 is (normally) the pathname of the current program +: ARGV ( u -- c-addr u ) + DUP ARGC U>= IF DROP 0 0 ELSE ARGV SWAP CELLS+ @ CSTRING THEN ; + : LOCALS| ( "name1…namen|" -- ; xn … x1 -- ) IMMEDIATE LOCAL-NAMES ▪ NULL TO LOCAL-NAMES 0 BEGIN