@ -8,8 +8,11 @@
# include "fh_stack.h"
# include "fh_stack.h"
# include "fh_mem.h"
# include "fh_mem.h"
static enum fh_error w_add ( struct fh_thread_s * fh )
# define TOBOOL(a) (a == 0 ? 0 : 0xFFFFFFFF)
static enum fh_error w_plus ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
uint32_t a = 0 , b = 0 ;
uint32_t a = 0 , b = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
@ -18,8 +21,9 @@ static enum fh_error w_add(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_sub ( struct fh_thread_s * fh )
static enum fh_error w_minus ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
uint32_t a = 0 , b = 0 ;
uint32_t a = 0 , b = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
@ -28,8 +32,9 @@ static enum fh_error w_sub(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_mul ( struct fh_thread_s * fh )
static enum fh_error w_star ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
uint32_t a = 0 , b = 0 ;
uint32_t a = 0 , b = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
@ -38,8 +43,176 @@ static enum fh_error w_mul(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_colon ( struct fh_thread_s * fh )
static enum fh_error w_zero_less ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , TOBOOL ( a < 0 ) ) ) ;
return FH_OK ;
}
static enum fh_error w_zero_greater ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , TOBOOL ( a > 0 ) ) ) ;
return FH_OK ;
}
static enum fh_error w_zero_equals ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , TOBOOL ( a = = 0 ) ) ) ;
return FH_OK ;
}
static enum fh_error w_zero_not_equals ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , TOBOOL ( a ! = 0 ) ) ) ;
return FH_OK ;
}
static enum fh_error w_less ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 , b = 0 ;
TRY ( ds_pop ( fh , & b ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , TOBOOL ( a < b ) ) ) ;
return FH_OK ;
}
static enum fh_error w_greater ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 , b = 0 ;
TRY ( ds_pop ( fh , & b ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , TOBOOL ( a > b ) ) ) ;
return FH_OK ;
}
static enum fh_error w_equals ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 , b = 0 ;
TRY ( ds_pop ( fh , & b ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , TOBOOL ( a = = b ) ) ) ;
return FH_OK ;
}
static enum fh_error w_not_equals ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 , b = 0 ;
TRY ( ds_pop ( fh , & b ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , TOBOOL ( a ! = b ) ) ) ;
return FH_OK ;
}
static enum fh_error wp_add ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
enum fh_error rv ;
uint32_t a = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , a + w - > param ) ) ;
return FH_OK ;
}
static enum fh_error wp_mul ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
enum fh_error rv ;
uint32_t a = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , a * w - > param ) ) ;
return FH_OK ;
}
static enum fh_error wp_div ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
enum fh_error rv ;
uint32_t a = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , a * w - > param ) ) ;
return FH_OK ;
}
static enum fh_error w_star_slash ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 , b = 0 , c = 0 ;
TRY ( ds_pop ( fh , & c ) ) ;
TRY ( ds_pop ( fh , & b ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
if ( c = = 0 ) {
return FH_ERR_DIV_BY_ZERO ;
}
uint64_t v = ( ( uint64_t ) a * ( uint64_t ) b ) / ( uint64_t ) c ;
TRY ( ds_push ( fh , ( uint32_t ) v ) ) ;
return FH_OK ;
}
static enum fh_error w_slash ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 , b = 0 ;
TRY ( ds_pop ( fh , & b ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
if ( b = = 0 ) {
return FH_ERR_DIV_BY_ZERO ;
}
TRY ( ds_push ( fh , a / b ) ) ;
return FH_OK ;
}
static enum fh_error w_slash_mod ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 , b = 0 ;
TRY ( ds_pop ( fh , & b ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
if ( b = = 0 ) {
return FH_ERR_DIV_BY_ZERO ;
}
uint32_t rem = a % b ;
uint32_t div = a / b ;
TRY ( ds_push ( fh , rem ) ) ;
TRY ( ds_push ( fh , div ) ) ;
return FH_OK ;
}
static enum fh_error w_colon ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
if ( fh - > state ! = FH_STATE_INTERPRET ) {
if ( fh - > state ! = FH_STATE_INTERPRET ) {
return FH_ERR_INVALID_STATE ;
return FH_ERR_INVALID_STATE ;
}
}
@ -54,8 +227,9 @@ static enum fh_error w_colon(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_semicolon ( struct fh_thread_s * fh )
static enum fh_error w_semicolon ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
struct fh_instruction_s instr ;
struct fh_instruction_s instr ;
@ -73,8 +247,9 @@ static enum fh_error w_semicolon(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_dup ( struct fh_thread_s * fh )
static enum fh_error w_dup ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
uint32_t a = 0 ;
uint32_t a = 0 ;
TRY ( ds_peek ( fh , & a ) ) ;
TRY ( ds_peek ( fh , & a ) ) ;
@ -82,30 +257,76 @@ static enum fh_error w_dup(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_drop ( struct fh_thread_s * fh )
static enum fh_error w_two_dup ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 ;
uint32_t b = 0 ;
TRY ( ds_peek_n ( fh , & a , 0 ) ) ;
TRY ( ds_peek_n ( fh , & b , 1 ) ) ;
TRY ( ds_push ( fh , b ) ) ;
TRY ( ds_push ( fh , a ) ) ;
return FH_OK ;
}
static enum fh_error w_drop ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
return FH_OK ;
}
static enum fh_error w_two_drop ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
uint32_t a = 0 ;
uint32_t a = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_swap ( struct fh_thread_s * fh )
static enum fh_error w_swap ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
TRY ( ds_roll ( fh , 1 ) ) ;
TRY ( ds_roll ( fh , 1 ) ) ;
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_rot ( struct fh_thread_s * fh )
static enum fh_error w_two_swap ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
if ( fh - > data_stack_top < 4 ) {
LOG ( " DS two-swap UNDERFLOW " ) ;
return FH_ERR_DS_UNDERFLOW ;
}
uint32_t n = fh - > data_stack_top - 4 ;
uint32_t a = fh - > data_stack [ n ] ;
uint32_t b = fh - > data_stack [ n + 1 ] ;
fh - > data_stack [ n ] = fh - > data_stack [ n + 2 ] ;
fh - > data_stack [ n + 1 ] = fh - > data_stack [ n + 3 ] ;
fh - > data_stack [ n + 2 ] = a ;
fh - > data_stack [ n + 3 ] = b ;
return FH_OK ;
}
static enum fh_error w_rot ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
TRY ( ds_roll ( fh , 2 ) ) ;
TRY ( ds_roll ( fh , 2 ) ) ;
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_over ( struct fh_thread_s * fh )
static enum fh_error w_over ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
uint32_t a = 0 ;
uint32_t a = 0 ;
TRY ( ds_peek_n ( fh , & a , 1 ) ) ;
TRY ( ds_peek_n ( fh , & a , 1 ) ) ;
@ -113,8 +334,22 @@ static enum fh_error w_over(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_tuck ( struct fh_thread_s * fh )
static enum fh_error w_two_over ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
uint32_t a = 0 ;
uint32_t b = 0 ;
TRY ( ds_peek_n ( fh , & a , 2 ) ) ;
TRY ( ds_peek_n ( fh , & b , 3 ) ) ;
TRY ( ds_push ( fh , b ) ) ;
TRY ( ds_push ( fh , a ) ) ;
return FH_OK ;
}
static enum fh_error w_tuck ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
uint32_t a = 0 ;
uint32_t a = 0 ;
uint32_t b = 0 ;
uint32_t b = 0 ;
@ -126,8 +361,9 @@ static enum fh_error w_tuck(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_pick ( struct fh_thread_s * fh )
static enum fh_error w_pick ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
uint32_t nth = 0 ;
uint32_t nth = 0 ;
uint32_t a = 0 ;
uint32_t a = 0 ;
@ -137,8 +373,9 @@ static enum fh_error w_pick(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_roll ( struct fh_thread_s * fh )
static enum fh_error w_roll ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
uint32_t n = 0 ;
uint32_t n = 0 ;
TRY ( ds_pop ( fh , & n ) ) ;
TRY ( ds_pop ( fh , & n ) ) ;
@ -146,8 +383,78 @@ static enum fh_error w_roll(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_dot ( struct fh_thread_s * fh )
static enum fh_error w_to_r ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( rs_push ( fh , a ) ) ;
return FH_OK ;
}
static enum fh_error w_two_to_r ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a ;
uint32_t b ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_pop ( fh , & b ) ) ;
TRY ( rs_push ( fh , b ) ) ;
TRY ( rs_push ( fh , a ) ) ;
return FH_OK ;
}
static enum fh_error w_two_r_from ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a ;
uint32_t b ;
TRY ( rs_pop ( fh , & a ) ) ;
TRY ( rs_pop ( fh , & b ) ) ;
TRY ( ds_push ( fh , b ) ) ;
TRY ( ds_push ( fh , a ) ) ;
return FH_OK ;
}
static enum fh_error w_two_r_fetch ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a ;
uint32_t b ;
TRY ( rs_peek_n ( fh , & a , 0 ) ) ;
TRY ( rs_peek_n ( fh , & b , 1 ) ) ;
TRY ( ds_push ( fh , b ) ) ;
TRY ( ds_push ( fh , a ) ) ;
return FH_OK ;
}
static enum fh_error w_r_from ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a ;
TRY ( rs_pop ( fh , & a ) ) ;
TRY ( ds_push ( fh , a ) ) ;
return FH_OK ;
}
static enum fh_error w_r_fetch ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t a ;
TRY ( rs_peek ( fh , & a ) ) ;
TRY ( ds_push ( fh , a ) ) ;
return FH_OK ;
}
static enum fh_error w_dot ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
uint32_t a = 0 ;
uint32_t a = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_pop ( fh , & a ) ) ;
@ -156,8 +463,9 @@ static enum fh_error w_dot(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_type ( struct fh_thread_s * fh )
static enum fh_error w_type ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
enum fh_error rv ;
enum fh_error rv ;
uint32_t count = 0 , addr = 0 ;
uint32_t count = 0 , addr = 0 ;
TRY ( ds_pop ( fh , & count ) ) ;
TRY ( ds_pop ( fh , & count ) ) ;
@ -167,59 +475,167 @@ static enum fh_error w_type(struct fh_thread_s *fh)
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_cr ( struct fh_thread_s * fh )
static enum fh_error w_cr ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
( void ) fh ;
( void ) fh ;
FHPRINT ( " \n " ) ;
FHPRINT ( " \n " ) ;
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_space ( struct fh_thread_s * fh )
static enum fh_error w_space ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
( void ) fh ;
( void ) fh ;
FHPRINT ( " " ) ;
FHPRINT ( " " ) ;
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_dump ( struct fh_thread_s * fh )
static enum fh_error w_dump ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
( void ) fh ;
( void ) fh ;
FHPRINT ( " DS " ) ;
for ( int i = 0 ; i < fh - > data_stack_top ; i + + ) {
for ( int i = 0 ; i < fh - > data_stack_top ; i + + ) {
FHPRINT ( " %d " , fh - > data_stack [ i ] ) ;
FHPRINT ( " %d " , fh - > data_stack [ i ] ) ;
}
}
FHPRINT ( " \n RS " ) ;
for ( int i = 0 ; i < fh - > return_stack_top ; i + + ) {
FHPRINT ( " %d " , fh - > return_stack [ i ] ) ;
}
FHPRINT ( " \n " ) ;
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_s_quote ( struct fh_thread_s * fh )
static enum fh_error w_abort ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
fh - > data_stack_top = 0 ;
fh - > return_stack_top = 0 ;
fh - > state = FH_STATE_QUIT ;
return FH_OK ;
}
static enum fh_error w_quit ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
fh - > return_stack_top = 0 ;
fh - > state = FH_STATE_QUIT ;
return FH_OK ;
}
static enum fh_error w_s_quote ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
fh_setsubstate ( fh , FH_SUBSTATE_SQUOTE ) ;
fh_setsubstate ( fh , FH_SUBSTATE_SQUOTE ) ;
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_dot_quote ( struct fh_thread_s * fh )
static enum fh_error w_dot_quote ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
fh_setsubstate ( fh , FH_SUBSTATE_DOTQUOTE ) ;
fh_setsubstate ( fh , FH_SUBSTATE_DOTQUOTE ) ;
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_backslash ( struct fh_thread_s * fh )
static enum fh_error w_backslash ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
fh_setsubstate ( fh , FH_SUBSTATE_LINECOMMENT ) ;
fh_setsubstate ( fh , FH_SUBSTATE_LINECOMMENT ) ;
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_paren ( struct fh_thread_s * fh )
static enum fh_error w_paren ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
fh_setsubstate ( fh , FH_SUBSTATE_PARENCOMMENT ) ;
fh_setsubstate ( fh , FH_SUBSTATE_PARENCOMMENT ) ;
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error w_bye ( struct fh_thread_s * fh )
static enum fh_error w_bye ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
{
( void ) w ;
fh_setstate ( fh , FH_STATE_SHUTDOWN , 0 ) ;
fh_setstate ( fh , FH_STATE_SHUTDOWN , 0 ) ;
return FH_OK ;
return FH_OK ;
}
}
static enum fh_error wp_setbase ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
fh - > base = w - > param ;
return FH_OK ;
}
static enum fh_error w_base ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
TRY ( ds_push ( fh , MAGICADDR_BASE ) ) ;
return FH_OK ;
}
static enum fh_error w_fetch ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t addr = 0 ;
TRY ( ds_pop ( fh , & addr ) ) ;
uint32_t val = 0 ;
TRY ( fh_fetch ( fh , addr , & val ) ) ;
TRY ( ds_push ( fh , val ) ) ;
return FH_OK ;
}
static enum fh_error w_store ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t addr = 0 ;
TRY ( ds_pop ( fh , & addr ) ) ;
uint32_t val = 0 ;
TRY ( ds_pop ( fh , & val ) ) ;
TRY ( fh_store ( fh , addr , val ) ) ;
return FH_OK ;
}
static enum fh_error w_two_store ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t addr = 0 ;
TRY ( ds_pop ( fh , & addr ) ) ;
uint32_t a = 0 , b = 0 ;
TRY ( ds_pop ( fh , & a ) ) ;
TRY ( ds_pop ( fh , & b ) ) ;
TRY ( fh_store ( fh , addr , a ) ) ;
TRY ( fh_store ( fh , addr + CELL , b ) ) ;
return FH_OK ;
}
static enum fh_error w_two_fetch ( struct fh_thread_s * fh , const struct fh_word_s * w )
{
( void ) w ;
enum fh_error rv ;
uint32_t addr = 0 ;
TRY ( ds_pop ( fh , & addr ) ) ;
uint32_t a = 0 , b = 0 ;
TRY ( fh_fetch ( fh , addr , & a ) ) ;
TRY ( fh_fetch ( fh , addr + CELL , & b ) ) ;
TRY ( ds_push ( fh , b ) ) ;
TRY ( ds_push ( fh , a ) ) ;
return FH_OK ;
}
/** Add pointers to built-in word handlers to a runtime struct */
/** Add pointers to built-in word handlers to a runtime struct */
enum fh_error register_builtin_words ( struct fh_thread_s * fh )
enum fh_error register_builtin_words ( struct fh_thread_s * fh )
{
{
@ -227,37 +643,79 @@ enum fh_error register_builtin_words(struct fh_thread_s *fh)
const char * name ;
const char * name ;
word_exec_t handler ;
word_exec_t handler ;
bool immediate ;
bool immediate ;
uint32_t param ;
} ;
} ;
const struct name_and_handler builtins [ ] = {
const struct name_and_handler builtins [ ] = {
{ " s \" " , w_s_quote , 1 } ,
{ " s \" " , w_s_quote , 1 , 0 } ,
{ " . \" " , w_dot_quote , 1 } ,
{ " . \" " , w_dot_quote , 1 , 0 } ,
/* Compiler control words */
/* Compiler control words */
{ " bye " , w_bye , 0 } ,
{ " bye " , w_bye , 0 , 0 } ,
/* Pointers */
{ " @ " , w_fetch , 0 , 0 } ,
{ " ! " , w_store , 0 , 0 } ,
{ " 2! " , w_two_store , 0 , 0 } ,
{ " 2@ " , w_two_fetch , 0 , 0 } ,
/* Arithmetics */
/* Arithmetics */
{ " + " , w_add , 0 } ,
{ " dec " , wp_setbase , 0 , 10 } ,
{ " - " , w_sub , 0 } ,
{ " hex " , wp_setbase , 0 , 16 } ,
{ " * " , w_mul , 0 } ,
{ " base " , w_base , 0 , 0 } ,
{ " + " , w_plus , 0 , 0 } ,
{ " - " , w_minus , 0 , 0 } ,
{ " * " , w_star , 0 , 0 } ,
{ " */ " , w_star_slash , 0 , 0 } ,
{ " / " , w_slash , 0 , 0 } ,
{ " /mod " , w_slash_mod , 0 , 0 } ,
{ " 0< " , w_zero_less , 0 , 0 } ,
{ " 0= " , w_zero_equals , 0 , 0 } ,
{ " 0<> " , w_zero_not_equals , 0 , 0 } ,
{ " 0> " , w_zero_greater , 0 , 0 } ,
{ " < " , w_less , 0 , 0 } ,
{ " = " , w_equals , 0 , 0 } ,
{ " <> " , w_not_equals , 0 , 0 } ,
{ " > " , w_greater , 0 , 0 } ,
{ " 1+ " , wp_add , 0 , 1 } ,
{ " 1- " , wp_add , 0 , - 1 } ,
{ " 2+ " , wp_add , 0 , 2 } ,
{ " 2- " , wp_add , 0 , - 2 } ,
{ " 2* " , wp_mul , 0 , 2 } ,
{ " 2/ " , wp_div , 0 , 2 } ,
/* Stack manip */
/* Stack manip */
{ " dup " , w_dup , 0 } ,
{ " drop " , w_drop , 0 , 0 } ,
{ " drop " , w_drop , 0 } ,
{ " dup " , w_dup , 0 , 0 } ,
{ " swap " , w_swap , 0 } ,
{ " over " , w_over , 0 , 0 } ,
{ " rot " , w_rot , 0 } ,
{ " swap " , w_swap , 0 , 0 } ,
{ " over " , w_over , 0 } ,
{ " rot " , w_rot , 0 , 0 } ,
{ " tuck " , w_tuck , 0 } ,
{ " tuck " , w_tuck , 0 , 0 } ,
{ " pick " , w_pick , 0 } ,
{ " pick " , w_pick , 0 , 0 } ,
{ " roll " , w_roll , 0 } ,
{ " roll " , w_roll , 0 , 0 } ,
/* Double wide stack manip */
{ " 2drop " , w_two_drop , 0 , 0 } ,
{ " 2dup " , w_two_dup , 0 , 0 } ,
{ " 2over " , w_two_over , 0 , 0 } ,
{ " 2swap " , w_two_swap , 0 , 0 } ,
// /* Return stack manip */
{ " >r " , w_to_r , 0 , 0 } ,
{ " r> " , w_r_from , 0 , 0 } ,
{ " r@ " , w_r_fetch , 0 , 0 } ,
// /* Double wide return stack manip */
{ " 2>r " , w_two_to_r , 0 , 0 } ,
{ " 2r> " , w_two_r_from , 0 , 0 } ,
{ " 2r@ " , w_two_r_fetch , 0 , 0 } ,
/* Printing */
/* Printing */
{ " . " , w_dot , 0 } ,
{ " . " , w_dot , 0 , 0 } ,
{ " type " , w_type , 0 } ,
{ " type " , w_type , 0 , 0 } ,
{ " cr " , w_cr , 0 } ,
{ " cr " , w_cr , 0 , 0 } ,
{ " space " , w_space , 0 } ,
{ " space " , w_space , 0 , 0 } ,
{ " dump " , w_dump , 0 } ,
{ " dump " , w_dump , 0 , 0 } ,
/* Control words */
/* Control flow */
{ " : " , w_colon , 0 } ,
{ " abort " , w_abort , 0 , 0 } ,
{ " ; " , w_semicolon , 1 } ,
{ " quit " , w_quit , 0 , 0 } ,
{ " \\ " , w_backslash , 1 } , // line comment
/* Syntax */
{ " ( " , w_paren , 1 } , // enclosed comment
{ " : " , w_colon , 0 , 0 } ,
{ " ; " , w_semicolon , 1 , 0 } ,
{ " \\ " , w_backslash , 1 , 0 } , // line comment
{ " ( " , w_paren , 1 , 0 } , // enclosed comment
{ /* end marker */ }
{ /* end marker */ }
} ;
} ;
@ -270,6 +728,7 @@ enum fh_error register_builtin_words(struct fh_thread_s *fh)
w . handler = p - > handler ;
w . handler = p - > handler ;
w . builtin = 1 ;
w . builtin = 1 ;
w . immediate = p - > immediate ;
w . immediate = p - > immediate ;
w . param = p - > param ;
rv = fh_add_word ( & w , fh ) ;
rv = fh_add_word ( & w , fh ) ;
if ( rv ! = FH_OK ) {
if ( rv ! = FH_OK ) {
return rv ;
return rv ;