evaluate implemented

master
Ondřej Hruška 3 years ago
parent ab1b39598c
commit d0cead3c42
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 2
      include/fh_builtins.h
  2. 2
      include/fh_input.h
  3. 2
      include/forth.h
  4. 2
      include/forth_internal.h
  5. 12
      src/fh_builtins_meta.c
  6. 10
      src/fh_builtins_text.c
  7. 20
      src/fh_input.c
  8. 5
      src/fh_parse.c

@ -35,6 +35,8 @@ extern const struct name_and_handler fh_builtins_meta[];
extern const struct name_and_handler fh_builtins_text[]; extern const struct name_and_handler fh_builtins_text[];
extern const struct name_and_handler fh_builtins_system[]; extern const struct name_and_handler fh_builtins_system[];
enum fh_error ds_pop_addr_len(struct fh_thread_s *fh, uint32_t *addr, uint32_t *len);
enum fh_error wp_const(struct fh_thread_s *fh, const struct fh_word_s *w); enum fh_error wp_const(struct fh_thread_s *fh, const struct fh_word_s *w);
enum fh_error wp_mul(struct fh_thread_s *fh, const struct fh_word_s *w); enum fh_error wp_mul(struct fh_thread_s *fh, const struct fh_word_s *w);

@ -25,6 +25,8 @@ struct fh_input_spec_s {
char saved_buffer[INPUT_BUFFER_SIZE]; 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;
enum fh_state saved_state;
}; };
/** /**

@ -14,8 +14,8 @@
#include "fh_config.h" #include "fh_config.h"
#include "fh_error.h" #include "fh_error.h"
#include "fh_globals.h" #include "fh_globals.h"
#include "fh_input.h"
#include "fh_runtime.h" #include "fh_runtime.h"
#include "fh_input.h"
#include "fh_print.h" #include "fh_print.h"
#endif //FORTH_H #endif //FORTH_H

@ -23,8 +23,8 @@
#include "fh_helpers.h" #include "fh_helpers.h"
#include "fh_globals.h" #include "fh_globals.h"
#include "fh_print.h" #include "fh_print.h"
#include "fh_input.h"
#include "fh_runtime.h" #include "fh_runtime.h"
#include "fh_input.h"
#include "fh_mem.h" #include "fh_mem.h"
#include "fh_stack.h" #include "fh_stack.h"
#include "fh_parse.h" #include "fh_parse.h"

@ -595,6 +595,17 @@ static enum fh_error w_execute(struct fh_thread_s *fh, const struct fh_word_s *w
return FH_OK; return FH_OK;
} }
static enum fh_error w_evaluate(struct fh_thread_s *fh, const struct fh_word_s *w)
{
(void) w;
enum fh_error rv;
uint32_t 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));
return FH_OK;
}
static enum fh_error w_env_query(struct fh_thread_s *fh, const struct fh_word_s *w) static enum fh_error w_env_query(struct fh_thread_s *fh, const struct fh_word_s *w)
{ {
(void) w; (void) w;
@ -690,5 +701,6 @@ const struct name_and_handler fh_builtins_meta[] = {
{"environment?", w_env_query, 0, 0}, {"environment?", w_env_query, 0, 0},
{"marker", w_marker, 0, 0}, {"marker", w_marker, 0, 0},
{"compile,", w_compile_comma, 0, 0}, {"compile,", w_compile_comma, 0, 0},
{"evaluate", w_evaluate, 0, 0},
{ /* end marker */ } { /* end marker */ }
}; };

@ -1,6 +1,6 @@
#include "forth_internal.h" #include "forth_internal.h"
static enum fh_error pop_addr_len(struct fh_thread_s *fh, uint32_t *addr, uint32_t *len) enum fh_error ds_pop_addr_len(struct fh_thread_s *fh, uint32_t *addr, uint32_t *len)
{ {
enum fh_error rv; enum fh_error rv;
TRY(ds_pop(fh, len)); TRY(ds_pop(fh, len));
@ -121,7 +121,7 @@ static enum fh_error w_type(struct fh_thread_s *fh, const struct fh_word_s *w)
(void) w; (void) w;
enum fh_error rv; enum fh_error rv;
uint32_t count = 0, addr = 0; uint32_t count = 0, addr = 0;
TRY(pop_addr_len(fh, &addr, &count)); TRY(ds_pop_addr_len(fh, &addr, &count));
const char *str = fh_str_at(fh, addr); const char *str = fh_str_at(fh, addr);
if (!str) { return FH_ERR_INTERNAL; } if (!str) { return FH_ERR_INTERNAL; }
FHPRINT("%.*s", count, str); FHPRINT("%.*s", count, str);
@ -134,7 +134,7 @@ static enum fh_error w_fill(struct fh_thread_s *fh, const struct fh_word_s *w)
enum fh_error rv; enum fh_error rv;
uint32_t count = 0, addr = 0, ch; uint32_t count = 0, addr = 0, ch;
TRY(ds_pop(fh, &ch)); TRY(ds_pop(fh, &ch));
TRY(pop_addr_len(fh, &addr, &count)); TRY(ds_pop_addr_len(fh, &addr, &count));
const char *str = fh_str_at(fh, addr); const char *str = fh_str_at(fh, addr);
if (!str) { return FH_ERR_INTERNAL; } if (!str) { return FH_ERR_INTERNAL; }
if (count > 0) { if (count > 0) {
@ -415,7 +415,7 @@ static enum fh_error w_holds(struct fh_thread_s *fh, const struct fh_word_s *w)
(void) w; (void) w;
enum fh_error rv; enum fh_error rv;
uint32_t count = 0, addr = 0; uint32_t count = 0, addr = 0;
TRY(pop_addr_len(fh, &addr, &count)); TRY(ds_pop_addr_len(fh, &addr, &count));
const char *str = fh_str_at(fh, addr); const char *str = fh_str_at(fh, addr);
if (!str) { return FH_ERR_INTERNAL; } if (!str) { return FH_ERR_INTERNAL; }
@ -449,7 +449,7 @@ static enum fh_error w_to_number(struct fh_thread_s *fh, const struct fh_word_s
*/ */
uint32_t count = 0, addr = 0; uint32_t count = 0, addr = 0;
TRY(pop_addr_len(fh, &addr, &count)); TRY(ds_pop_addr_len(fh, &addr, &count));
const char *str = fh_str_at(fh, addr); const char *str = fh_str_at(fh, addr);
if (!str) { return FH_ERR_INTERNAL; } if (!str) { return FH_ERR_INTERNAL; }

@ -2,6 +2,8 @@
void fh_push_input(struct fh_thread_s *fh, struct fh_input_spec_s *newinput) void fh_push_input(struct fh_thread_s *fh, struct fh_input_spec_s *newinput)
{ {
LOG("--- Push input spec ---");
if (newinput == NULL) { if (newinput == NULL) {
LOGE("push input with NULL"); LOGE("push input with NULL");
return; return;
@ -19,13 +21,21 @@ void fh_push_input(struct fh_thread_s *fh, struct fh_input_spec_s *newinput)
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_state = fh->state;
oldinput->saved_execptr = fh->execptr;
newinput->previous = oldinput; newinput->previous = oldinput;
fh->inputlen = 0;
fh->inputptr = 0;
// fh_setstate(fh, FH_STATE_INTERPRET, 0);
fh->input = newinput; fh->input = newinput;
} }
void fh_pop_input(struct fh_thread_s *fh) void fh_pop_input(struct fh_thread_s *fh)
{ {
LOG("--- Pop input spec ---");
struct fh_input_spec_s *discarded = fh->input; struct fh_input_spec_s *discarded = fh->input;
fh->input = NULL; fh->input = NULL;
@ -38,6 +48,8 @@ void fh_pop_input(struct fh_thread_s *fh)
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_setstate(fh, restored->saved_state, 0);
if (discarded->free_self) { if (discarded->free_self) {
discarded->free_self(discarded); discarded->free_self(discarded);
@ -87,12 +99,13 @@ 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; 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);
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
@ -103,7 +116,7 @@ static bool str_refill(struct fh_thread_s *fh, struct fh_input_spec_s *spec)
{ {
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 = INPUTBUF_ADDR - fh->inputlen; 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;
@ -113,6 +126,9 @@ static bool str_refill(struct fh_thread_s *fh, struct fh_input_spec_s *spec)
} }
memcpy(wp, &fis->str[fis->readpos], space_left); memcpy(wp, &fis->str[fis->readpos], space_left);
*(wp + space_left) = 0;
fis->readpos += space_left;
fh->inputlen += space_left;
return true; return true;
} else { } else {
return false; return false;

@ -226,6 +226,7 @@ enum fh_error fh_process_line(struct fh_thread_s *fh);
enum fh_error fh_runtime_start(struct fh_thread_s *fh, struct fh_input_spec_s *input) enum fh_error fh_runtime_start(struct fh_thread_s *fh, struct fh_input_spec_s *input)
{ {
enum fh_error rv; enum fh_error rv;
void *original_input = fh->input;
fh_push_input(fh, input); fh_push_input(fh, input);
if (fh_globals.interactive) { if (fh_globals.interactive) {
@ -276,8 +277,8 @@ enum fh_error fh_runtime_start(struct fh_thread_s *fh, struct fh_input_spec_s *i
} else { } else {
LOG("Pop input"); LOG("Pop input");
fh_pop_input(fh); fh_pop_input(fh);
if (!fh->input) { if (fh->input == original_input || !fh->input) {
// we are done. // we are done
break; break;
} }
} }

Loading…
Cancel
Save