moved buffer into heap, prep to remove substates

master
Ondřej Hruška 3 years ago
parent d79898fa20
commit 7f08e8717f
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 2
      include/fh_mem.h
  2. 9
      include/fh_runtime.h
  3. 2
      include/forth.h
  4. 2
      src/fh_builtins.c
  5. 24
      src/fh_mem.c
  6. 25
      src/fh_runtime.c
  7. 2
      src/main.c

@ -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);

@ -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

@ -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;
}

@ -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];

@ -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");

@ -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 {

Loading…
Cancel
Save