#include <onward.h>
#include <onward_sys.h>
-
-/* System Calls
- *****************************************************************************/
#include <stdio.h>
-#include <stdlib.h>
+#include <stdbool.h>
+#include <dlfcn.h>
-static void syscall_open(void)
-{
- intptr_t modenum = onward_aspop();
- char* fname = (char*)onward_aspop();
- char* mode;
- switch (modenum) {
- case 0: mode = "r"; break;
- case 1: mode = "w"; break;
- case 2: mode = "a"; break;
- case 3: mode = "r+"; break;
- case 4: mode = "w+"; break;
- case 5: mode = "a+"; break;
- default: mode = NULL; break;
- }
- onward_aspush(mode ? (intptr_t)fopen(fname, mode) : 0);
-}
-static void syscall_close(void)
-{
- onward_aspush(fclose((FILE*)onward_aspop()));
-}
+FILE* infile;
+FILE* outfile;
-static void syscall_read(void)
-{
- size_t nbytes = (size_t)onward_aspop();
- FILE* fhndl = (FILE*)onward_aspop();
- void* dest = (void*)onward_aspop();
- onward_aspush(nbytes != fread(dest, 1u, nbytes, fhndl));
-}
+/* Standalone Interpreter
+ *****************************************************************************/
-static void syscall_write(void)
-{
- size_t nbytes = (size_t)onward_aspop();
- void* src = (void*)onward_aspop();
- FILE* fhndl = (FILE*)onward_aspop();
- onward_aspush(nbytes != fwrite(src, 1u, nbytes, fhndl));
-}
+static bool Newline_Consumed = false;
+value_t Argument_Stack[ARG_STACK_SZ];
+value_t Return_Stack[RET_STACK_SZ];
+value_t Word_Buffer[WORD_BUF_SZ];
-static void syscall_seek(void)
-{
- intptr_t nbytes = onward_aspop();
- intptr_t origin = onward_aspop();
- FILE* fhndl = (FILE*)onward_aspop();
- origin = (origin == 0) ? SEEK_CUR : (origin < 0) ? SEEK_SET : SEEK_END;
- onward_aspush(fseek(fhndl, nbytes, origin));
-}
-static void syscall_alloc(void)
-{
- onward_aspush((intptr_t)malloc((size_t)onward_aspop()));
+defcode("load-lib", load_lib, LATEST_BUILTIN, 0u) {
+ char* lib = (char*)onward_aspop();
+ void* handle = dlopen(lib, RTLD_LAZY);
+ if (!handle)
+ {
+ fprintf(stderr, "%s\n", dlerror());
+ }
+ onward_aspush((value_t)handle);
}
-static void syscall_free(void)
-{
- free((void*)onward_aspop());
+defcode("load-sym", load_sym, &load_lib, 0u) {
+ char* sym = (char*)onward_aspop();
+ void* lib = (void*)onward_aspop();
+ void* val = dlsym(lib, sym);
+ onward_aspush((value_t)val);
}
-typedef void (*syscall_fn_t)(void);
-
-static syscall_fn_t System_Calls[7] = {
- /* File Operations */
- &syscall_open,
- &syscall_close,
- &syscall_read,
- &syscall_write,
- &syscall_seek,
+defcode("ccall", ccall, &load_sym, 0u) {
- /* Memory Operations */
- &syscall_alloc,
- &syscall_free,
-};
-
-/* Standalone Interpreter
- *****************************************************************************/
-#include <stdbool.h>
+}
-static bool Newline_Consumed = false;
-value_t Argument_Stack[ARG_STACK_SZ];
-value_t Return_Stack[RET_STACK_SZ];
-value_t Word_Buffer[WORD_BUF_SZ];
+defcode("ccall-ret", ccall_ret, &ccall, 0u) {
-defvar("infile", infile, 0u, LATEST_BUILTIN);
-defvar("outfile", outfile, 0u, &infile_word);
-defvar("errfile", errfile, 0u, &outfile_word);
-defcode("syscall", syscall, &errfile_word, 0u) {
- System_Calls[onward_aspop()]();
}
-defcode("dumpw", dumpw, &syscall, 0u) {
+defcode("dumpw", dumpw, &load_sym, 0u) {
word_t* word = (word_t*)onward_aspop();
printf("name:\t'%s'\n", word->name);
printf("flags:\t%#zx\n", word->flags);
}
}
+
value_t fetch_char(void)
{
- value_t ch = (value_t)fgetc((FILE*)infile);
+ value_t ch = (value_t)fgetc(infile);
if ((char)ch == '\n')
Newline_Consumed = true;
return ch;
void emit_char(value_t val)
{
- fputc((int)val, (FILE*)outfile);
+ fputc((int)val, outfile);
}
void print_stack(void) {
}
void parse(FILE* file) {
- value_t old = infile;
- infile = (value_t)file;
+ FILE* old = infile;
+ infile = file;
if (file == stdin)
printf(":> ");
while (!feof(file)) {
int i;
/* Initialize implementation specific words */
latest = (value_t)&dumpw;
- infile = (value_t)stdin;
- outfile = (value_t)stdout;
- errfile = (value_t)stderr;
+ infile = stdin;
+ outfile = stdout;
/* Load any dictionaries specified on the command line */
for (i = 1; i < argc; i++)
parse_file(argv[i]);
static value_t char_oneof(char ch, char* chs);
-/** Version number of the implementation */
-defconst("VERSION", VERSION, 0, 0u);
-
/** Number of bytes in a stack cell */
-defconst("CELLSZ", CELLSZ, sizeof(value_t), &VERSION_word);
+defconst("CELLSZ", CELLSZ, sizeof(value_t), 0u);
/** Number of bits that make up a stack cell */
defconst("BITCOUNT", BITCOUNT, SYS_BITCOUNT, &CELLSZ_word);
/** Fetches the next word from the input string */
defcode("word", word, &dropline, 0u) {
- static char buffer[32u];
+ static char buffer[1024u];
char* str = buffer;
int curr;
/* Skip any whitespace */
key_code();
curr = (int)onward_aspop();
} while (char_oneof((char)curr, " \t\r\n"));
+
/* Copy characters into the buffer */
while(((int)curr != EOF) && !char_oneof((char)curr, " \t\r\n")) {
*str++ = (char)curr;
key_code();
curr = (int)onward_aspop();
}
+
/* Terminate the string */
*str = '\0';
+
/* Return the internal buffer */
onward_aspush((value_t)buffer);
}
do {
word_t* current = (word_t*)( onward_pcfetch() );
/* If the current instruction is null then "return" */
- if ((void*)0u == current) {
+ if (NULL == current) {
pc = (value_t)onward_rspop();
/* if the instruction is a primitive then execute the c function */
} else if (current->flags & F_PRIMITIVE_MSK) {