From: David Given Date: Tue, 14 Jul 2015 19:34:56 +0000 (+0200) Subject: Many fixes; now prints the prompt and gets as far as reading text from X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=223cb32e563d3c60e48f30f935f0826312d7a204;p=FUZIX.git Many fixes; now prints the prompt and gets as far as reading text from the user. --- diff --git a/Applications/util/fforth.c b/Applications/util/fforth.c index a3547a92..39ca3984 100644 --- a/Applications/util/fforth.c +++ b/Applications/util/fforth.c @@ -100,7 +100,6 @@ static cell_t* dsp; static cell_t rstack[RSTACKSIZE]; static cell_t* rsp; -static char pad[MAX_LINE_LENGTH]; static char tib[MAX_LINE_LENGTH]; static cell_t tib_h = MAX_LINE_LENGTH; static cell_t tibo = 0; @@ -160,9 +159,9 @@ static void rpush(cell_t val) static cell_t rpop(void) { - if (dsp == &dstack[0]) + if (rsp == &rstack[0]) panic("return stack underflow"); - return *--dsp; + return *--rsp; } static void* claim_workspace(size_t length) @@ -199,24 +198,19 @@ static void codeword(cdefn_t* w) pc = (void*) w->payload; } -static void sysvarword(cdefn_t* w) -{ - dpush((cell_t) w->payload); -} - -static void indvarword(cdefn_t* w) -{ - cell_t* p = (void*) dpop(); - dpush(*p); -} - -static void varword(cdefn_t* w) -{ - dpush((cell_t) &w->payload); -} +static void rvarword(cdefn_t* w) { dpush((cell_t) w->payload); } +static void wvarword(defn_t* w) { w->payload = (void*) dpop(); } +static void rivarword(cdefn_t* w) { dpush(*(cell_t*) w->payload); } +static void wivarword(cdefn_t* w) { *(cell_t*)w->payload = dpop(); } /* Forward declarations of words go here --- do not edit.*/ //@EXPORT{ +static cdefn_t _exit_word; +static cdefn_t _fputc_word; +static cdefn_t _fwrite_word; +static cdefn_t _stderr_word; +static cdefn_t _stdin_word; +static cdefn_t _stdout_word; static cdefn_t accept_word; static cdefn_t add_word; static cdefn_t allot_word; @@ -236,8 +230,6 @@ static cdefn_t dot_quote_rword; static cdefn_t emit_word; static cdefn_t execute_word; static cdefn_t exit_word; -static cdefn_t fputc_word; -static cdefn_t fwrite_word; static cdefn_t here_word; static cdefn_t in_a_word; static cdefn_t latest_word; @@ -249,16 +241,12 @@ static cdefn_t pad_word; static cdefn_t pling_word; static cdefn_t pop_word; static cdefn_t quit_word; -static cdefn_t return_word; static cdefn_t rsp0_word; static cdefn_t rsp_at_word; static cdefn_t rsp_pling_word; static cdefn_t sp0_word; static cdefn_t sp_at_word; static cdefn_t sp_pling_word; -static cdefn_t stderr_word; -static cdefn_t stdin_word; -static cdefn_t stdout_word; static cdefn_t sub_word; static cdefn_t tib_h_word; static cdefn_t tib_word; @@ -266,12 +254,12 @@ static cdefn_t type_word; static cdefn_t zero_word; //@EXPORT} -static void fwrite_cb(cdefn_t* w) +static void _fwrite_cb(cdefn_t* w) { FILE* fp = (FILE*)dpop(); - size_t n = dpop(); + size_t len = dpop(); void* ptr = (void*)dpop(); - dpush(fwrite(ptr, 1, n, fp)); + dpush(fwrite(ptr, 1, len, fp)); } static void accept_cb(cdefn_t* w) @@ -303,96 +291,95 @@ static void dot_quote_rcb(cdefn_t* w) pc = alignup(ptr+len+1); } +static void _exit_cb(cdefn_t* w) { exit(dpop()); } +static void _fputc_cb(cdefn_t* w) { FILE* fp = (FILE*)dpop(); fputc(dpop(), fp); } static void add_cb(cdefn_t* w) { dpush(dpop() + dpop()); } static void allot_cb(cdefn_t* w) { claim_workspace(dpop()); } static void at_cb(cdefn_t* w) { dpush(*(cell_t*)dpop()); } +static void branch_cb(cdefn_t* w) { pc = (void*) *pc; } +static void branchif_cb(cdefn_t* w) { if (dpop() == (cell_t)w->payload) pc = (void*)*pc; else pc++; } static void c_at_cb(cdefn_t* w) { dpush(*(uint8_t*)dpop()); } static void c_pling_cb(cdefn_t* w) { uint8_t* p = (uint8_t*)dpop(); *p = dpop(); } static void div_cb(cdefn_t* w) { cell_t a = dpop(); cell_t b = dpop(); dpush(b / a); } static void execute_cb(cdefn_t* w) { cdefn_t* p = (void*) dpop(); codeword(p); } -static void exit_cb(cdefn_t* w) { exit(dpop()); } -static void fputc_cb(cdefn_t* w) { FILE* fp = (FILE*)dpop(); fputc(dpop(), fp); } -static void here_cb(cdefn_t* w) { dpush((cell_t) here); } +static void exit_cb(cdefn_t* w) { pc = (void*)rpop(); } static void lit_cb(cdefn_t* w) { dpush((cell_t) *pc++); } static void mul_cb(cdefn_t* w) { dpush(dpop() * dpop()); } -static void pad_cb(cdefn_t* w) { dpush((cell_t) pad); } static void pling_cb(cdefn_t* w) { cell_t* p = (cell_t*)dpop(); *p = dpop(); } static void pop_cb(cdefn_t* w) { dpop(); } -static void return_cb(cdefn_t* w) { pc = (void*) rpop(); } static void sub_cb(cdefn_t* w) { cell_t a = dpop(); cell_t b = dpop(); dpush(b - a); } -static void branchif_cb(cdefn_t* w) { void* iftrue = (void*) *pc++; if (dpop() == (cell_t)w->payload) pc = iftrue; } -static void branch_cb(cdefn_t* w) { pc = (void*) *pc; } -static void sp_pling_cb(cdefn_t* w) { dsp = (void*)dpop(); } -static void rsp_pling_cb(cdefn_t* w) { rsp = (void*)dpop(); } static cdefn_t* bye_ops[] = { &zero_word, &exit_word }; static cdefn_t* c_comma_ops[] = { &here_word, &c_pling_word, &one_word, &allot_word, &exit_word }; static cdefn_t* cells_ops[] = { &cell_word, &mul_word, &exit_word }; static cdefn_t* comma_ops[] = { &here_word, &pling_word, &cell_word, &allot_word, &exit_word }; -static cdefn_t* emit_ops[] = { &stdout_word, &fputc_word, &exit_word }; -static cdefn_t* type_ops[] = { &stdout_word, &fwrite_word, &pop_word, &exit_word }; +static cdefn_t* emit_ops[] = { &_stdout_word, &_fputc_word, &exit_word }; +static cdefn_t* type_ops[] = { &_stdout_word, &_fwrite_word, &pop_word, &exit_word }; +static const char prompt_msg[4] = " ok\n"; static cdefn_t* quit_ops[] = { /* Reset stacks. */ &sp0_word, &sp_pling_word, &rsp0_word, &rsp_pling_word, + /* Display the prompt. */ + &lit_word, (void*)prompt_msg, &lit_word, (void*)4, &type_word, /* Read a line from the terminal. */ &tib_word, &tib_h_word, &accept_word, /* And go round again */ - &branch_word, (void*)quit_ops + &branch_word, (void*)(quit_ops+4) }; /* List of words go here. To add a word, add a new entry and run this file as * a shell script. The link field will be set correctly. * BEWARE: these lines are parsed using whitespace. LEAVE EXACTLY AS IS.*/ -static cdefn_t accept_word = { accept_cb, "accept", NULL, NULL }; //@W +static cdefn_t _exit_word = { _exit_cb, "_exit", NULL, NULL }; //@W +static cdefn_t _fputc_word = { _fputc_cb, "_fputc", &_exit_word, NULL }; //@W +static cdefn_t _fwrite_word = { _fwrite_cb, "_fwrite", &_fputc_word, NULL }; //@W +static cdefn_t _stderr_word = { rivarword, "_stderr", &_fwrite_word, &stderr, }; //@W +static cdefn_t _stdin_word = { rivarword, "_stdin", &_stderr_word, &stdin, }; //@W +static cdefn_t _stdout_word = { rivarword, "_stdout", &_stdin_word, &stdout, }; //@W +static cdefn_t accept_word = { accept_cb, "accept", &_stdout_word, NULL }; //@W static cdefn_t add_word = { add_cb, "+", &accept_word, NULL }; //@W static cdefn_t allot_word = { allot_cb, "allot", &add_word, NULL, }; //@W static cdefn_t at_word = { at_cb, "@", &allot_word, NULL }; //@W -static cdefn_t base_word = { sysvarword, "base", &at_word, &base }; //@W +static cdefn_t base_word = { rvarword, "base", &at_word, &base }; //@W static cdefn_t branch_word = { branch_cb, NULL, &base_word, (void*)0 }; //@W static cdefn_t branchif_word = { branchif_cb, NULL, &branch_word, (void*)0 }; //@W static cdefn_t bye_word = { codeword, "bye", &branchif_word, bye_ops, }; //@W static cdefn_t c_at_word = { c_at_cb, "c@", &bye_word, NULL }; //@W static cdefn_t c_comma_word = { codeword, "c,", &c_at_word, c_comma_ops, }; //@W static cdefn_t c_pling_word = { c_pling_cb, "c!", &c_comma_word, NULL }; //@W -static cdefn_t cell_word = { sysvarword, "cell", &c_pling_word, (void*)CELL, }; //@W +static cdefn_t cell_word = { rvarword, "cell", &c_pling_word, (void*)CELL, }; //@W static cdefn_t cells_word = { codeword, "cells", &cell_word, cells_ops, }; //@W static cdefn_t comma_word = { codeword, ",", &cells_word, comma_ops, }; //@W static cdefn_t div_word = { div_cb, "/", &comma_word, NULL }; //@W static cdefn_t dot_quote_rword = { dot_quote_rcb, NULL, &div_word, NULL }; //@W static cdefn_t emit_word = { codeword, "emit", &dot_quote_rword, emit_ops }; //@W static cdefn_t execute_word = { execute_cb, "execute", &emit_word, NULL }; //@W -static cdefn_t exit_word = { exit_cb, "_exit", &execute_word, NULL }; //@W -static cdefn_t fputc_word = { fputc_cb, "_fwrite", &exit_word, NULL }; //@W -static cdefn_t fwrite_word = { fwrite_cb, "_fwrite", &fputc_word, NULL }; //@W -static cdefn_t here_word = { here_cb, "here", &fwrite_word, NULL, }; //@W -static cdefn_t in_a_word = { sysvarword, ">in", &here_word, &tibo }; //@W -static cdefn_t latest_word = { indvarword, "latest", &in_a_word, &latest, }; //@W +static cdefn_t exit_word = { exit_cb, "exit", &execute_word, NULL }; //@W +static cdefn_t here_word = { rivarword, "here", &exit_word, &here }; //@W +static cdefn_t in_a_word = { rvarword, ">in", &here_word, &tibo }; //@W +static cdefn_t latest_word = { rivarword, "latest", &in_a_word, &latest, }; //@W static cdefn_t lit_word = { lit_cb, NULL, &latest_word, NULL, }; //@W -static cdefn_t m_one_word = { sysvarword, "-1", &lit_word, (void*)-1, }; //@W +static cdefn_t m_one_word = { rvarword, "-1", &lit_word, (void*)-1, }; //@W static cdefn_t mul_word = { mul_cb, "*", &m_one_word, NULL }; //@W -static cdefn_t one_word = { sysvarword, "1", &mul_word, (void*)1, }; //@W -static cdefn_t pad_word = { pad_cb, "pad", &one_word, NULL }; //@W +static cdefn_t one_word = { rvarword, "1", &mul_word, (void*)1, }; //@W +static cdefn_t pad_word = { rvarword, "pad", &one_word, &here }; //@W static cdefn_t pling_word = { pling_cb, "!", &pad_word, NULL }; //@W static cdefn_t pop_word = { pop_cb, "pop", &pling_word, NULL }; //@W static cdefn_t quit_word = { codeword, NULL, &pop_word, quit_ops }; //@W -static cdefn_t return_word = { return_cb, ";", &quit_word, NULL, }; //@W -static cdefn_t rsp0_word = { sysvarword, "rsp0", &return_word, rstack }; //@W -static cdefn_t rsp_at_word = { indvarword, "rsp@", &rsp0_word, &rsp }; //@W -static cdefn_t rsp_pling_word = { sp_pling_cb, "rsp!", &rsp_at_word, NULL }; //@W -static cdefn_t sp0_word = { sysvarword, "sp0", &rsp_pling_word, dstack }; //@W -static cdefn_t sp_at_word = { indvarword, "sp@", &sp0_word, &dsp }; //@W -static cdefn_t sp_pling_word = { sp_pling_cb, "sp!", &sp_at_word, NULL }; //@W -static cdefn_t stderr_word = { indvarword, "_stderr", &sp_pling_word, &stderr, }; //@W -static cdefn_t stdin_word = { indvarword, "_stdin", &stderr_word, &stdin, }; //@W -static cdefn_t stdout_word = { indvarword, "_stdout", &stdin_word, &stdout, }; //@W -static cdefn_t sub_word = { sub_cb, "-", &stdout_word, NULL }; //@W -static cdefn_t tib_h_word = { sysvarword, "tib#", &sub_word, &tib_h }; //@W -static cdefn_t tib_word = { sysvarword, "tib", &tib_h_word, tib }; //@W -static cdefn_t type_word = { codeword, "emit", &tib_word, type_ops }; //@W -static cdefn_t zero_word = { sysvarword, "0", &type_word, (void*)0, }; //@W +static cdefn_t rsp0_word = { rvarword, "rsp0", &quit_word, rstack }; //@W +static cdefn_t rsp_at_word = { rivarword, "rsp@", &rsp0_word, &rsp }; //@W +static cdefn_t rsp_pling_word = { wivarword, "rsp!", &rsp_at_word, &rsp }; //@W +static cdefn_t sp0_word = { rvarword, "sp0", &rsp_pling_word, dstack }; //@W +static cdefn_t sp_at_word = { rivarword, "sp@", &sp0_word, &dsp }; //@W +static cdefn_t sp_pling_word = { wivarword, "sp!", &sp_at_word, &dsp }; //@W +static cdefn_t sub_word = { sub_cb, "-", &sp_pling_word, NULL }; //@W +static cdefn_t tib_h_word = { rvarword, "tib#", &sub_word, &tib_h }; //@W +static cdefn_t tib_word = { rvarword, "tib", &tib_h_word, tib }; //@W +static cdefn_t type_word = { codeword, "type", &tib_word, type_ops }; //@W +static cdefn_t zero_word = { rvarword, "0", &type_word, (void*)0, }; //@W static cdefn_t* latest = &zero_word; //@E @@ -409,6 +396,7 @@ int main(int argc, const char* argv[]) for (;;) { const struct definition* w = (void*) *pc++; + //printf("[%s]\n", w->name); w->code(w); } }