-#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();
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("");
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--) {
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) {
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]);
#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);
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;
/* 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++;
: 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
/** 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);
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);
--- /dev/null
+/**
+ @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 */
free((void*)onward_aspop());
}
-syscall_fn_t System_Calls[] = {
+syscall_fn_t System_Calls[7] = {
/* File Operations */
&syscall_open,
&syscall_close,
typedef void (*syscall_fn_t)(void);
-syscall_fn_t System_Calls[];
+syscall_fn_t System_Calls[7];
#endif /* SYCALL_H */
#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)
// File To Test
#include "onward.h"
+extern char* input;
+
void state_reset(void);
//-----------------------------------------------------------------------------
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"));
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, ""));
}
//-------------------------------------------------------------------------
// 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;
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();
((primitive_t)zbr.code)();
CHECK((intptr_t)&code[1] == pc);
}
+#endif
//-------------------------------------------------------------------------
// Testing: interp
// File To Test
#include "onward.h"
+extern char* input;
+
void state_reset(void);
static intptr_t get_const(const word_t* word) {
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));