| 1 | /* @(#) pf_guts.h 98/01/28 1.4 */\r |
| 2 | #ifndef _pf_guts_h\r |
| 3 | #define _pf_guts_h\r |
| 4 | \r |
| 5 | /***************************************************************\r |
| 6 | ** Include file for PForth, a Forth based on 'C'\r |
| 7 | **\r |
| 8 | ** Author: Phil Burk\r |
| 9 | ** Copyright 1994 3DO, Phil Burk, Larry Polansky, David Rosenboom\r |
| 10 | **\r |
| 11 | ** The pForth software code is dedicated to the public domain,\r |
| 12 | ** and any third party may reproduce, distribute and modify\r |
| 13 | ** the pForth software code or any derivative works thereof\r |
| 14 | ** without any compensation or license. The pForth software\r |
| 15 | ** code is provided on an "as is" basis without any warranty\r |
| 16 | ** of any kind, including, without limitation, the implied\r |
| 17 | ** warranties of merchantability and fitness for a particular\r |
| 18 | ** purpose and their equivalents under the laws of any jurisdiction.\r |
| 19 | **\r |
| 20 | ***************************************************************/\r |
| 21 | \r |
| 22 | /*\r |
| 23 | ** PFORTH_VERSION changes when PForth is modified and released.\r |
| 24 | ** See README file for version info.\r |
| 25 | */\r |
| 26 | #define PFORTH_VERSION "27"\r |
| 27 | \r |
| 28 | /*\r |
| 29 | ** PFORTH_FILE_VERSION changes when incompatible changes are made\r |
| 30 | ** in the ".dic" file format.\r |
| 31 | **\r |
| 32 | ** FV3 - 950225 - Use ABS_TO_CODEREL for CodePtr. See file "pf_save.c".\r |
| 33 | ** FV4 - 950309 - Added NameSize and CodeSize to pfSaveForth().\r |
| 34 | ** FV5 - 950316 - Added Floats and reserved words.\r |
| 35 | ** FV6 - 961213 - Added ID_LOCAL_PLUSSTORE, ID_COLON_P, etc.\r |
| 36 | ** FV7 - 971203 - Added ID_FILL, (1LOCAL@), etc., ran out of reserved, resorted.\r |
| 37 | ** FV8 - 980818 - Added Endian flag.\r |
| 38 | ** FV9 - 20100503 - Added support for 64-bit CELL.\r |
| 39 | */\r |
| 40 | #define PF_FILE_VERSION (9) /* Bump this whenever primitives added. */\r |
| 41 | #define PF_EARLIEST_FILE_VERSION (9) /* earliest one still compatible */\r |
| 42 | \r |
| 43 | /***************************************************************\r |
| 44 | ** Sizes and other constants\r |
| 45 | ***************************************************************/\r |
| 46 | \r |
| 47 | #define TIB_SIZE (256)\r |
| 48 | \r |
| 49 | #ifndef FALSE\r |
| 50 | #define FALSE (0)\r |
| 51 | #endif\r |
| 52 | #ifndef TRUE\r |
| 53 | #define TRUE (1)\r |
| 54 | #endif\r |
| 55 | \r |
| 56 | #define FFALSE (0)\r |
| 57 | #define FTRUE (-1)\r |
| 58 | #define BLANK (' ')\r |
| 59 | \r |
| 60 | #define FLAG_PRECEDENCE (0x80)\r |
| 61 | #define FLAG_IMMEDIATE (0x40)\r |
| 62 | #define FLAG_SMUDGE (0x20)\r |
| 63 | #define MASK_NAME_SIZE (0x1F)\r |
| 64 | \r |
| 65 | /* Debug TRACE flags */\r |
| 66 | #define TRACE_INNER (0x0002)\r |
| 67 | #define TRACE_COMPILE (0x0004)\r |
| 68 | #define TRACE_SPECIAL (0x0008)\r |
| 69 | \r |
| 70 | /* Numeric types returned by NUMBER? */\r |
| 71 | #define NUM_TYPE_BAD (0)\r |
| 72 | #define NUM_TYPE_SINGLE (1)\r |
| 73 | #define NUM_TYPE_DOUBLE (2)\r |
| 74 | #define NUM_TYPE_FLOAT (3)\r |
| 75 | \r |
| 76 | #define CREATE_BODY_OFFSET (3*sizeof(cell_t))\r |
| 77 | \r |
| 78 | /***************************************************************\r |
| 79 | ** Primitive Token IDS\r |
| 80 | ** Do NOT change the order of these IDs or dictionary files will break!\r |
| 81 | ***************************************************************/\r |
| 82 | enum cforth_primitive_ids\r |
| 83 | {\r |
| 84 | ID_EXIT = 0, /* ID_EXIT must always be zero. */\r |
| 85 | /* Do NOT change the order of these IDs or dictionary files will break! */\r |
| 86 | ID_1MINUS,\r |
| 87 | ID_1PLUS,\r |
| 88 | ID_2DUP,\r |
| 89 | ID_2LITERAL,\r |
| 90 | ID_2LITERAL_P,\r |
| 91 | ID_2MINUS,\r |
| 92 | ID_2OVER,\r |
| 93 | ID_2PLUS,\r |
| 94 | ID_2SWAP,\r |
| 95 | ID_2_R_FETCH,\r |
| 96 | ID_2_R_FROM,\r |
| 97 | ID_2_TO_R,\r |
| 98 | ID_ACCEPT_P,\r |
| 99 | ID_ALITERAL,\r |
| 100 | ID_ALITERAL_P,\r |
| 101 | ID_ALLOCATE,\r |
| 102 | ID_AND,\r |
| 103 | ID_ARSHIFT,\r |
| 104 | ID_BAIL,\r |
| 105 | ID_BODY_OFFSET,\r |
| 106 | ID_BRANCH,\r |
| 107 | ID_BYE,\r |
| 108 | ID_CALL_C,\r |
| 109 | ID_CFETCH,\r |
| 110 | ID_CMOVE,\r |
| 111 | ID_CMOVE_UP,\r |
| 112 | ID_COLON,\r |
| 113 | ID_COLON_P,\r |
| 114 | ID_COMPARE,\r |
| 115 | ID_COMP_EQUAL,\r |
| 116 | ID_COMP_GREATERTHAN,\r |
| 117 | ID_COMP_LESSTHAN,\r |
| 118 | ID_COMP_NOT_EQUAL,\r |
| 119 | ID_COMP_U_GREATERTHAN,\r |
| 120 | ID_COMP_U_LESSTHAN,\r |
| 121 | ID_COMP_ZERO_EQUAL,\r |
| 122 | ID_COMP_ZERO_GREATERTHAN,\r |
| 123 | ID_COMP_ZERO_LESSTHAN,\r |
| 124 | ID_COMP_ZERO_NOT_EQUAL,\r |
| 125 | ID_CR,\r |
| 126 | ID_CREATE,\r |
| 127 | ID_CREATE_P,\r |
| 128 | ID_CSTORE,\r |
| 129 | ID_DEFER,\r |
| 130 | ID_DEFER_P,\r |
| 131 | ID_DEPTH,\r |
| 132 | ID_DIVIDE,\r |
| 133 | ID_DOT,\r |
| 134 | ID_DOTS,\r |
| 135 | ID_DO_P,\r |
| 136 | ID_DROP,\r |
| 137 | ID_DUMP,\r |
| 138 | ID_DUP,\r |
| 139 | ID_D_MINUS,\r |
| 140 | ID_D_MTIMES,\r |
| 141 | ID_D_MUSMOD,\r |
| 142 | ID_D_PLUS,\r |
| 143 | ID_D_UMSMOD,\r |
| 144 | ID_D_UMTIMES,\r |
| 145 | ID_EMIT,\r |
| 146 | ID_EMIT_P,\r |
| 147 | ID_EOL,\r |
| 148 | ID_ERRORQ_P,\r |
| 149 | ID_EXECUTE,\r |
| 150 | ID_FETCH,\r |
| 151 | ID_FILE_CLOSE,\r |
| 152 | ID_FILE_CREATE,\r |
| 153 | ID_FILE_OPEN,\r |
| 154 | ID_FILE_POSITION,\r |
| 155 | ID_FILE_READ,\r |
| 156 | ID_FILE_REPOSITION,\r |
| 157 | ID_FILE_RO,\r |
| 158 | ID_FILE_RW,\r |
| 159 | ID_FILE_SIZE,\r |
| 160 | ID_FILE_WRITE,\r |
| 161 | ID_FILL,\r |
| 162 | ID_FIND,\r |
| 163 | ID_FINDNFA,\r |
| 164 | ID_FLUSHEMIT,\r |
| 165 | ID_FREE,\r |
| 166 | ID_HERE,\r |
| 167 | ID_NUMBERQ_P,\r |
| 168 | ID_I,\r |
| 169 | ID_INCLUDE_FILE,\r |
| 170 | ID_J,\r |
| 171 | ID_KEY,\r |
| 172 | ID_LEAVE_P,\r |
| 173 | ID_LITERAL,\r |
| 174 | ID_LITERAL_P,\r |
| 175 | ID_LOADSYS,\r |
| 176 | ID_LOCAL_COMPILER,\r |
| 177 | ID_LOCAL_ENTRY,\r |
| 178 | ID_LOCAL_EXIT,\r |
| 179 | ID_LOCAL_FETCH,\r |
| 180 | ID_LOCAL_FETCH_1,\r |
| 181 | ID_LOCAL_FETCH_2,\r |
| 182 | ID_LOCAL_FETCH_3,\r |
| 183 | ID_LOCAL_FETCH_4,\r |
| 184 | ID_LOCAL_FETCH_5,\r |
| 185 | ID_LOCAL_FETCH_6,\r |
| 186 | ID_LOCAL_FETCH_7,\r |
| 187 | ID_LOCAL_FETCH_8,\r |
| 188 | ID_LOCAL_PLUSSTORE,\r |
| 189 | ID_LOCAL_STORE,\r |
| 190 | ID_LOCAL_STORE_1,\r |
| 191 | ID_LOCAL_STORE_2,\r |
| 192 | ID_LOCAL_STORE_3,\r |
| 193 | ID_LOCAL_STORE_4,\r |
| 194 | ID_LOCAL_STORE_5,\r |
| 195 | ID_LOCAL_STORE_6,\r |
| 196 | ID_LOCAL_STORE_7,\r |
| 197 | ID_LOCAL_STORE_8,\r |
| 198 | ID_LOOP_P,\r |
| 199 | ID_LSHIFT,\r |
| 200 | ID_MAX,\r |
| 201 | ID_MIN,\r |
| 202 | ID_MINUS,\r |
| 203 | ID_NAME_TO_PREVIOUS,\r |
| 204 | ID_NAME_TO_TOKEN,\r |
| 205 | ID_NOOP,\r |
| 206 | ID_NUMBERQ,\r |
| 207 | ID_OR,\r |
| 208 | ID_OVER,\r |
| 209 | ID_PICK,\r |
| 210 | ID_PLUS,\r |
| 211 | ID_PLUSLOOP_P,\r |
| 212 | ID_PLUS_STORE,\r |
| 213 | ID_QDO_P,\r |
| 214 | ID_QDUP,\r |
| 215 | ID_QTERMINAL,\r |
| 216 | ID_QUIT_P,\r |
| 217 | ID_REFILL,\r |
| 218 | ID_RESIZE,\r |
| 219 | ID_RESTORE_INPUT,\r |
| 220 | ID_ROLL,\r |
| 221 | ID_ROT,\r |
| 222 | ID_RP_FETCH,\r |
| 223 | ID_RP_STORE,\r |
| 224 | ID_RSHIFT,\r |
| 225 | ID_R_DROP,\r |
| 226 | ID_R_FETCH,\r |
| 227 | ID_R_FROM,\r |
| 228 | ID_SAVE_FORTH_P,\r |
| 229 | ID_SAVE_INPUT,\r |
| 230 | ID_SCAN,\r |
| 231 | ID_SEMICOLON,\r |
| 232 | ID_SKIP,\r |
| 233 | ID_SOURCE,\r |
| 234 | ID_SOURCE_ID,\r |
| 235 | ID_SOURCE_ID_POP,\r |
| 236 | ID_SOURCE_ID_PUSH,\r |
| 237 | ID_SOURCE_SET,\r |
| 238 | ID_SP_FETCH,\r |
| 239 | ID_SP_STORE,\r |
| 240 | ID_STORE,\r |
| 241 | ID_SWAP,\r |
| 242 | ID_TEST1,\r |
| 243 | ID_TEST2,\r |
| 244 | ID_TEST3,\r |
| 245 | ID_TICK,\r |
| 246 | ID_TIMES,\r |
| 247 | ID_TO_R,\r |
| 248 | ID_TYPE,\r |
| 249 | ID_TYPE_P,\r |
| 250 | ID_VAR_BASE,\r |
| 251 | ID_VAR_CODE_BASE,\r |
| 252 | ID_VAR_CODE_LIMIT,\r |
| 253 | ID_VAR_CONTEXT,\r |
| 254 | ID_VAR_DP,\r |
| 255 | ID_VAR_ECHO,\r |
| 256 | ID_VAR_HEADERS_BASE,\r |
| 257 | ID_VAR_HEADERS_LIMIT,\r |
| 258 | ID_VAR_HEADERS_PTR,\r |
| 259 | ID_VAR_NUM_TIB,\r |
| 260 | ID_VAR_OUT,\r |
| 261 | ID_VAR_RETURN_CODE,\r |
| 262 | ID_VAR_SOURCE_ID,\r |
| 263 | ID_VAR_STATE,\r |
| 264 | ID_VAR_TO_IN,\r |
| 265 | ID_VAR_TRACE_FLAGS,\r |
| 266 | ID_VAR_TRACE_LEVEL,\r |
| 267 | ID_VAR_TRACE_STACK,\r |
| 268 | ID_VLIST,\r |
| 269 | ID_WORD,\r |
| 270 | ID_WORD_FETCH,\r |
| 271 | ID_WORD_STORE,\r |
| 272 | ID_XOR,\r |
| 273 | ID_ZERO_BRANCH,\r |
| 274 | ID_CATCH,\r |
| 275 | ID_THROW,\r |
| 276 | ID_INTERPRET,\r |
| 277 | ID_FILE_WO,\r |
| 278 | ID_FILE_BIN,\r |
| 279 | /* Added to support 64 bit operation. */\r |
| 280 | ID_CELL,\r |
| 281 | ID_CELLS,\r |
| 282 | /* DELETE-FILE */\r |
| 283 | ID_FILE_DELETE,\r |
| 284 | /* If you add a word here, take away one reserved word below. */\r |
| 285 | #ifdef PF_SUPPORT_FP\r |
| 286 | /* Only reserve space if we are adding FP so that we can detect\r |
| 287 | ** unsupported primitives when loading dictionary.\r |
| 288 | */\r |
| 289 | ID_RESERVED01,\r |
| 290 | ID_RESERVED02,\r |
| 291 | ID_RESERVED03,\r |
| 292 | ID_RESERVED04,\r |
| 293 | ID_RESERVED05,\r |
| 294 | ID_RESERVED06,\r |
| 295 | ID_RESERVED07,\r |
| 296 | ID_RESERVED08,\r |
| 297 | ID_RESERVED09,\r |
| 298 | ID_RESERVED10,\r |
| 299 | ID_RESERVED11,\r |
| 300 | ID_RESERVED12,\r |
| 301 | ID_RESERVED13,\r |
| 302 | ID_FP_D_TO_F,\r |
| 303 | ID_FP_FSTORE,\r |
| 304 | ID_FP_FTIMES,\r |
| 305 | ID_FP_FPLUS,\r |
| 306 | ID_FP_FMINUS,\r |
| 307 | ID_FP_FSLASH,\r |
| 308 | ID_FP_F_ZERO_LESS_THAN,\r |
| 309 | ID_FP_F_ZERO_EQUALS,\r |
| 310 | ID_FP_F_LESS_THAN,\r |
| 311 | ID_FP_F_TO_D,\r |
| 312 | ID_FP_FFETCH,\r |
| 313 | ID_FP_FDEPTH,\r |
| 314 | ID_FP_FDROP,\r |
| 315 | ID_FP_FDUP,\r |
| 316 | ID_FP_FLITERAL,\r |
| 317 | ID_FP_FLITERAL_P,\r |
| 318 | ID_FP_FLOAT_PLUS,\r |
| 319 | ID_FP_FLOATS,\r |
| 320 | ID_FP_FLOOR,\r |
| 321 | ID_FP_FMAX,\r |
| 322 | ID_FP_FMIN,\r |
| 323 | ID_FP_FNEGATE,\r |
| 324 | ID_FP_FOVER,\r |
| 325 | ID_FP_FROT,\r |
| 326 | ID_FP_FROUND,\r |
| 327 | ID_FP_FSWAP,\r |
| 328 | ID_FP_FSTAR_STAR,\r |
| 329 | ID_FP_FABS,\r |
| 330 | ID_FP_FACOS,\r |
| 331 | ID_FP_FACOSH,\r |
| 332 | ID_FP_FALOG,\r |
| 333 | ID_FP_FASIN,\r |
| 334 | ID_FP_FASINH,\r |
| 335 | ID_FP_FATAN,\r |
| 336 | ID_FP_FATAN2,\r |
| 337 | ID_FP_FATANH,\r |
| 338 | ID_FP_FCOS,\r |
| 339 | ID_FP_FCOSH,\r |
| 340 | ID_FP_FLN,\r |
| 341 | ID_FP_FLNP1,\r |
| 342 | ID_FP_FLOG,\r |
| 343 | ID_FP_FSIN,\r |
| 344 | ID_FP_FSINCOS,\r |
| 345 | ID_FP_FSINH,\r |
| 346 | ID_FP_FSQRT,\r |
| 347 | ID_FP_FTAN,\r |
| 348 | ID_FP_FTANH,\r |
| 349 | ID_FP_FPICK,\r |
| 350 | #endif\r |
| 351 | /* Add new IDs by replacing reserved IDs or extending FP routines. */\r |
| 352 | /* Do NOT change the order of these IDs or dictionary files will break! */\r |
| 353 | NUM_PRIMITIVES /* This must always be LAST */\r |
| 354 | };\r |
| 355 | \r |
| 356 | \r |
| 357 | \r |
| 358 | /***************************************************************\r |
| 359 | ** THROW Codes\r |
| 360 | ***************************************************************/\r |
| 361 | /* ANSI standard definitions needed by pForth */\r |
| 362 | #define THROW_ABORT (-1)\r |
| 363 | #define THROW_ABORT_QUOTE (-2)\r |
| 364 | #define THROW_STACK_OVERFLOW (-3)\r |
| 365 | #define THROW_STACK_UNDERFLOW (-4)\r |
| 366 | #define THROW_UNDEFINED_WORD (-13)\r |
| 367 | #define THROW_EXECUTING (-14)\r |
| 368 | #define THROW_PAIRS (-22)\r |
| 369 | #define THROW_FLOAT_STACK_UNDERFLOW ( -45)\r |
| 370 | #define THROW_QUIT (-56)\r |
| 371 | \r |
| 372 | /* THROW codes unique to pForth */\r |
| 373 | #define THROW_BYE (-256) /* Exit program. */\r |
| 374 | #define THROW_SEMICOLON (-257) /* Error detected at ; */\r |
| 375 | #define THROW_DEFERRED (-258) /* Not a deferred word. Used in system.fth */\r |
| 376 | \r |
| 377 | /***************************************************************\r |
| 378 | ** Structures\r |
| 379 | ***************************************************************/\r |
| 380 | \r |
| 381 | typedef struct pfTaskData_s\r |
| 382 | {\r |
| 383 | cell_t *td_StackPtr; /* Primary data stack */\r |
| 384 | cell_t *td_StackBase;\r |
| 385 | cell_t *td_StackLimit;\r |
| 386 | cell_t *td_ReturnPtr; /* Return stack */\r |
| 387 | cell_t *td_ReturnBase;\r |
| 388 | cell_t *td_ReturnLimit;\r |
| 389 | #ifdef PF_SUPPORT_FP\r |
| 390 | PF_FLOAT *td_FloatStackPtr;\r |
| 391 | PF_FLOAT *td_FloatStackBase;\r |
| 392 | PF_FLOAT *td_FloatStackLimit;\r |
| 393 | #endif\r |
| 394 | cell_t *td_InsPtr; /* Instruction pointer, "PC" */\r |
| 395 | FileStream *td_InputStream;\r |
| 396 | /* Terminal. */\r |
| 397 | char td_TIB[TIB_SIZE]; /* Buffer for terminal input. */\r |
| 398 | cell_t td_IN; /* Index into Source */\r |
| 399 | cell_t td_SourceNum; /* #TIB after REFILL */\r |
| 400 | char *td_SourcePtr; /* Pointer to TIB or other source. */\r |
| 401 | cell_t td_LineNumber; /* Incremented on every refill. */\r |
| 402 | cell_t td_OUT; /* Current output column. */\r |
| 403 | } pfTaskData_t;\r |
| 404 | \r |
| 405 | typedef struct pfNode\r |
| 406 | {\r |
| 407 | struct pfNode *n_Next;\r |
| 408 | struct pfNode *n_Prev;\r |
| 409 | } pfNode;\r |
| 410 | \r |
| 411 | /* Structure of header entry in dictionary. These will be stored in dictionary specific endian format*/\r |
| 412 | typedef struct cfNameLinks\r |
| 413 | {\r |
| 414 | cell_t cfnl_PreviousName; /* name relative address of previous */\r |
| 415 | ExecToken cfnl_ExecToken; /* Execution token for word. */\r |
| 416 | /* Followed by variable length name field. */\r |
| 417 | } cfNameLinks;\r |
| 418 | \r |
| 419 | #define PF_DICF_ALLOCATED_SEGMENTS ( 0x0001)\r |
| 420 | typedef struct pfDictionary_s\r |
| 421 | {\r |
| 422 | pfNode dic_Node;\r |
| 423 | ucell_t dic_Flags;\r |
| 424 | /* Headers contain pointers to names and dictionary. */\r |
| 425 | \r |
| 426 | ucell_t dic_HeaderBaseUnaligned;\r |
| 427 | \r |
| 428 | ucell_t dic_HeaderBase;\r |
| 429 | ucell_t dic_HeaderPtr;\r |
| 430 | ucell_t dic_HeaderLimit;\r |
| 431 | /* Code segment contains tokenized code and data. */\r |
| 432 | ucell_t dic_CodeBaseUnaligned;\r |
| 433 | ucell_t dic_CodeBase;\r |
| 434 | union\r |
| 435 | {\r |
| 436 | cell_t *Cell;\r |
| 437 | uint8_t *Byte;\r |
| 438 | } dic_CodePtr;\r |
| 439 | ucell_t dic_CodeLimit;\r |
| 440 | } pfDictionary_t;\r |
| 441 | \r |
| 442 | /* Save state of include when nesting files. */\r |
| 443 | typedef struct IncludeFrame\r |
| 444 | {\r |
| 445 | FileStream *inf_FileID;\r |
| 446 | cell_t inf_LineNumber;\r |
| 447 | cell_t inf_SourceNum;\r |
| 448 | cell_t inf_IN;\r |
| 449 | char inf_SaveTIB[TIB_SIZE];\r |
| 450 | } IncludeFrame;\r |
| 451 | \r |
| 452 | #define MAX_INCLUDE_DEPTH (16)\r |
| 453 | \r |
| 454 | /***************************************************************\r |
| 455 | ** Prototypes\r |
| 456 | ***************************************************************/\r |
| 457 | \r |
| 458 | #ifdef __cplusplus\r |
| 459 | extern "C" {\r |
| 460 | #endif\r |
| 461 | \r |
| 462 | int pfCatch( ExecToken XT );\r |
| 463 | \r |
| 464 | #ifdef __cplusplus\r |
| 465 | }\r |
| 466 | #endif\r |
| 467 | \r |
| 468 | /***************************************************************\r |
| 469 | ** External Globals\r |
| 470 | ***************************************************************/\r |
| 471 | extern pfTaskData_t *gCurrentTask;\r |
| 472 | extern pfDictionary_t *gCurrentDictionary;\r |
| 473 | extern char gScratch[TIB_SIZE];\r |
| 474 | extern cell_t gNumPrimitives;\r |
| 475 | \r |
| 476 | extern ExecToken gLocalCompiler_XT; /* CFA of (LOCAL) compiler. */\r |
| 477 | extern ExecToken gNumberQ_XT; /* XT of NUMBER? */\r |
| 478 | extern ExecToken gQuitP_XT; /* XT of (QUIT) */\r |
| 479 | extern ExecToken gAcceptP_XT; /* XT of ACCEPT */\r |
| 480 | \r |
| 481 | #define DEPTH_AT_COLON_INVALID (-100)\r |
| 482 | extern cell_t gDepthAtColon;\r |
| 483 | \r |
| 484 | /* Global variables. */\r |
| 485 | extern cell_t gVarContext; /* Points to last name field. */\r |
| 486 | extern cell_t gVarState; /* 1 if compiling. */\r |
| 487 | extern cell_t gVarBase; /* Numeric Base. */\r |
| 488 | extern cell_t gVarEcho; /* Echo input from file. */\r |
| 489 | extern cell_t gVarEchoAccept; /* Echo input from ACCEPT. */\r |
| 490 | extern cell_t gVarTraceLevel;\r |
| 491 | extern cell_t gVarTraceStack;\r |
| 492 | extern cell_t gVarTraceFlags;\r |
| 493 | extern cell_t gVarQuiet; /* Suppress unnecessary messages, OK, etc. */\r |
| 494 | extern cell_t gVarReturnCode; /* Returned to caller of Forth, eg. UNIX shell. */\r |
| 495 | \r |
| 496 | extern IncludeFrame gIncludeStack[MAX_INCLUDE_DEPTH];\r |
| 497 | extern cell_t gIncludeIndex;\r |
| 498 | /***************************************************************\r |
| 499 | ** Macros\r |
| 500 | ***************************************************************/\r |
| 501 | \r |
| 502 | \r |
| 503 | /* Endian specific macros for creating target dictionaries for machines with\r |
| 504 | \r |
| 505 | ** different endian-ness.\r |
| 506 | \r |
| 507 | */\r |
| 508 | \r |
| 509 | #if defined(PF_BIG_ENDIAN_DIC)\r |
| 510 | \r |
| 511 | #define WRITE_FLOAT_DIC WriteFloatBigEndian\r |
| 512 | #define WRITE_CELL_DIC(addr,data) WriteCellBigEndian((uint8_t *)(addr),(ucell_t)(data))\r |
| 513 | #define WRITE_SHORT_DIC(addr,data) Write16BigEndian((uint8_t *)(addr),(uint16_t)(data))\r |
| 514 | #define READ_FLOAT_DIC ReadFloatBigEndian\r |
| 515 | #define READ_CELL_DIC(addr) ReadCellBigEndian((const uint8_t *)(addr))\r |
| 516 | #define READ_SHORT_DIC(addr) Read16BigEndian((const uint8_t *)(addr))\r |
| 517 | \r |
| 518 | #elif defined(PF_LITTLE_ENDIAN_DIC)\r |
| 519 | \r |
| 520 | #define WRITE_FLOAT_DIC WriteFloatLittleEndian\r |
| 521 | #define WRITE_CELL_DIC(addr,data) WriteCellLittleEndian((uint8_t *)(addr),(ucell_t)(data))\r |
| 522 | #define WRITE_SHORT_DIC(addr,data) Write16LittleEndian((uint8_t *)(addr),(uint16_t)(data))\r |
| 523 | #define READ_FLOAT_DIC ReadFloatLittleEndian\r |
| 524 | #define READ_CELL_DIC(addr) ReadCellLittleEndian((const uint8_t *)(addr))\r |
| 525 | #define READ_SHORT_DIC(addr) Read16LittleEndian((const uint8_t *)(addr))\r |
| 526 | \r |
| 527 | #else\r |
| 528 | \r |
| 529 | #define WRITE_FLOAT_DIC(addr,data) { *((PF_FLOAT *)(addr)) = (PF_FLOAT)(data); }\r |
| 530 | #define WRITE_CELL_DIC(addr,data) { *((cell_t *)(addr)) = (cell_t)(data); }\r |
| 531 | #define WRITE_SHORT_DIC(addr,data) { *((int16_t *)(addr)) = (int16_t)(data); }\r |
| 532 | #define READ_FLOAT_DIC(addr) ( *((PF_FLOAT *)(addr)) )\r |
| 533 | #define READ_CELL_DIC(addr) ( *((const ucell_t *)(addr)) )\r |
| 534 | #define READ_SHORT_DIC(addr) ( *((const uint16_t *)(addr)) )\r |
| 535 | \r |
| 536 | #endif\r |
| 537 | \r |
| 538 | \r |
| 539 | #define HEADER_HERE (gCurrentDictionary->dic_HeaderPtr.Cell)\r |
| 540 | #define CODE_HERE (gCurrentDictionary->dic_CodePtr.Cell)\r |
| 541 | #define CODE_COMMA( N ) WRITE_CELL_DIC(CODE_HERE++,(N))\r |
| 542 | #define NAME_BASE (gCurrentDictionary->dic_HeaderBase)\r |
| 543 | #define CODE_BASE (gCurrentDictionary->dic_CodeBase)\r |
| 544 | #define NAME_SIZE (gCurrentDictionary->dic_HeaderLimit - gCurrentDictionary->dic_HeaderBase)\r |
| 545 | #define CODE_SIZE (gCurrentDictionary->dic_CodeLimit - gCurrentDictionary->dic_CodeBase)\r |
| 546 | \r |
| 547 | #define IN_CODE_DIC(addr) ( ( ((uint8_t *)(addr)) >= gCurrentDictionary->dic_CodeBase) && ( ((uint8_t *)(addr)) < gCurrentDictionary->dic_CodeLimit) )\r |
| 548 | \r |
| 549 | #define IN_NAME_DIC(addr) ( ( ((uint8_t *)(addr)) >= gCurrentDictionary->dic_HeaderBase) && ( ((uint8_t *)(addr)) < gCurrentDictionary->dic_HeaderLimit) )\r |
| 550 | #define IN_DICS(addr) (IN_CODE_DIC(addr) || IN_NAME_DIC(addr))\r |
| 551 | \r |
| 552 | /* Address conversion */\r |
| 553 | #define ABS_TO_NAMEREL( a ) ((cell_t) (((ucell_t) a) - NAME_BASE ))\r |
| 554 | #define ABS_TO_CODEREL( a ) ((cell_t) (((ucell_t) a) - CODE_BASE ))\r |
| 555 | #define NAMEREL_TO_ABS( a ) ((ucell_t) (((cell_t) a) + NAME_BASE))\r |
| 556 | #define CODEREL_TO_ABS( a ) ((ucell_t) (((cell_t) a) + CODE_BASE))\r |
| 557 | \r |
| 558 | /* The check for >0 is only needed for CLONE testing. !!! */\r |
| 559 | #define IsTokenPrimitive(xt) ((xt<gNumPrimitives) && (xt>=0))\r |
| 560 | \r |
| 561 | #define FREE_VAR(v) { if (v) { pfFreeMem((void *)(v)); v = 0; } }\r |
| 562 | \r |
| 563 | #define DATA_STACK_DEPTH (gCurrentTask->td_StackBase - gCurrentTask->td_StackPtr)\r |
| 564 | #define DROP_DATA_STACK (gCurrentTask->td_StackPtr++)\r |
| 565 | #define POP_DATA_STACK (*gCurrentTask->td_StackPtr++)\r |
| 566 | #define PUSH_DATA_STACK(x) {*(--(gCurrentTask->td_StackPtr)) = (cell_t) x; }\r |
| 567 | \r |
| 568 | /* Force Quad alignment. */\r |
| 569 | #define QUADUP(x) (((x)+3)&~3)\r |
| 570 | \r |
| 571 | #define MIN(a,b) ( ((a)<(b)) ? (a) : (b) )\r |
| 572 | #define MAX(a,b) ( ((a)>(b)) ? (a) : (b) )\r |
| 573 | \r |
| 574 | \r |
| 575 | #ifndef TOUCH\r |
| 576 | #define TOUCH(argument) ((void)argument)\r |
| 577 | #endif\r |
| 578 | \r |
| 579 | /***************************************************************\r |
| 580 | ** I/O related macros\r |
| 581 | ***************************************************************/\r |
| 582 | \r |
| 583 | #define EMIT(c) ioEmit(c)\r |
| 584 | #define EMIT_CR EMIT('\n');\r |
| 585 | \r |
| 586 | #define MSG(cs) pfMessage(cs)\r |
| 587 | #define ERR(x) MSG(x)\r |
| 588 | \r |
| 589 | #define DBUG(x) /* PRT(x) */\r |
| 590 | #define DBUGX(x) /* DBUG(x) */\r |
| 591 | \r |
| 592 | #define MSG_NUM_D(msg,num) { MSG(msg); ffDot((cell_t) num); EMIT_CR; }\r |
| 593 | #define MSG_NUM_H(msg,num) { MSG(msg); ffDotHex((cell_t) num); EMIT_CR; }\r |
| 594 | \r |
| 595 | #define DBUG_NUM_D(msg,num) { pfDebugMessage(msg); pfDebugPrintDecimalNumber((cell_t) num); pfDebugMessage("\n"); }\r |
| 596 | \r |
| 597 | #endif /* _pf_guts_h */\r |