moved buffer into heap, prep to remove substates
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
#ifndef FORTH_FH_MEM_H
|
||||
#define FORTH_FH_MEM_H
|
||||
|
||||
void fh_fill_input_buffer(struct fh_thread_s *fh, const char *data, size_t num);
|
||||
|
||||
void fh_align(struct fh_thread_s *fh);
|
||||
|
||||
void fh_setbase(struct fh_thread_s *fh, uint32_t base);
|
||||
|
||||
@@ -148,6 +148,11 @@ struct fh_thread_s {
|
||||
/** Address of the last dict word */
|
||||
uint32_t dict_last;
|
||||
|
||||
/** Input buffer parse position */
|
||||
uint32_t inputptr;
|
||||
/** Input buffer total content size */
|
||||
uint32_t inputlen;
|
||||
|
||||
/** Forth state */
|
||||
enum fh_state state;
|
||||
|
||||
@@ -158,6 +163,10 @@ struct fh_thread_s {
|
||||
uint32_t base;
|
||||
};
|
||||
|
||||
#define HEAP_END (HEAP_SIZE - WORDBUF_SIZE - INPUT_BUFFER_SIZE)
|
||||
#define WORDBUF_ADDR HEAP_END
|
||||
#define INPUTBUF_ADDR (HEAP_END + WORDBUF_SIZE)
|
||||
|
||||
enum fh_error fh_add_word(const struct fh_word_s *w, struct fh_thread_s *fh);
|
||||
|
||||
void fh_setstate(struct fh_thread_s *fh, enum fh_state state, enum fh_substate substate);
|
||||
|
||||
+1
-1
@@ -16,6 +16,6 @@
|
||||
struct fh_thread_s;
|
||||
|
||||
enum fh_error fh_init(struct fh_thread_s *fh);
|
||||
enum fh_error fh_process_line(struct fh_thread_s *fh, const char *linebuf);
|
||||
enum fh_error fh_process_line(struct fh_thread_s *fh, const char *linebuf, size_t len);
|
||||
|
||||
#endif //FORTH_H
|
||||
|
||||
+1
-1
@@ -992,7 +992,7 @@ static enum fh_error w_pad(struct fh_thread_s *fh, const struct fh_word_s *w)
|
||||
(void) w;
|
||||
enum fh_error rv;
|
||||
uint32_t addr = fh->here + PAD_OFFSET;
|
||||
if (addr + 84 >= HEAP_SIZE) {
|
||||
if (addr + 84 >= HEAP_END) {
|
||||
LOGE("Heap overflow, PAD is too small!");
|
||||
return FH_ERR_HEAP_FULL;
|
||||
}
|
||||
|
||||
+21
-3
@@ -1,10 +1,23 @@
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "fh_print.h"
|
||||
#include "fh_error.h"
|
||||
#include "fh_runtime.h"
|
||||
#include "fh_mem.h"
|
||||
|
||||
// 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!
|
||||
|
||||
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)
|
||||
{
|
||||
fh->here = WORDALIGNED(fh->here);
|
||||
@@ -102,7 +115,7 @@ enum fh_error fh_heap_reserve(
|
||||
{
|
||||
uint32_t p = fh->here;
|
||||
|
||||
if (p + len > HEAP_SIZE) {
|
||||
if (p + len > HEAP_END) {
|
||||
return FH_ERR_HEAP_FULL;
|
||||
}
|
||||
|
||||
@@ -121,6 +134,11 @@ enum fh_error fh_heap_reserve(
|
||||
/** Write bytes to heap at a given location. The region must have been previously allocated! */
|
||||
void fh_heap_write(struct fh_thread_s *fh, uint32_t addr, const void *src, uint32_t len)
|
||||
{
|
||||
if (addr > HEAP_SIZE) {
|
||||
LOGE("Attempted write past end of heap");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&fh->heap[addr], src, len);
|
||||
}
|
||||
|
||||
@@ -149,14 +167,14 @@ char *fh_str_at(struct fh_thread_s *fh, uint32_t addr) {
|
||||
}
|
||||
|
||||
struct fh_instruction_s *fh_instr_at(struct fh_thread_s *fh, uint32_t addr) {
|
||||
if (addr >= HEAP_SIZE) {
|
||||
if (addr >= HEAP_END) {
|
||||
LOGE("fh_instr_at out of bounds!");
|
||||
}
|
||||
return (void *) &fh->heap[addr];
|
||||
}
|
||||
|
||||
struct fh_word_s *fh_word_at(struct fh_thread_s *fh, uint32_t addr) {
|
||||
if (addr >= HEAP_SIZE) {
|
||||
if (addr >= HEAP_END) {
|
||||
LOGE("fh_word_at out of bounds!");
|
||||
}
|
||||
return (struct fh_word_s *) &fh->heap[addr];
|
||||
|
||||
+18
-7
@@ -233,6 +233,7 @@ static enum fh_error fh_handle_quoted_string(
|
||||
if (fh->state == FH_STATE_INTERPRET) {
|
||||
switch (fh->substate) {
|
||||
case FH_SUBSTATE_S_QUOTE:
|
||||
addr = fh->here;
|
||||
TRY(fh_heap_put(fh, start, len));
|
||||
TRY(ds_push(fh, addr));
|
||||
TRY(ds_push(fh, len));
|
||||
@@ -461,27 +462,36 @@ static inline bool isnl(char c)
|
||||
}
|
||||
|
||||
/** Process a line read from input */
|
||||
enum fh_error fh_process_line(struct fh_thread_s *fh, const char *linebuf)
|
||||
enum fh_error fh_process_line(struct fh_thread_s *fh, const char *linebuf, size_t len)
|
||||
{
|
||||
enum fh_error rv;
|
||||
const char *rp = linebuf;
|
||||
|
||||
#define ReadPtr ((char*)(&fh->heap[INPUTBUF_ADDR + fh->inputptr]))
|
||||
#define ReadPos (fh->inputptr)
|
||||
#define ReadLen (fh->inputlen)
|
||||
|
||||
fh_fill_input_buffer(fh, linebuf, len);
|
||||
|
||||
char c;
|
||||
|
||||
if (!fh_globals.interactive) {
|
||||
LOGI("%s", linebuf);
|
||||
}
|
||||
|
||||
while (0 != (c = *rp) && fh->state != FH_STATE_SHUTDOWN) {
|
||||
while (ReadPos < ReadLen && fh->state != FH_STATE_SHUTDOWN) {
|
||||
c = *ReadPtr;
|
||||
/* end on newline */
|
||||
if (isnl(c)) {
|
||||
goto done;
|
||||
}
|
||||
/* skip whitespace */
|
||||
if (isspace(c)) {
|
||||
rp++;
|
||||
ReadPos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const char * const rp = ReadPtr;
|
||||
|
||||
char *end;
|
||||
size_t length;
|
||||
switch (fh->substate) {
|
||||
@@ -520,7 +530,7 @@ enum fh_error fh_process_line(struct fh_thread_s *fh, const char *linebuf)
|
||||
}
|
||||
|
||||
if (end) {
|
||||
rp = end + 1;
|
||||
ReadPos += length + 1;
|
||||
} else {
|
||||
goto done;
|
||||
}
|
||||
@@ -534,7 +544,7 @@ enum fh_error fh_process_line(struct fh_thread_s *fh, const char *linebuf)
|
||||
LOG("Quoted string: \"%.*s\"", (int) length, rp);
|
||||
TRY(fh_handle_quoted_string(fh, rp, length));
|
||||
fh_setsubstate(fh, FH_SUBSTATE_NONE);
|
||||
rp = end + 1;
|
||||
ReadPos += length + 1;
|
||||
} else {
|
||||
/* no end. this is weird. */
|
||||
LOGE("Unterminated quoted string!");
|
||||
@@ -545,9 +555,10 @@ enum fh_error fh_process_line(struct fh_thread_s *fh, const char *linebuf)
|
||||
case FH_SUBSTATE_PAREN_COMMENT:
|
||||
end = strchr(rp, ')');
|
||||
if (end) {
|
||||
length = end - rp;
|
||||
LOG("Discard inline comment");
|
||||
fh_setsubstate(fh, FH_SUBSTATE_NONE);
|
||||
rp = end + 1;
|
||||
ReadPos += length + 1;
|
||||
} else {
|
||||
/* no end, discard all */
|
||||
LOGE("Unterminated parenthesis comment");
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ int main(int argc, char *argv[])
|
||||
continue;
|
||||
}
|
||||
|
||||
rv = fh_process_line(&fh, linebuf);
|
||||
rv = fh_process_line(&fh, linebuf, strlen(linebuf));
|
||||
if (rv == FH_OK) {
|
||||
FHPRINT_SVC(" ok\n");
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user