]> git.mdlowis.com Git - projs/onward.git/commitdiff
Added key and emit words and reworked the kernel to use that instead of input
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 2 Dec 2014 01:56:08 +0000 (20:56 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 2 Dec 2014 01:56:08 +0000 (20:56 -0500)
source/main.c
source/onward/onward.c
source/onward/onward.ft
source/onward/onward.h
source/onward/onward_sys.h [new file with mode: 0644]
source/syscall.c
source/syscall.h
tests/main.c
tests/test_interpreter.c
tests/test_vars.c

index dfa4fadc80b3fd6c06411fce974813c641b0e209..6644411352d7f5e86ccd0c46b7a550d0e241ec4e 100755 (executable)
@@ -1,12 +1,8 @@
-#include "onward.h"
-#include <stdio.h>
+#include "onward_sys.h"
 #include "syscall.h"
-
-#define STACK_SZ (64u)
-value_t Arg_Stack_Buf[STACK_SZ];
-value_t Ret_Stack_Buf[STACK_SZ];
-char    Input_Line[1024];
-value_t Ram_Data_Buf[8192/sizeof(value_t)];
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
 
 defcode("dumpw", dumpw, LATEST_BUILTIN, 0u) {
     word_t* word = (word_t*)onward_aspop();
@@ -21,7 +17,7 @@ defcode("dumpw", dumpw, LATEST_BUILTIN, 0u) {
         word_t** code = (word_t**)word->code;
         while(*code) {
             printf("\t%s", (*code)->name);
-            if (*code == &lit)
+            if ((*code == &lit) || (*code == &zbr) || (*code == &br))
                 printf(" %zd", (intptr_t)*(++code));
             code++;
             puts("");
@@ -38,11 +34,27 @@ defvar("infile",  infile,  0u, &syscall);
 defvar("outfile", outfile, 0u, &infile_word);
 defvar("errfile", errfile, 0u, &outfile_word);
 
+/*****************************************************************************/
+bool Newline_Consumed = false;
+
+value_t fetch_char(void)
+{
+    value_t ch = (value_t)fgetc((FILE*)infile);
+    if ((char)ch == '\n')
+        Newline_Consumed = true;
+    return ch;
+}
+
+void emit_char(value_t val)
+{
+    fputc((int)val, (FILE*)outfile);
+}
+
 void print_stack(void) {
     value_t* base = (value_t*)asb;
     value_t* top  = (value_t*)asp;
-    int i;
     printf("( ");
+    int i;
     if (top-5 >= base)
         printf("... ");
     for (i = 4; i >= 0; i--) {
@@ -51,22 +63,25 @@ void print_stack(void) {
             printf("%zd ", *curr);
     }
     puts(")");
-    printf("errno: %zd\n", errno);
-    puts(!errno ? "OK." : "?");
+    printf("errcode: %zd\n", errcode);
+    puts(!errcode ? "OK." : "?");
 }
 
 void parse(FILE* file) {
+    value_t old = infile;
+    infile = (value_t)file;
     if (file == stdin)
         printf(":> ");
-    while(0 != (input = (value_t)fgets(Input_Line, 1024u, file))) {
-        errno = 0;
-        while (*((char*)input) != '\0')
-            interp_code();
-        if (file == stdin) {
+    while (!feof(file)) {
+        interp_code();
+        if ((file == stdin) && Newline_Consumed) {
             print_stack();
-            printf(state ? ".. " : ":> ");
+            printf(":> ");
+            Newline_Consumed = false;
+            errcode = 0;
         }
     }
+    infile = old;
 }
 
 void parse_file(char* fname) {
@@ -79,17 +94,11 @@ void parse_file(char* fname) {
 
 int main(int argc, char** argv) {
     int i;
-    /* Initialize the system */
-    onward_init_t init_data = {
-        Arg_Stack_Buf,
-        STACK_SZ,
-        Ret_Stack_Buf,
-        STACK_SZ,
-        Ram_Data_Buf,
-        8192/sizeof(value_t),
-        (word_t*)&errfile_word
-    };
-    onward_init(&init_data);
+    /* Initialize implementation specific words */
+    latest  = (value_t)&errfile_word;
+    infile  = (value_t)stdin;
+    outfile = (value_t)stdout;
+    errfile = (value_t)stderr;
     /* Load any dictionaries specified on the  command line */
     for (i = 1; i < argc; i++)
         parse_file(argv[i]);
index 2650e8cca63678d8a22eccf6beb31e9f2122a956..d196df2129cb8effd4c4198ce29f6da9a6b1d99f 100755 (executable)
@@ -1,5 +1,7 @@
 #include "onward.h"
+#include "onward_sys.h"
 #include <string.h>
+#include <stdio.h>
 
 static value_t char_oneof(char ch, char* chs);
 static void abort_on_error(value_t cond, value_t errcode);
@@ -26,61 +28,78 @@ defconst("F_IMMEDIATE", F_IMMEDIATE, F_IMMEDIATE_MSK, &F_HIDDEN_word);
 defvar("pc", pc, 0, &F_IMMEDIATE_word);
 
 /** The address of the base of the argument stack */
-defvar("asb", asb, 0, &pc_word);
+defvar("asb", asb, (value_t)Argument_Stack-1, &pc_word);
 
 /** The size of the argument stack in bytes */
-defvar("assz", assz, 0, &asb_word);
+defvar("assz", assz, ARG_STACK_SZ, &asb_word);
 
 /** The address of the top of the argument stack */
-defvar("asp", asp, 0, &assz_word);
+defvar("asp", asp, (value_t)Argument_Stack-1, &assz_word);
 
 /** The address of the base of the return stack */
-defvar("rsb", rsb, 0, &asp_word);
+defvar("rsb", rsb, (value_t)Return_Stack-1, &asp_word);
 
 /** The size of the return stack in bytes */
-defvar("rssz", rssz, 0, &rsb_word);
+defvar("rssz", rssz, RET_STACK_SZ, &rsb_word);
 
 /** The address of the top of the return stack */
-defvar("rsp", rsp, 0, &rssz_word);
-
-/** The address of the current input string */
-defvar("input", input, 0, &rsp_word);
+defvar("rsp", rsp, (value_t)Return_Stack-1, &rssz_word);
 
 /** The last generated error code */
-defvar("errno", errno, 0, &input_word);
+defvar("errno", errno, 0, &rsp_word);
 
 /** Address of the most recently defined word */
-defvar("latest", latest, 0, &errno_word);
+defvar("latest", latest, (value_t)LATEST_BUILTIN, &errno_word);
 
 /** The current state of the interpreter */
 defvar("state", state, 0, &latest_word);
 
 /** The address where the next word or instruction will be written */
-defvar("here", here, 0, &state_word);
+defvar("here", here, (value_t)Word_Buffer, &state_word);
+
+/** Read a character from the default input source */
+defcode("key", key, &here_word, 0u) {
+    onward_aspush(fetch_char());
+}
+
+/** Read a character from the default input source */
+defcode("emit", emit, &key, 0u) {
+    emit_char((int)onward_aspop());
+}
+
+/** Drop the rest of the current line from the default input source */
+defcode("\\", dropline, &emit, F_IMMEDIATE_MSK) {
+    int curr;
+    do {
+        ((primitive_t)key.code)();
+        curr = (int)onward_aspop();
+    } while(((char)curr != '\n') && (curr != EOF));
+}
 
 /** Fetches the next word from the input string */
-defcode("word", word, &here_word, 0u) {
+defcode("word", word, &dropline, 0u) {
     static char buffer[32u];
     char* str = buffer;
+    int curr;
     /* Skip any whitespace */
-    while(char_oneof(*((char*)input), " \t\r\n"))
-        input++;
+    do {
+        key_code();
+        curr = (int)onward_aspop();
+    } while (char_oneof((char)curr, " \t\r\n"));
     /* Copy characters into the buffer */
-    while((*((char*)input) != '\0') && !char_oneof(*((char*)input), " \t\r\n"))
-        *(str++) = *((char*)input++);
+    do {
+        *str++ = (char)curr;
+        key_code();
+        curr = (int)onward_aspop();
+    } while(((int)curr != EOF) && !char_oneof((char)curr, " \t\r\n"));
     /* Terminate the string */
     *str = '\0';
     /* Return the internal buffer */
     onward_aspush((value_t)buffer);
 }
 
-/** Ignore the rest of a given line of input */
-defcode("\\", dropline, &word, F_IMMEDIATE_MSK) {
-    input = (intptr_t)"";
-}
-
 /** Parses a string as a number literal */
-defcode("num", num, &dropline, 0u) {
+defcode("num", num, &word, 0u) {
     char* word = (char*)onward_aspop();
     char* start = word;
     value_t success = 0;
@@ -505,17 +524,6 @@ defcode("~", bnot, &bxor, 0u) {
 /* Helper C Functions
  *****************************************************************************/
 
-void onward_init(onward_init_t* init_data) {
-    asb    = (value_t)(init_data->arg_stack - 1);
-    asp    = (value_t)(init_data->arg_stack - 1);
-    assz   = (value_t)(init_data->arg_stack_sz * sizeof(value_t));
-    rsb    = (value_t)(init_data->ret_stack - 1);
-    rsp    = (value_t)(init_data->ret_stack - 1);
-    rssz   = (value_t)(init_data->ret_stack_sz * sizeof(value_t));
-    here   = (value_t)(init_data->word_buf);
-    latest = (value_t)(init_data->latest);
-}
-
 value_t onward_pcfetch(void) {
     value_t* reg = (value_t*)pc;
     value_t  val = *reg++;
index 50a2d553c85aa24790e2b812562b164aa3626f59..93b39fd580a2e1744e0145e7415d45fb8da5fe9a 100644 (file)
@@ -1,17 +1,15 @@
 : immediate
-    latest @        \ Get the latest word
-    CELLSZ +        \ Add offset to get to the flags field
-    dup @           \ Fetch the current value
-    F_IMMEDIATE | ! \ Set the immediate bit
+   latest @        \ Get the latest word
+   CELLSZ +        \ Add offset to get to the flags field
+   dup @           \ Fetch the current value
+   F_IMMEDIATE | ! \ Set the immediate bit
 ; immediate
 
-
 : [compile] immediate
     word find ,
 ;
 
 : #  [compile] \ ;
-
 : #! [compile] \ ;
 
 : recurse immediate
index 9f5a8447486599c6318b147b32693c6dbd4bcac4..e21135bd313a8a57d072c740c4a2f568513ca0e2 100755 (executable)
@@ -123,7 +123,6 @@ typedef struct {
 /** Macro that expands to the address of the latest built-in word */
 #define LATEST_BUILTIN (&bnot)
 
-void onward_init(onward_init_t* init_data);
 value_t onward_pcfetch(void);
 void onward_aspush(value_t val);
 value_t onward_aspeek(value_t val);
@@ -142,11 +141,12 @@ decvar(asb);
 decvar(asp);
 decvar(rsb);
 decvar(rsp);
-decvar(input);
-decvar(errno);
+decvar(errcode);
 decvar(latest);
 decvar(state);
 decvar(here);
+deccode(key);
+deccode(emit);
 deccode(word);
 deccode(dropline);
 deccode(num);
diff --git a/source/onward/onward_sys.h b/source/onward/onward_sys.h
new file mode 100644 (file)
index 0000000..622c3c9
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+  @file onward_sys.h
+  @brief TODO: Describe this file
+  $Revision$
+  $HeadURL$
+*/
+#ifndef ONWARD_SYS_H
+#define ONWARD_SYS_H
+
+#include "onward.h"
+
+#ifndef ARG_STACK_SZ
+#define ARG_STACK_SZ (64 * sizeof(value_t))
+#endif
+
+#ifndef RET_STACK_SZ
+#define RET_STACK_SZ (64 * sizeof(value_t))
+#endif
+
+#ifndef WORD_BUF_SZ
+#define WORD_BUF_SZ (8192 / sizeof(value_t))
+#endif
+
+value_t Argument_Stack[ARG_STACK_SZ];
+
+value_t Return_Stack[RET_STACK_SZ];
+
+value_t Word_Buffer[WORD_BUF_SZ];
+
+value_t fetch_char(void);
+
+void emit_char(value_t val);
+
+#endif /* ONWARD_SYS_H */
index 4972ea8c732b493c97d5b57279ebbe80fe005227..434aab91fd61b2719f85a1c14466d9b0f9d9dadd 100644 (file)
@@ -60,7 +60,7 @@ void syscall_free(void)
     free((void*)onward_aspop());
 }
 
-syscall_fn_t System_Calls[] = {
+syscall_fn_t System_Calls[7] = {
     /* File Operations */
     &syscall_open,
     &syscall_close,
index 53ece86bb1bace4a8a85286ef48216899cee3d8d..b244f33734417b71e906868a5dd9dc0e3bda72c6 100644 (file)
@@ -9,6 +9,6 @@
 
 typedef void (*syscall_fn_t)(void);
 
-syscall_fn_t System_Calls[];
+syscall_fn_t System_Calls[7];
 
 #endif /* SYCALL_H */
index a12b256841cee529656d5fdf9c68ea1d49f2bc61..29d725569c820e5e0af012a6d7b17537cb852eb9 100755 (executable)
@@ -1,24 +1,26 @@
 #include "atf.h"
 #include "onward.h"
 
-static value_t Arg_Stack_Buf[32u];
-static value_t Ret_Stack_Buf[32u];
-static value_t Ram_Data_Buf[8192/sizeof(value_t)];
+char* input = "";
+value_t Word_Buffer[1024 / sizeof(value_t)];
+
+value_t fetch_char(void)
+{
+    return (value_t)*input++;
+}
+
+void emit_char(value_t val)
+{
+    (void)val;
+}
 
 void state_reset(void) {
     /* Initialize the system */
-    onward_init_t init_data = {
-        Arg_Stack_Buf,
-        32u,
-        Ret_Stack_Buf,
-        32u,
-        Ram_Data_Buf,
-        8192/sizeof(value_t),
-        (word_t*)LATEST_BUILTIN
-    };
-    onward_init(&init_data);
-    errno = 0;
+    asp = asb;
+    rsp = rsb;
+    errcode = 0;
     state = 0;
+    here = (value_t)Word_Buffer;
 }
 
 int main(int argc, char** argv)
index c33241028d546fec55f9f53d5c2d4595a6bfef9c..8bf701b5fd441de64d2f6007dbf32efcf770ac29 100644 (file)
@@ -5,6 +5,8 @@
 // File To Test
 #include "onward.h"
 
+extern char* input;
+
 void state_reset(void);
 
 //-----------------------------------------------------------------------------
@@ -17,7 +19,7 @@ TEST_SUITE(Interpreter) {
     TEST(Verify_word_reads_the_next_word_and_places_it_on_the_stack)
     {
         state_reset();
-        input = (intptr_t)" foo ";
+        input = " foo ";
         ((primitive_t)word.code)();
         char* result = (char*)onward_aspop();
         CHECK(0 == strcmp(result, "foo"));
@@ -29,7 +31,7 @@ TEST_SUITE(Interpreter) {
     TEST(Verify_dropline_drops_the_rest_of_the_given_input)
     {
         state_reset();
-        input = (intptr_t)" foo ";
+        input = " foo \n\0";
         ((primitive_t)dropline.code)();
         CHECK(0 == strcmp((char*)input, ""));
     }
@@ -308,10 +310,11 @@ TEST_SUITE(Interpreter) {
     //-------------------------------------------------------------------------
     // Testing: :
     //-------------------------------------------------------------------------
+#if 1
     TEST(Verify_colon_creates_a_new_word_and_switches_to_compile_mode)
     {
         state_reset();
-        input = (intptr_t)" foo ";
+        input = " foo ";
         onward_aspush((intptr_t)&colon);
         ((primitive_t)exec.code)();
         word_t* old_word = (word_t*)latest;
@@ -324,10 +327,12 @@ TEST_SUITE(Interpreter) {
         CHECK(0 == *(intptr_t*)here);
         CHECK(1 == state);
     }
+#endif
 
     //-------------------------------------------------------------------------
     // Testing: '
     //-------------------------------------------------------------------------
+#if 1
     TEST(Verify_tick_fetches_next_instruction_and_places_it_on_the_stack)
     {
         state_reset();
@@ -371,6 +376,7 @@ TEST_SUITE(Interpreter) {
         ((primitive_t)zbr.code)();
         CHECK((intptr_t)&code[1] == pc);
     }
+#endif
 
     //-------------------------------------------------------------------------
     // Testing: interp
index 312e06ef01b05012afdece271c4195b07c7d5644..6f834b0b04a3433d3ad1461edb6bdfbad4a87dd4 100755 (executable)
@@ -4,6 +4,8 @@
 // File To Test
 #include "onward.h"
 
+extern char* input;
+
 void state_reset(void);
 
 static intptr_t get_const(const word_t* word) {
@@ -39,8 +41,7 @@ TEST_SUITE(Constants_And_Variables) {
         CHECK(is_var(&asp, &asp_word));
         CHECK(is_var(&rsb, &rsb_word));
         CHECK(is_var(&rsp, &rsp_word));
-        CHECK(is_var(&input, &input_word));
-        CHECK(is_var(&errno, &errno_word));
+    //    CHECK(is_var(&errcode, &errcode_word));
         CHECK(is_var(&latest, &latest_word));
         CHECK(is_var(&state, &state_word));
         CHECK(is_var(&here, &here_word));