Compare commits

..

No commits in common. 'b09bbc4afab9c8a52b7219a7b4cca6c313f9206b' and '5db9ae83d3e4f34e978d2fb36125162715aedeeb' have entirely different histories.

  1. 9
      include/fh_input.h
  2. 2
      include/fh_runtime.h
  3. 5
      src/fh_builtins_meta.c
  4. 139
      src/fh_input.c
  5. 9
      src/fh_mem.c
  6. 23
      src/fh_parse.c
  7. 3
      testfiles/combinedtest.f
  8. 7
      testfiles/rescan.f

@ -15,22 +15,15 @@ typedef bool (*fh_input_refill_t)(struct fh_thread_s *fh, struct fh_input_spec_s
/** Spec free func */ /** Spec free func */
typedef void (*fh_input_free_t)(void *spec); typedef void (*fh_input_free_t)(void *spec);
typedef void (*fh_input_start_t)(struct fh_thread_s *fh, struct fh_input_spec_s *spec);
typedef void (*fh_input_pushpop_t)(struct fh_thread_s *fh, struct fh_input_spec_s *spec);
struct fh_input_spec_s { struct fh_input_spec_s {
struct fh_input_spec_s *previous; struct fh_input_spec_s *previous;
fh_input_refill_t refill_input_buffer; fh_input_refill_t refill_input_buffer;
fh_input_start_t start;
fh_input_free_t free_self; fh_input_free_t free_self;
fh_input_pushpop_t push_prepare;
fh_input_pushpop_t pop_restore;
uint32_t linenum; uint32_t linenum;
char *cwd; // CWD of the input, used for relative includes. malloc'd (strdup) char *cwd; // CWD of the input, used for relative includes. malloc'd (strdup)
// saved values, filled when pushing // saved values, filled when pushing
uint32_t saved_inputaddr; char saved_buffer[INPUT_BUFFER_SIZE];
uint32_t saved_inputptr; uint32_t saved_inputptr;
uint32_t saved_inputlen; uint32_t saved_inputlen;
uint32_t saved_execptr; uint32_t saved_execptr;

@ -193,8 +193,6 @@ struct fh_thread_s {
/** Pictured numeric output buffer write cursor (used for prepend) */ /** Pictured numeric output buffer write cursor (used for prepend) */
uint32_t pictnumptr; uint32_t pictnumptr;
/** Start addr of the input string (SOURCE) */
uint32_t inputaddr;
/** Input buffer parse position */ /** Input buffer parse position */
uint32_t inputptr; uint32_t inputptr;
/** Input buffer total content size */ /** Input buffer total content size */

@ -295,8 +295,10 @@ static enum fh_error w_source(struct fh_thread_s *fh, const struct fh_word_s *w)
{ {
(void) w; (void) w;
enum fh_error rv; enum fh_error rv;
TRY(ds_push(fh, fh->inputaddr)); TRY(ds_push(fh, INPUTBUF_ADDR));
TRY(ds_push(fh, fh->inputlen)); TRY(ds_push(fh, fh->inputlen));
// TRY(ds_push(fh, INPUTBUF_ADDR + fh->inputptr));
// TRY(ds_push(fh, fh->inputlen - fh->inputptr));
return FH_OK; return FH_OK;
} }
@ -599,6 +601,7 @@ static enum fh_error w_evaluate(struct fh_thread_s *fh, const struct fh_word_s *
enum fh_error rv; enum fh_error rv;
uint32_t addr, count; uint32_t addr, count;
TRY(ds_pop_addr_len(fh, &addr, &count)); TRY(ds_pop_addr_len(fh, &addr, &count));
fh_runtime_start(fh, fh_create_input_from_string(fh_str_at(fh, addr), count, fh->input->cwd)); fh_runtime_start(fh, fh_create_input_from_string(fh_str_at(fh, addr), count, fh->input->cwd));
return FH_OK; return FH_OK;
} }

@ -13,17 +13,13 @@ enum fh_error fh_push_input(struct fh_thread_s *fh, struct fh_input_spec_s *newi
fh->input = NULL; fh->input = NULL;
if (NULL != oldinput) { if (NULL != oldinput) {
oldinput->push_prepare(fh, oldinput); memcpy(&oldinput->saved_buffer[0], &fh->heap[INPUTBUF_ADDR], INPUT_BUFFER_SIZE);
// memcpy(&oldinput->saved_buffer[0], &fh->heap[INPUTBUF_ADDR], INPUT_BUFFER_SIZE);
oldinput->saved_inputlen = fh->inputlen; oldinput->saved_inputlen = fh->inputlen;
oldinput->saved_inputptr = fh->inputptr; oldinput->saved_inputptr = fh->inputptr;
oldinput->saved_execptr = fh->execptr; oldinput->saved_execptr = fh->execptr;
oldinput->saved_inputaddr = fh->inputaddr;
newinput->previous = oldinput; newinput->previous = oldinput;
} }
fh->execptr = MAGICADDR_EXEC_INTERACTIVE;
fh->inputlen = 0; fh->inputlen = 0;
fh->inputptr = 0; fh->inputptr = 0;
@ -50,13 +46,10 @@ enum fh_error fh_pop_input(struct fh_thread_s *fh)
} }
fh->input = restored; // this can be NULL, that must be checked by caller. fh->input = restored; // this can be NULL, that must be checked by caller.
restored->pop_restore(fh, restored); memcpy(&fh->heap[INPUTBUF_ADDR], &restored->saved_buffer[0], INPUT_BUFFER_SIZE);
// memcpy(&fh->heap[INPUTBUF_ADDR], &restored->saved_buffer[0], INPUT_BUFFER_SIZE);
fh->inputlen = restored->saved_inputlen; fh->inputlen = restored->saved_inputlen;
fh->inputptr = restored->saved_inputptr; fh->inputptr = restored->saved_inputptr;
fh->execptr = restored->saved_execptr; fh->execptr = restored->saved_execptr;
fh->inputaddr = restored->saved_inputaddr;
// fh_setstate(fh, restored->saved_state, 0); // fh_setstate(fh, restored->saved_state, 0);
if (discarded->free_self) { if (discarded->free_self) {
@ -72,7 +65,6 @@ enum fh_error fh_pop_input(struct fh_thread_s *fh)
struct file_input_spec { struct file_input_spec {
struct fh_input_spec_s spec; struct fh_input_spec_s spec;
char saved_buffer[INPUT_BUFFER_SIZE];
FILE *file; FILE *file;
}; };
@ -80,31 +72,12 @@ struct string_input_spec {
struct fh_input_spec_s spec; struct fh_input_spec_s spec;
const char *str; const char *str;
size_t len; size_t len;
size_t readpos;
}; };
static void file_push_prepare(struct fh_thread_s *fh, struct fh_input_spec_s *spec)
{
struct file_input_spec *fspec = (void*) spec;
memcpy(&fspec->saved_buffer[0], &fh->heap[INPUTBUF_ADDR], INPUT_BUFFER_SIZE);
}
static void file_pop_restore(struct fh_thread_s *fh, struct fh_input_spec_s *spec)
{
struct file_input_spec *fspec = (void*) spec;
memcpy(&fh->heap[INPUTBUF_ADDR], &fspec->saved_buffer[0], INPUT_BUFFER_SIZE);
}
static void str_push_prepare(struct fh_thread_s *fh, struct fh_input_spec_s *spec)
{
}
static void str_pop_restore(struct fh_thread_s *fh, struct fh_input_spec_s *spec)
{
}
static inline uint8_t *inputbuf_at(struct fh_thread_s *fh, size_t pos) static inline uint8_t *inputbuf_at(struct fh_thread_s *fh, size_t pos)
{ {
return &fh->heap[fh->inputaddr + pos]; return &fh->heap[INPUTBUF_ADDR + pos];
} }
void fh_input_memmove_leftovers(struct fh_thread_s *fh) void fh_input_memmove_leftovers(struct fh_thread_s *fh)
@ -113,45 +86,33 @@ void fh_input_memmove_leftovers(struct fh_thread_s *fh)
// something is left // something is left
uint32_t remains = fh->inputlen - fh->inputptr; uint32_t remains = fh->inputlen - fh->inputptr;
if (remains > 0) { if (remains > 0) {
LOG("Refill, reuse %d bytes left in buffer", remains);
memmove(inputbuf_at(fh, 0), inputbuf_at(fh, fh->inputptr), remains); memmove(inputbuf_at(fh, 0), inputbuf_at(fh, fh->inputptr), remains);
fh->inputptr = 0; fh->inputptr = 0;
fh->inputlen = remains; fh->inputlen = remains;
} else { } else {
LOG("Refill, nothing reused (1)");
fh->inputptr = 0; fh->inputptr = 0;
fh->inputlen = 0; fh->inputlen = 0;
} }
} else { } else {
LOG("Refill, nothing reused (2)");
fh->inputptr = 0; fh->inputptr = 0;
fh->inputlen = 0; fh->inputlen = 0;
} }
} }
static void file_start(struct fh_thread_s *fh, struct fh_input_spec_s *spec)
{
fh->inputaddr = INPUTBUF_ADDR;
//
}
static void str_start(struct fh_thread_s *fh, struct fh_input_spec_s *spec)
{
struct string_input_spec *strspec = (struct string_input_spec *) spec;
fh->inputaddr = (void*)strspec->str - (void*)&fh->heap[0]; // XXX this will explode if string is not in the internal heap!
fh->inputlen = strspec->len;
fh->inputptr = 0;
}
static bool file_refill(struct fh_thread_s *fh, struct fh_input_spec_s *spec) static bool file_refill(struct fh_thread_s *fh, struct fh_input_spec_s *spec)
{ {
struct file_input_spec *fis = (struct file_input_spec *) spec; struct file_input_spec *fis = (struct file_input_spec *) spec;
fh_input_memmove_leftovers(fh); fh_input_memmove_leftovers(fh);
uint32_t space_left = INPUT_BUFFER_SIZE - fh->inputlen - 1; uint32_t space_left = INPUT_BUFFER_SIZE - fh->inputlen - 1;
char *wp = (char *) inputbuf_at(fh, fh->inputptr); char *wp = (char *) inputbuf_at(fh, fh->inputptr);
//LOG("spec %p, fgets %d", spec, space_left); LOG("spec %p, fgets %d", spec, space_left);
if (fgets(wp, (int) space_left, fis->file)) { if (fgets(wp, (int) space_left, fis->file)) {
spec->linenum++; spec->linenum++;
fh->inputlen = strnlen(wp, INPUT_BUFFER_SIZE); fh->inputlen = strnlen(wp, INPUT_BUFFER_SIZE);
wp[fh->inputlen] = 0; LOG("read %d bytes from file", fh->inputlen);
//LOG("read %d bytes from file", fh->inputlen);
return true; return true;
} else { } else {
return fh->inputptr > fh->inputlen; // return false only if there is nothing left return fh->inputptr > fh->inputlen; // return false only if there is nothing left
@ -160,26 +121,25 @@ static bool file_refill(struct fh_thread_s *fh, struct fh_input_spec_s *spec)
static bool str_refill(struct fh_thread_s *fh, struct fh_input_spec_s *spec) static bool str_refill(struct fh_thread_s *fh, struct fh_input_spec_s *spec)
{ {
return fh->inputptr < fh->inputlen; struct string_input_spec *fis = (struct string_input_spec *) spec;
// struct string_input_spec *fis = (struct string_input_spec *) spec; fh_input_memmove_leftovers(fh);
// fh_input_memmove_leftovers(fh); uint32_t space_left = INPUT_BUFFER_SIZE - fh->inputlen - 1;
// uint32_t space_left = INPUT_BUFFER_SIZE - fh->inputlen - 1; char *wp = (char *) inputbuf_at(fh, fh->inputptr);
// char *wp = (char *) inputbuf_at(fh, fh->inputptr);
// uint32_t chars_remaining_in_string = fis->len - fis->readpos;
// uint32_t chars_remaining_in_string = fis->len - fis->readpos; if (chars_remaining_in_string > 0) {
// if (chars_remaining_in_string > 0) { if (chars_remaining_in_string < space_left) {
// if (chars_remaining_in_string < space_left) { space_left = chars_remaining_in_string;
// space_left = chars_remaining_in_string; }
// }
// memcpy(wp, &fis->str[fis->readpos], space_left);
// memcpy(wp, &fis->str[fis->readpos], space_left); *(wp + space_left) = 0;
// *(wp + space_left) = 0; fis->readpos += space_left;
// fis->readpos += space_left; fh->inputlen += space_left;
// fh->inputlen += space_left; return true;
// return true; } else {
// } else { return false;
// return false; }
// }
} }
static void free_filespec(void *p) static void free_filespec(void *p)
@ -208,23 +168,19 @@ static void free_strspec(void *p)
struct fh_input_spec_s *fh_create_input_from_filestruct(FILE *f, const char *cwd) struct fh_input_spec_s *fh_create_input_from_filestruct(FILE *f, const char *cwd)
{ {
struct file_input_spec *spec = calloc(sizeof(struct file_input_spec), 1); struct file_input_spec *fis = calloc(sizeof(struct file_input_spec), 1);
if (!spec) { if (!fis) {
LOGE("Err alloc input spec struct"); LOGE("Err alloc input spec struct");
return NULL; return NULL;
} }
LOG("Input for FILE, cwd: %s", cwd); fis->spec.free_self = free_filespec;
spec->spec.free_self = free_filespec; fis->spec.refill_input_buffer = file_refill;
spec->spec.start = file_start; fis->file = f;
spec->spec.push_prepare = file_push_prepare;
spec->spec.pop_restore = file_pop_restore;
spec->spec.refill_input_buffer = file_refill;
spec->file = f;
if (cwd) { if (cwd) {
spec->spec.cwd = strdup(cwd); fis->spec.cwd = strdup(cwd);
} }
return (struct fh_input_spec_s*) spec; return (struct fh_input_spec_s*) fis;
} }
struct fh_input_spec_s *fh_create_input_from_filename(char *path) struct fh_input_spec_s *fh_create_input_from_filename(char *path)
@ -243,9 +199,6 @@ struct fh_input_spec_s *fh_create_input_from_filename(char *path)
} }
spec->spec.free_self = free_filespec; spec->spec.free_self = free_filespec;
spec->spec.start = file_start;
spec->spec.push_prepare = file_push_prepare;
spec->spec.pop_restore = file_pop_restore;
spec->spec.refill_input_buffer = file_refill; spec->spec.refill_input_buffer = file_refill;
spec->file = f; spec->file = f;
@ -263,22 +216,18 @@ struct fh_input_spec_s *fh_create_input_from_filename(char *path)
struct fh_input_spec_s *fh_create_input_from_string(char *str, size_t len, const char *cwd) struct fh_input_spec_s *fh_create_input_from_string(char *str, size_t len, const char *cwd)
{ {
struct string_input_spec *spec = calloc(sizeof(struct string_input_spec), 1); struct string_input_spec *sis = calloc(sizeof(struct string_input_spec), 1);
if (!spec) { if (!sis) {
return NULL; return NULL;
} }
LOG("Evaluating: \"%.*s\"", (int)len, str); sis->spec.free_self = free_strspec;
sis->spec.refill_input_buffer = str_refill;
spec->spec.free_self = free_strspec; sis->str = str;
spec->spec.refill_input_buffer = str_refill; sis->readpos = 0;
spec->spec.push_prepare = str_push_prepare; sis->len = len;
spec->spec.pop_restore = str_pop_restore; sis->spec.cwd = cwd ? strdup(cwd) : NULL;
spec->spec.start = str_start; return (struct fh_input_spec_s*) sis;
spec->str = str;
spec->len = len;
spec->spec.cwd = cwd ? strdup(cwd) : NULL;
return (struct fh_input_spec_s*) spec;
} }
void fh_input_teardown(struct fh_thread_s *fh) void fh_input_teardown(struct fh_thread_s *fh)

@ -3,6 +3,15 @@
// Important distinction: HEAP_END is the end of the normally addressable region. HEAP_SIZE is the full memory area. // Important distinction: HEAP_END is the end of the normally addressable region. HEAP_SIZE is the full memory area.
// Buffers are placed at the end of the heap! // Buffers are placed at the end of the heap!
void fh_fill_input_buffer(struct fh_thread_s *fh, const char *data, size_t num)
{
assert(num <= INPUT_BUFFER_SIZE);
memcpy(&fh->heap[INPUTBUF_ADDR], data, num);
fh->heap[INPUTBUF_ADDR + num] = 0; // terminator
fh->inputptr = 0;
fh->inputlen = num;
}
void fh_align(struct fh_thread_s *fh) void fh_align(struct fh_thread_s *fh)
{ {
fh->here = WORDALIGNED(fh->here); fh->here = WORDALIGNED(fh->here);

@ -63,7 +63,7 @@ enum fh_error fh_handle_ascii_word(
void fh_input_consume_matching(struct fh_thread_s *fh, chartest_t test, void *param) void fh_input_consume_matching(struct fh_thread_s *fh, chartest_t test, void *param)
{ {
char *rp = (char *) &fh->heap[fh->inputaddr + fh->inputptr]; char *rp = (char *) &fh->heap[INPUTBUF_ADDR + fh->inputptr];
while (test(*rp, param)) { while (test(*rp, param)) {
rp++; rp++;
fh->inputptr++; fh->inputptr++;
@ -72,7 +72,7 @@ void fh_input_consume_matching(struct fh_thread_s *fh, chartest_t test, void *pa
void fh_input_consume_spaces(struct fh_thread_s *fh) void fh_input_consume_spaces(struct fh_thread_s *fh)
{ {
char *rp = (char *) &fh->heap[fh->inputaddr + fh->inputptr]; char *rp = (char *) &fh->heap[INPUTBUF_ADDR + fh->inputptr];
while (isspace(*rp)) { while (isspace(*rp)) {
rp++; rp++;
fh->inputptr++; fh->inputptr++;
@ -81,9 +81,9 @@ void fh_input_consume_spaces(struct fh_thread_s *fh)
enum fh_error fh_input_read_delimited(struct fh_thread_s *fh, char **out, size_t *len, chartest_t test, void *param) enum fh_error fh_input_read_delimited(struct fh_thread_s *fh, char **out, size_t *len, chartest_t test, void *param)
{ {
char *rp = (char *) &fh->heap[fh->inputaddr + fh->inputptr]; char *rp = (char *) &fh->heap[INPUTBUF_ADDR + fh->inputptr];
char *start = rp; char *start = rp;
while (fh->inputptr < fh->inputlen) { while (1) {
char c = *rp; char c = *rp;
if (test(c, param)) { if (test(c, param)) {
if (rp == start) { if (rp == start) {
@ -98,9 +98,6 @@ enum fh_error fh_input_read_delimited(struct fh_thread_s *fh, char **out, size_t
rp++; rp++;
fh->inputptr++; fh->inputptr++;
} }
*out = start;
*len = rp - start;
return FH_OK;
} }
static bool chartest_space_or_end(char c, void *param) static bool chartest_space_or_end(char c, void *param)
@ -116,7 +113,7 @@ enum fh_error fh_input_read_word(struct fh_thread_s *fh, char **out, size_t *len
enum fh_error fh_input_read_quotedstring(struct fh_thread_s *fh, bool escaped, char *outbuf, size_t capacity, size_t *out_len) enum fh_error fh_input_read_quotedstring(struct fh_thread_s *fh, bool escaped, char *outbuf, size_t capacity, size_t *out_len)
{ {
char *rp = (char *) &fh->heap[fh->inputaddr + fh->inputptr]; char *rp = (char *) &fh->heap[INPUTBUF_ADDR + fh->inputptr];
bool next_escaped = false; bool next_escaped = false;
size_t remains = capacity; size_t remains = capacity;
size_t len = 0; size_t len = 0;
@ -236,14 +233,12 @@ enum fh_error fh_runtime_start(struct fh_thread_s *fh, struct fh_input_spec_s *i
FHPRINT("%s", FH_PROMPT_STR); FHPRINT("%s", FH_PROMPT_STR);
} }
input->start(fh, input);
while (1) { while (1) {
//LOG("Refill input buffer"); LOG("Refill input buffer");
if (fh->input->refill_input_buffer(fh, fh->input)) { if (fh->input->refill_input_buffer(fh, fh->input)) {
// discard spaces at the end // discard spaces at the end
while (isspace(fh->heap[fh->inputaddr + fh->inputlen - 1]) && fh->inputlen > 0) { while (isspace(fh->heap[INPUTBUF_ADDR + fh->inputlen - 1]) && fh->inputlen > 0) {
fh->heap[fh->inputaddr + fh->inputlen - 1] = 0; fh->heap[INPUTBUF_ADDR + fh->inputlen - 1] = 0;
fh->inputlen--; fh->inputlen--;
} }
@ -296,7 +291,7 @@ enum fh_error fh_process_line(struct fh_thread_s *fh)
{ {
enum fh_error rv; enum fh_error rv;
#define ReadPtr ((char*)(&fh->heap[fh->inputaddr + fh->inputptr])) #define ReadPtr ((char*)(&fh->heap[INPUTBUF_ADDR + fh->inputptr]))
#define ReadPos (fh->inputptr) #define ReadPos (fh->inputptr)
#define ReadLen (fh->inputlen) #define ReadLen (fh->inputlen)

@ -1049,7 +1049,6 @@ TESTING OUTPUT: . ." CR EMIT SPACE SPACES TYPE U.
T{ OUTPUT-TEST -> }T T{ OUTPUT-TEST -> }T
0 [if]
\ ------------------------------------------------------------------------ \ ------------------------------------------------------------------------
TESTING INPUT: ACCEPT TESTING INPUT: ACCEPT
@ -1063,7 +1062,6 @@ CREATE ABUF 50 CHARS ALLOT
; ;
T{ ACCEPT-TEST -> }T T{ ACCEPT-TEST -> }T
[then]
\ ------------------------------------------------------------------------ \ ------------------------------------------------------------------------
TESTING DICTIONARY SEARCH RULES TESTING DICTIONARY SEARCH RULES
@ -1588,7 +1586,6 @@ T{ 25 RN2 EXECUTE -> 33 22 11 0 }T
\ ----------------------------------------------------------------------------- \ -----------------------------------------------------------------------------
TESTING C" TESTING C"
1 debug
T{ : CQ1 C" 123" ; -> }T T{ : CQ1 C" 123" ; -> }T
T{ CQ1 COUNT EVALUATE -> 123 }T T{ CQ1 COUNT EVALUATE -> 123 }T
T{ : CQ2 C" " ; -> }T T{ : CQ2 C" " ; -> }T

@ -1,7 +0,0 @@
VARIABLE SCANS
: RESCAN? -1 SCANS +! SCANS @ IF 0 >IN ! THEN ;
1 debug
: GS2 1 SCANS ! S" 123 RESCAN?" EVALUATE ;
GS2
??
Loading…
Cancel
Save