From 96d8dfe11e5418e2724f9f0e9ecfa67e5907a1b7 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 1 Dec 2014 20:56:08 -0500 Subject: [PATCH] Added key and emit words and reworked the kernel to use that instead of input --- source/main.c | 67 ++++++++++++++++++--------------- source/onward/onward.c | 76 +++++++++++++++++++++----------------- source/onward/onward.ft | 10 ++--- source/onward/onward.h | 6 +-- source/onward/onward_sys.h | 34 +++++++++++++++++ source/syscall.c | 2 +- source/syscall.h | 2 +- tests/main.c | 30 ++++++++------- tests/test_interpreter.c | 12 ++++-- tests/test_vars.c | 5 ++- 10 files changed, 151 insertions(+), 93 deletions(-) create mode 100644 source/onward/onward_sys.h diff --git a/source/main.c b/source/main.c index dfa4fad..6644411 100755 --- a/source/main.c +++ b/source/main.c @@ -1,12 +1,8 @@ -#include "onward.h" -#include +#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 +#include +#include 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]); diff --git a/source/onward/onward.c b/source/onward/onward.c index 2650e8c..d196df2 100755 --- a/source/onward/onward.c +++ b/source/onward/onward.c @@ -1,5 +1,7 @@ #include "onward.h" +#include "onward_sys.h" #include +#include 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++; diff --git a/source/onward/onward.ft b/source/onward/onward.ft index 50a2d55..93b39fd 100644 --- a/source/onward/onward.ft +++ b/source/onward/onward.ft @@ -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 diff --git a/source/onward/onward.h b/source/onward/onward.h index 9f5a844..e21135b 100755 --- a/source/onward/onward.h +++ b/source/onward/onward.h @@ -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 index 0000000..622c3c9 --- /dev/null +++ b/source/onward/onward_sys.h @@ -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 */ diff --git a/source/syscall.c b/source/syscall.c index 4972ea8..434aab9 100644 --- a/source/syscall.c +++ b/source/syscall.c @@ -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, diff --git a/source/syscall.h b/source/syscall.h index 53ece86..b244f33 100644 --- a/source/syscall.h +++ b/source/syscall.h @@ -9,6 +9,6 @@ typedef void (*syscall_fn_t)(void); -syscall_fn_t System_Calls[]; +syscall_fn_t System_Calls[7]; #endif /* SYCALL_H */ diff --git a/tests/main.c b/tests/main.c index a12b256..29d7255 100755 --- a/tests/main.c +++ b/tests/main.c @@ -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) diff --git a/tests/test_interpreter.c b/tests/test_interpreter.c index c332410..8bf701b 100644 --- a/tests/test_interpreter.c +++ b/tests/test_interpreter.c @@ -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 diff --git a/tests/test_vars.c b/tests/test_vars.c index 312e06e..6f834b0 100755 --- a/tests/test_vars.c +++ b/tests/test_vars.c @@ -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)); -- 2.52.0