Files
gw-basic-2026/include/tokens.h
Eremey Valetov d8e8375366 Phase 1: expression calculator with direct mode
GW-BASIC reimplementation in C11, using Microsoft's open-sourced 8088
assembly as the authoritative reference.

Tokenizer (CRUNCH/LIST), expression evaluator with operator precedence,
all math functions (SIN, COS, TAN, ATN, SQR, LOG, EXP, RND, etc.),
string functions (LEFT$, RIGHT$, MID$, CHR$, ASC, VAL, STR$, etc.),
PRINT statement with comma/semicolon zones, TAB(), SPC().

Handles integer/single/double types with correct promotion, D exponent
for double-precision literals, type suffixes (%, !, #), &H hex/&O octal
literals, MBF conversion routines, and GW-BASIC-compatible number
formatting.

Platform-independent via HAL vtable; POSIX backend included.
2026-02-10 10:25:08 -05:00

232 lines
7.9 KiB
C

#ifndef GW_TOKENS_H
#define GW_TOKENS_H
#include <stdint.h>
/*
* Token values derived from IBMRES.ASM.
* Single-byte tokens: 0x80-0xF9
* Two-byte tokens: 0xFD xx (extended functions), 0xFE xx (extended stmts),
* 0xFF xx (built-in functions)
*/
/* Statement tokens (STMDSP) - starting at 128 */
#define TOK_END 0x80 /* 128 */
#define TOK_FOR 0x81 /* 129 */
#define TOK_NEXT 0x82 /* 130 */
#define TOK_DATA 0x83 /* 131 */
#define TOK_INPUT 0x84 /* 132 */
#define TOK_DIM 0x85 /* 133 */
#define TOK_READ 0x86 /* 134 */
#define TOK_LET 0x87 /* 135 */
#define TOK_GOTO 0x88 /* 136 */
#define TOK_RUN 0x89 /* 137 */
#define TOK_IF 0x8A /* 138 */
#define TOK_RESTORE 0x8B /* 139 */
#define TOK_GOSUB 0x8C /* 140 */
#define TOK_RETURN 0x8D /* 141 */
#define TOK_REM 0x8E /* 142 */
#define TOK_STOP 0x8F /* 143 */
#define TOK_PRINT 0x90 /* 144 */
#define TOK_CLEAR 0x91 /* 145 */
#define TOK_LIST 0x92 /* 146 */
#define TOK_NEW 0x93 /* 147 */
#define TOK_ON 0x94 /* 148 */
#define TOK_WAIT 0x95 /* 149 */
#define TOK_DEF 0x96 /* 150 */
#define TOK_POKE 0x97 /* 151 */
#define TOK_CONT 0x98 /* 152 */
/* 153-154: padding (SNERR) */
#define TOK_OUT 0x9B /* 155 */
#define TOK_LPRINT 0x9C /* 156 */
#define TOK_LLIST 0x9D /* 157 */
/* 158: padding */
#define TOK_WIDTH 0x9F /* 159 */
#define TOK_ELSE 0xA0 /* 160 */
#define TOK_TRON 0xA1 /* 161 */
#define TOK_TROFF 0xA2 /* 162 */
#define TOK_SWAP 0xA3 /* 163 */
#define TOK_ERASE 0xA4 /* 164 */
#define TOK_EDIT 0xA5 /* 165 */
#define TOK_ERROR 0xA6 /* 166 */
#define TOK_RESUME 0xA7 /* 167 */
#define TOK_DELETE 0xA8 /* 168 */
#define TOK_AUTO 0xA9 /* 169 */
#define TOK_RENUM 0xAA /* 170 */
#define TOK_DEFSTR 0xAB /* 171 */
#define TOK_DEFINT 0xAC /* 172 */
#define TOK_DEFSNG 0xAD /* 173 */
#define TOK_DEFDBL 0xAE /* 174 */
#define TOK_LINE 0xAF /* 175 */
#define TOK_WHILE 0xB0 /* 176 */
#define TOK_WEND 0xB1 /* 177 */
#define TOK_CALL 0xB2 /* 178 */
/* 179-181: padding */
#define TOK_WRITE 0xB6 /* 182 */
#define TOK_OPTION 0xB7 /* 183 */
#define TOK_RANDOMIZE 0xB8 /* 184 */
#define TOK_OPEN 0xB9 /* 185 */
#define TOK_CLOSE 0xBA /* 186 */
#define TOK_LOAD 0xBB /* 187 */
#define TOK_MERGE 0xBC /* 188 */
#define TOK_SAVE 0xBD /* 189 */
#define TOK_COLOR 0xBE /* 190 */
#define TOK_CLS 0xBF /* 191 */
#define TOK_MOTOR 0xC0 /* 192 */
#define TOK_BSAVE 0xC1 /* 193 */
#define TOK_BLOAD 0xC2 /* 194 */
#define TOK_SOUND 0xC3 /* 195 */
#define TOK_BEEP 0xC4 /* 196 */
#define TOK_PSET 0xC5 /* 197 */
#define TOK_PRESET 0xC6 /* 198 */
#define TOK_SCREEN 0xC7 /* 199 */
#define TOK_KEY 0xC8 /* 200 */
#define TOK_LOCATE 0xC9 /* 201 */
/* Non-statement keyword tokens */
#define TOK_TO 0xCA /* 202 */
#define TOK_THEN 0xCB /* 203 */
#define TOK_TAB 0xCC /* 204 */
#define TOK_STEP 0xCD /* 205 */
#define TOK_USR 0xCE /* 206 */
#define TOK_FN 0xCF /* 207 */
#define TOK_SPC 0xD0 /* 208 */
#define TOK_NOT 0xD1 /* 209 */
#define TOK_ERL 0xD2 /* 210 */
#define TOK_ERR 0xD3 /* 211 */
#define TOK_STRINGS 0xD4 /* 212 - STRING$ */
#define TOK_USING 0xD5 /* 213 */
#define TOK_INSTR 0xD6 /* 214 */
#define TOK_SQUOTE 0xD7 /* 215 - ' (single quote = REM) */
#define TOK_VARPTR 0xD8 /* 216 */
#define TOK_CSRLIN 0xD9 /* 217 */
#define TOK_POINT 0xDA /* 218 */
#define TOK_OFF 0xDB /* 219 */
#define TOK_INKEYS 0xDC /* 220 - INKEY$ */
/* Operator tokens (after 7-byte gap at 221-227) */
#define TOK_GT 0xE4 /* 228 - > */
#define TOK_EQ 0xE5 /* 229 - = */
#define TOK_LT 0xE6 /* 230 - < */
#define TOK_PLUS 0xE7 /* 231 - + */
#define TOK_MINUS 0xE8 /* 232 - - */
#define TOK_MUL 0xE9 /* 233 - * */
#define TOK_DIV 0xEA /* 234 - / */
#define TOK_POW 0xEB /* 235 - ^ */
#define TOK_AND 0xEC /* 236 */
#define TOK_OR 0xED /* 237 */
#define TOK_XOR 0xEE /* 238 */
#define TOK_EQV 0xEF /* 239 */
#define TOK_IMP 0xF0 /* 240 */
#define TOK_MOD 0xF1 /* 241 */
#define TOK_IDIV 0xF2 /* 242 - \ (integer division) */
/* Multi-byte token prefixes */
#define TOK_PREFIX_FD 0xFD /* extended functions */
#define TOK_PREFIX_FE 0xFE /* extended statements */
#define TOK_PREFIX_FF 0xFF /* built-in functions */
/* Built-in function tokens (prefix 0xFF) */
#define FUNC_LEFT 0x80 /* 128 */
#define FUNC_RIGHT 0x81 /* 129 */
#define FUNC_MID 0x82 /* 130 */
#define FUNC_SGN 0x83 /* 131 */
#define FUNC_INT 0x84 /* 132 */
#define FUNC_ABS 0x85 /* 133 */
#define FUNC_SQR 0x86 /* 134 */
#define FUNC_RND 0x87 /* 135 */
#define FUNC_SIN 0x88 /* 136 */
#define FUNC_LOG 0x89 /* 137 */
#define FUNC_EXP 0x8A /* 138 */
#define FUNC_COS 0x8B /* 139 */
#define FUNC_TAN 0x8C /* 140 */
#define FUNC_ATN 0x8D /* 141 */
#define FUNC_FRE 0x8E /* 142 */
#define FUNC_INP 0x8F /* 143 */
#define FUNC_POS 0x90 /* 144 */
#define FUNC_LEN 0x91 /* 145 */
#define FUNC_STR 0x92 /* 146 */
#define FUNC_VAL 0x93 /* 147 */
#define FUNC_ASC 0x94 /* 148 */
#define FUNC_CHR 0x95 /* 149 */
#define FUNC_PEEK 0x96 /* 150 */
#define FUNC_SPACE 0x97 /* 151 */
#define FUNC_OCT 0x98 /* 152 */
#define FUNC_HEX 0x99 /* 153 */
#define FUNC_LPOS 0x9A /* 154 */
#define FUNC_CINT 0x9B /* 155 */
#define FUNC_CSNG 0x9C /* 156 */
#define FUNC_CDBL 0x9D /* 157 */
#define FUNC_FIX 0x9E /* 158 */
#define FUNC_PEN 0x9F /* 159 */
#define FUNC_STICK 0xA0 /* 160 */
#define FUNC_STRIG 0xA1 /* 161 */
#define FUNC_EOF 0xA2 /* 162 */
#define FUNC_LOC 0xA3 /* 163 */
#define FUNC_LOF 0xA4 /* 164 */
/* Extended statement tokens (prefix 0xFE) */
#define XSTMT_FILES 0x80
#define XSTMT_FIELD 0x81
#define XSTMT_SYSTEM 0x82
#define XSTMT_NAME 0x83
#define XSTMT_LSET 0x84
#define XSTMT_RSET 0x85
#define XSTMT_KILL 0x86
#define XSTMT_PUT 0x87
#define XSTMT_GET 0x88
#define XSTMT_RESET 0x89
#define XSTMT_COMMON 0x8A
#define XSTMT_CHAIN 0x8B
#define XSTMT_DATE 0x8C
#define XSTMT_TIME 0x8D
#define XSTMT_PAINT 0x8E
#define XSTMT_COM 0x8F
#define XSTMT_CIRCLE 0x90
#define XSTMT_DRAW 0x91
#define XSTMT_PLAY 0x92
#define XSTMT_TIMER 0x93
#define XSTMT_ERDEV 0x94
#define XSTMT_IOCTL 0x95
#define XSTMT_CHDIR 0x96
#define XSTMT_MKDIR 0x97
#define XSTMT_RMDIR 0x98
#define XSTMT_SHELL 0x99
#define XSTMT_ENVIRON 0x9A
#define XSTMT_VIEW 0x9B
#define XSTMT_WINDOW 0x9C
#define XSTMT_PMAP 0x9D
#define XSTMT_PALETTE 0x9E
#define XSTMT_LCOPY 0x9F
#define XSTMT_CALLS 0xA0
/* Extended function tokens (prefix 0xFD) */
#define XFUNC_CVI 0x80
#define XFUNC_CVS 0x81
#define XFUNC_CVD 0x82
#define XFUNC_MKI 0x83
#define XFUNC_MKS 0x84
#define XFUNC_MKD 0x85
/* Special token constants - embedded constant prefixes */
#define TOK_COLON ':' /* statement separator (not tokenized) */
#define TOK_INT2 0x0E /* 2-byte integer (int16_t follows) */
#define TOK_INT1 0x0F /* 1-byte integer 0-255 (uint8_t follows) */
/* 0x11-0x1A: literal integers 0-9 (no data bytes) */
#define TOK_CONST_SNG 0x1C /* single-precision (4 bytes IEEE follow) */
#define TOK_CONST_DBL 0x1F /* double-precision (8 bytes IEEE follow) */
/* Keyword table entry */
typedef struct {
const char *name;
uint8_t token; /* token value (or second byte for multi-byte) */
uint8_t prefix; /* 0 for single-byte, 0xFD/0xFE/0xFF for multi */
} keyword_entry_t;
extern const keyword_entry_t gw_keywords[];
extern int gw_keyword_count;
const char *gw_token_name(uint8_t prefix, uint8_t token);
#endif