31 #define FVM_THREADING 1 48 #define FVM_KERNEL_DICT 1 55 #define FVM_KERNEL_OPT 1 58 #define OP(n) case OP_ ## n: 59 #define NEXT() goto INNER 61 #define CALL(fn) tp = fn; goto FNCALL 62 #define MAP(if) (-ir-1) 64 #if defined(ARDUINO_ARCH_AVR) 65 # define FNTAB(ix) (code_P) pgm_read_word(fntab+ix) 66 # define FNSTR(ix) (const __FlashStringHelper*) pgm_read_word(fnstr+ix) 67 # define OPSTR(ix) (const __FlashStringHelper*) pgm_read_word(opstr+ix) 69 # define FNTAB(ix) fntab[ix] 70 # define FNSTR(ix) fnstr[ix] 71 # define OPSTR(ix) opstr[ix] 75 #if (FVM_THREADING == 0) || !defined(ARDUINO_ARCH_AVR) 76 # if defined(ARDUINO_ARCH_AVR) 77 # define fetch_byte(ip) (int8_t) pgm_read_byte(ip) 78 # define fetch_word(ip) (cell_t) pgm_read_word(ip) 80 # define fetch_byte(ip) (*((int8_t*) (ip))) 81 # define fetch_word(ip) (*((cell_t*) (ip))) 88 return ((int8_t) pgm_read_byte(ip));
89 return (*(((int8_t*) ip) - FVM::CODE_P_MAX));
96 return (*(
FVM::cell_t*) (((int8_t*) ip) - FVM::CODE_P_MAX));
106 for (
int i = 0; i <
m_next; i++)
110 for (
int i = 0; (s = (
const char*)
FNSTR(i)) != 0; i++)
114 for (
int i = 0; (s = (
const char*)
OPSTR(i)) != 0; i++)
115 if (!strcmp_P(name, s))
return (i);
123 Stream& ios = task.
m_ios;
128 while (!ios.available());
135 while (!ios.available());
146 Stream& ios = task.
m_ios;
157 uint32_t start = micros();
180 #if (FVM_KERNEL_OPT == 1) 194 uint32_t stop = micros();
196 ios.print(F(
"task@"));
201 ios.print(stop - start);
207 ios.print((uint16_t) (rp - task.m_rp0));
211 uint16_t depth = (uint16_t) (rp - task.m_rp0);
212 while (depth--) ios.print(
' ');
219 #if (FVM_KERNEL_OPT == 1) 226 #if (FVM_KERNEL_DICT == 0) 234 #if (FVM_KERNEL_DICT == 0) 237 #if (FVM_THREADING == 1) 244 ios.print(
OPSTR(ir));
249 tmp = (sp - task.
m_sp0);
266 if (task.
m_trace) start = micros();
273 switch ((uint8_t) ir) {
280 if (tmp != 0)
NEXT();
308 #if defined(ARDUINO_ARCH_AVR) 346 #if defined(ARDUINO_ARCH_AVR) 349 tos = *((
cell_t*) (tp + 1));
378 ip += (tos == 0) ? ir : 1;
424 if (*rp < *(rp - 1)) {
442 if (*rp < *(rp - 1)) {
506 #if (FVM_KERNEL_OPT == 1) 534 tos = *((uint8_t*) tos);
542 *((uint8_t*) tos) = *sp--;
563 *((
cell_t*) tos) += *sp--;
568 static const code_t PLUS_STORE_CODE[] PROGMEM = {
577 CALL(PLUS_STORE_CODE);
596 static const code_t HERE_CODE[] PROGMEM = {
615 static const code_t ALLOT_CODE[] PROGMEM = {
633 static const code_t COMMA_CODE[] PROGMEM = {
653 static const code_t C_COMMA_CODE[] PROGMEM = {
707 tmp = (sp - task.
m_sp0);
726 static const code_t NIP_CODE[] PROGMEM = {
748 static const code_t DUP_CODE[] PROGMEM = {
759 if (tos != 0) *++sp = tos;
763 static const code_t QUESTION_DUP_CODE[] PROGMEM = {
769 CALL(QUESTION_DUP_CODE);
782 static const code_t OVER_CODE[] PROGMEM = {
799 static const code_t TUCK_CODE[] PROGMEM = {
823 static const code_t SWAP_CODE[] PROGMEM = {
842 static const code_t ROT_CODE[] PROGMEM = {
861 static const code_t MINUS_ROT_CODE[] PROGMEM = {
866 CALL(MINUS_ROT_CODE);
874 for (; tmp > 0; tmp--)
875 sp[-tmp] = sp[-tmp + 1];
883 static const code_t TWO_SWAP_CODE[] PROGMEM = {
896 static const code_t TWO_DUP_CODE[] PROGMEM = {
907 static const code_t TWO_OVER_CODE[] PROGMEM = {
918 static const code_t TWO_DROP_CODE[] PROGMEM = {
985 static const code_t CELLS_CODE[] PROGMEM = {
1025 static const code_t NEGATE_CODE[] PROGMEM = {
1098 tos = (((
cell2_t) tmp) * (*sp--)) / tos;
1152 tos = ((*sp <= tos) & (*sp >= tmp)) ? -1 : 0;
1157 static const code_t WITHIN_CODE[] PROGMEM = {
1176 if (tos < 0) tos = -tos;
1180 static const code_t ABS_CODE[] PROGMEM = {
1190 static const code_t ABS_CODE[] PROGMEM = {
1207 if (tmp < tos) tos = tmp;
1211 static const code_t MIN_CODE[] PROGMEM = {
1222 static const code_t MIN_CODE[] PROGMEM = {
1239 if (tmp > tos) tos = tmp;
1243 static const code_t MAX_CODE[] PROGMEM = {
1254 static const code_t MAX_CODE[] PROGMEM = {
1276 tos = (tos != 0) ? -1 : 0;
1280 static const code_t ZERO_NOT_EQUALS_CODE[] PROGMEM = {
1285 CALL(ZERO_NOT_EQUALS_CODE);
1292 tos = (tos < 0) ? -1 : 0;
1296 static const code_t ZERO_LESS_CODE[] PROGMEM = {
1301 CALL(ZERO_LESS_CODE);
1312 tos = (tos == 0) ? -1 : 0;
1318 tos = (tos > 0) ? -1 : 0;
1325 tos = (*sp-- != tos) ? -1 : 0;
1329 static const code_t NOT_EQUALS_CODE[] PROGMEM = {
1334 CALL(NOT_EQUALS_CODE);
1341 tos = (*sp-- < tos) ? -1 : 0;
1345 static const code_t LESS_CODE[] PROGMEM = {
1357 tos = (*sp-- == tos) ? -1 : 0;
1361 static const code_t EQUALS_CODE[] PROGMEM = {
1373 tos = (*sp-- > tos) ? -1 : 0;
1377 static const code_t GREATER_CODE[] PROGMEM = {
1394 tos =
lookup((
const char*) tos);
1413 for (
int i = 0; (s = (
const char*)
OPSTR(i)) != 0; i++) {
1414 len = ios.print((
const __FlashStringHelper*) s);
1418 for (;len < 16; len++) ios.print(
' ');
1421 for (
int i = 0; (s = (
const char*)
FNSTR(i)) != 0; i++) {
1422 len = ios.print((
const __FlashStringHelper*) s);
1426 for (;len < 16; len++) ios.print(
' ');
1446 static const code_t WORDS_CODE[] PROGMEM = {
1496 static const code_t HEX_CODE[] PROGMEM = {
1513 static const code_t DECIMAL_CODE[] PROGMEM = {
1526 if (ios.available()) {
1544 static const code_t KEY_CODE[] PROGMEM = {
1558 ios.print((
char) tos);
1571 static const code_t CR_CODE[] PROGMEM = {
1587 static const code_t SPACE_CODE[] PROGMEM = {
1599 while (tos-- > 0) ios.print(
' ');
1604 static const code_t SPACES_CODE[] PROGMEM = {
1625 ios.print(tos, task.
m_base);
1632 static const code_t DOT_CODE[] PROGMEM = {
1655 tmp = (sp - task.
m_sp0);
1658 ios.print(F(
"]: "));
1662 ios.print(*++tp, task.
m_base);
1674 static const code_t DOT_S_CODE[] PROGMEM = {
1701 #if defined(ARDUINO_ARCH_AVR) 1703 ip += ios.print((
const __FlashStringHelper*) ip) + 1;
1705 ip += ios.print((
const char*) ip - CODE_P_MAX) + 1;
1707 ip += ios.print((
const __FlashStringHelper*) ip) + 1;
1715 ios.print((
const char*) tos);
1723 const __FlashStringHelper* s = NULL;
1725 s = (
const __FlashStringHelper*)
OPSTR(tos);
1728 tos = (s != NULL) ? ios.print(s) : 0;
1735 static const code_t QUESTION_CODE[] PROGMEM = {
1740 CALL(QUESTION_CODE);
1749 static const code_t DELAY_CODE[] PROGMEM = {
1783 pinMode(tos, *sp--);
1790 tos = digitalRead(tos);
1796 digitalWrite(tos, *sp--);
1803 digitalWrite(tos, !digitalRead(tos));
1810 tos = analogRead(tos & 0xf);
1816 analogWrite(tos, *sp--);
1823 #if (FVM_KERNEL_OPT == 1) 1839 if (op < 0 || op >
TOKEN_MAX)
return (-1);
1840 static const code_t EXECUTE_CODE[] PROGMEM = {
1845 return (
execute(EXECUTE_CODE, task));
1851 char c =
scan(buffer, task);
1852 int res =
execute(buffer, task);
1854 while ((res =
resume(task)) > 0);
1856 else if (res == -1) {
1858 int value = strtol(buffer, &endptr, task.
m_base == 10 ? 0 : task.
m_base);
1860 task.
m_ios.print(buffer);
1861 task.
m_ios.println(F(
" ??"));
1867 if (c ==
'\n' && !task.
trace())
1872 #if (FVM_KERNEL_DICT == 1) 2018 #if (FVM_KERNEL_DICT == 1) static const char C_COMMA_PSTR[]
static const char SLASH_MODE_PSTR[]
static const char SLIT_PSTR[]
static const char LSHIFT_PSTR[]
static const char WORDS_PSTR[]
static const char LIT_PSTR[]
static const char DOT_QUOTE_PSTR[]
static const char FUNC_PSTR[]
static const char DOT_S_PSTR[]
static const char DOES_PSTR[]
static const char OVER_PSTR[]
static const char PARAM_PSTR[]
static const char TWO_DUP_PSTR[]
static const char NEGATE_PSTR[]
static const char YIELD_PSTR[]
static const char QUESTION_KEY_PSTR[]
static const char CALL_PSTR[]
static const char FALSE_PSTR[]
static const char PLUS_PSTR[]
static const char TUCK_PSTR[]
static const char NOOP_PSTR[]
static const char COMPILE_PSTR[]
static const char TWO_PSTR[]
static const char TWO_OVER_PSTR[]
static const char HERE_PSTR[]
static const char ALLOT_PSTR[]
static const char EXIT_PSTR[]
static const char CELLS_PSTR[]
static const str_P opstr[]
static const char DROP_PSTR[]
static const char MINUS_ROT_PSTR[]
static const char TWO_DROP_PSTR[]
static const char SLASH_PSTR[]
static const char DIGITALTOGGLE_PSTR[]
static const char ZERO_GREATER_PSTR[]
static const char MINUS_ONE_PSTR[]
static const char ROOM_PSTR[]
static const char R_FETCH_PSTR[]
static const char ZERO_EXIT_PSTR[]
static const char TYPE_PSTR[]
static const char PINMODE_PSTR[]
static const char LOOP_PSTR[]
void(* fn_t)(task_t &task, void *env)
static const char MILLIS_PSTR[]
static const char DIGITALREAD_PSTR[]
static const char I_PSTR[]
static const char ZERO_PSTR[]
static const char CLIT_PSTR[]
static const uint16_t CODE_P_MAX
static const char STAR_PSTR[]
static const char NOT_PSTR[]
code_P * m_rp
Return stack pointer.
static const char TWO_MINUS_PSTR[]
static const char TWO_PLUS_PSTR[]
static const char EMPTY_PSTR[]
static const char J_PSTR[]
static const char R_FROM_PSTR[]
static const char ONE_MINUS_PSTR[]
static const char TWO_STAR_PSTR[]
static const char U_LESS_PSTR[]
static const char LOOKUP_PSTR[]
static const char C_STORE_PSTR[]
cell_t m_base
Number conversion base.
static const char TWO_SLASH_PSTR[]
static const char SYSCALL_PSTR[]
static const char ABS_PSTR[]
static const char SWAP_PSTR[]
static const char MICROS_PSTR[]
static const char MINUS_TWO_PSTR[]
static const char HEX_PSTR[]
static const char MAX_PSTR[]
static const char ONE_PSTR[]
static const char COMMA_PSTR[]
static const char DEPTH_PSTR[]
static const char STORE_PSTR[]
static const char ANALOGREAD_PSTR[]
static const char DP_PSTR[]
static const char DIGITALWRITE_PSTR[]
static const char DECIMAL_PSTR[]
static const char PLUS_LOOP_PSTR[]
static const char CR_PSTR[]
static const char MIN_PSTR[]
static const char MINUS_PSTR[]
static const char DUP_PSTR[]
static const char ROT_PSTR[]
static const char PICK_PSTR[]
int execute(int op, task_t &task)
static const char DOT_NAME_PSTR[]
static const char GREATER_PSTR[]
static const char QUESTION_PSTR[]
static const char ZERO_LESS_PSTR[]
static const char BASE_PSTR[]
cell_t * m_sp
Parameter stack pointer.
static const char ANALOGWRITE_PSTR[]
code_P * m_rp0
Return stack bottom pointer.
static const char ZERO_EQUALS_PSTR[]
static const char EXECUTE_PSTR[]
static const char LEAVE_PSTR[]
static const char PLUS_STORE_PSTR[]
cell_t * m_sp0
Parameter stack bottom pointer.
static const char NOT_EQUALS_PSTR[]
static const char BRANCH_PSTR[]
int interpret(task_t &task)
static const char KEY_PSTR[]
static const char ONE_PLUS_PSTR[]
static const char ZERO_NOT_EQUALS_PSTR[]
static const char DOT_PSTR[]
static const char XOR_PSTR[]
int lookup(const char *name)
static const char AND_PSTR[]
static const char WITHIN_PSTR[]
static const char SP_PSTR[]
static const char CELL_PSTR[]
static const char VAR_PSTR[]
static const char QUESTION_DUP_PSTR[]
static const char INVERT_PSTR[]
static const char MOD_PSTR[]
static const char DELAY_PSTR[]
static const char FETCH_PSTR[]
static const char C_FETCH_PSTR[]
static const char ZERO_BRANCH_PSTR[]
static const char DO_PSTR[]
static const char EQUALS_PSTR[]
static const char TO_R_PSTR[]
static const char EMIT_PSTR[]
static const char BOOL_PSTR[]
static const char LESS_PSTR[]
static const char RSHIFT_PSTR[]
static const char SPACE_PSTR[]
static const char ROLL_PSTR[]
static const char TRACE_PSTR[]
static const char STAR_SLASH_PSTR[]
static const char HALT_PSTR[]
Print contents of parameter stack.
FVM::Task< 32, 16 > task(Serial, WORD3_CODE)
static const char NIP_PSTR[]
int scan(char *bp, task_t &task)
static const char TO_BODY_PSTR[]
static const char TRUE_PSTR[]
static const char SPACES_PSTR[]
static const char OR_PSTR[]
static const char CONST_PSTR[]
static const char U_DOT_PSTR[]
Stream & m_ios
Input/Output stream.
static const char TWO_SWAP_PSTR[]