ref: 3ce06cd42417862d69f1df3b914aba5a09eddd72
dir: /src/asm/globlex.c/
#include "asm/asm.h" #include "asm/symbol.h" #include "asm/rpn.h" #include "asm/symbol.h" #include "asm/main.h" #include "asm/lexer.h" #include "asmy.h" #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> UBYTE oDontExpandStrings = 0; SLONG nGBGfxID = -1; SLONG nBinaryID = -1; SLONG gbgfx2bin(char ch) { SLONG i; for (i = 0; i <= 3; i += 1) { if (CurrentOptions.gbgfx[i] == ch) { return (i); } } return (0); } SLONG binary2bin(char ch) { SLONG i; for (i = 0; i <= 1; i += 1) { if (CurrentOptions.binary[i] == ch) { return (i); } } return (0); } SLONG char2bin(char ch) { if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 10); if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 10); if (ch >= '0' && ch <= '9') return (ch - '0'); return (0); } typedef SLONG(*x2bin) (char ch); SLONG ascii2bin(char *s) { SLONG radix = 10; SLONG result = 0; x2bin convertfunc = char2bin; switch (*s) { case '$': radix = 16; s += 1; convertfunc = char2bin; break; case '&': radix = 8; s += 1; convertfunc = char2bin; break; case '`': radix = 4; s += 1; convertfunc = gbgfx2bin; break; case '%': radix = 2; s += 1; convertfunc = binary2bin; break; } if (radix == 4) { SLONG c; while (*s != '\0') { c = convertfunc(*s++); result = result * 2 + ((c & 1) << 8) + ((c & 2) >> 1); } } else { while (*s != '\0') result = result * radix + convertfunc(*s++); } return (result); } ULONG ParseFixedPoint(char *s, ULONG size) { char dest[256]; ULONG i = 0, dot = 0; while (size && dot != 2) { if (s[i] == '.') dot += 1; if (dot < 2) { dest[i] = s[i]; size -= 1; i += 1; } } dest[i] = 0; yyunputbytes(size); yylval.nConstValue = (SLONG) (atof(s) * 65536); return (1); } ULONG ParseNumber(char *s, ULONG size) { char dest[256]; strncpy(dest, s, size); dest[size] = 0; yylval.nConstValue = ascii2bin(dest); return (1); } ULONG ParseSymbol(char *src, ULONG size) { char dest[MAXSYMLEN + 1]; int copied = 0, size_backup = size; while (size && copied < MAXSYMLEN) { if (*src == '\\') { char *marg; src += 1; size -= 1; if (*src == '@') marg = sym_FindMacroArg(-1); else if (*src >= '0' && *src <= '9') marg = sym_FindMacroArg(*src); else { fatalerror("Malformed ID"); return (0); } src += 1; size -= 1; if (marg) { while (*marg) dest[copied++] = *marg++; } } else { dest[copied++] = *src++; size -= 1; } } if (copied > MAXSYMLEN) fatalerror("Symbol too long"); dest[copied] = 0; if (oDontExpandStrings == 0 && sym_isString(dest)) { char *s; yyskipbytes(size_backup); yyunputstr(s = sym_GetStringValue(dest)); while (*s) { if (*s++ == '\n') { nLineNo -= 1; } } return (0); } else { strcpy(yylval.tzString, dest); return (1); } } ULONG PutMacroArg(char *src, ULONG size) { char *s; yyskipbytes(size); if ((s = sym_FindMacroArg(src[1] - '0')) != NULL) { yyunputstr(s); } else { yyerror("Macro argument not defined"); } return (0); } ULONG PutUniqueArg(char *src, ULONG size) { src = src; yyskipbytes(size); yyunputstr(sym_FindMacroArg(-1)); return (0); } enum { T_LEX_MACROARG = 3000, T_LEX_MACROUNIQUE }; extern struct sLexInitString localstrings[]; struct sLexInitString staticstrings[] = { { "||", T_OP_LOGICOR }, { "&&", T_OP_LOGICAND }, { "==", T_OP_LOGICEQU }, { ">", T_OP_LOGICGT }, { "<", T_OP_LOGICLT }, { ">=", T_OP_LOGICGE }, { "<=", T_OP_LOGICLE }, { "!=", T_OP_LOGICNE }, { "!", T_OP_LOGICNOT }, { "|", T_OP_OR }, { "^", T_OP_XOR }, { "&", T_OP_AND }, { "<<", T_OP_SHL }, { ">>", T_OP_SHR }, { "+", T_OP_ADD }, { "-", T_OP_SUB }, { "*", T_OP_MUL }, { "/", T_OP_DIV }, { "%", T_OP_MOD }, { "~", T_OP_NOT }, { "def", T_OP_DEF }, { "bank", T_OP_BANK }, { "div", T_OP_FDIV }, { "mul", T_OP_FMUL }, { "sin", T_OP_SIN }, { "cos", T_OP_COS }, { "tan", T_OP_TAN }, { "asin", T_OP_ASIN }, { "acos", T_OP_ACOS }, { "atan", T_OP_ATAN }, { "atan2", T_OP_ATAN2 }, { "strcmp", T_OP_STRCMP }, { "strin", T_OP_STRIN }, { "strsub", T_OP_STRSUB }, { "strlen", T_OP_STRLEN }, { "strcat", T_OP_STRCAT }, { "strupr", T_OP_STRUPR }, { "strlwr", T_OP_STRLWR }, { "include", T_POP_INCLUDE }, { "printt", T_POP_PRINTT }, { "printv", T_POP_PRINTV }, { "printf", T_POP_PRINTF }, { "export", T_POP_EXPORT }, { "xdef", T_POP_EXPORT }, { "import", T_POP_IMPORT }, { "xref", T_POP_IMPORT }, { "global", T_POP_GLOBAL }, { "ds", T_POP_DS }, { NAME_DB, T_POP_DB }, { NAME_DW, T_POP_DW }, #ifdef NAME_DL { NAME_DL, T_POP_DL }, #endif { "section", T_POP_SECTION }, { "purge", T_POP_PURGE }, { "rsreset", T_POP_RSRESET }, { "rsset", T_POP_RSSET }, { "incbin", T_POP_INCBIN }, { "fail", T_POP_FAIL }, { "warn", T_POP_WARN }, { "macro", T_POP_MACRO }, /* Not needed but we have it here just to protect the name */ { "endm", T_POP_ENDM }, { "shift", T_POP_SHIFT }, { "rept", T_POP_REPT }, /* Not needed but we have it here just to protect the name */ { "endr", T_POP_ENDR }, { "if", T_POP_IF }, { "else", T_POP_ELSE }, { "endc", T_POP_ENDC }, { "bss", T_SECT_BSS }, #if defined(GAMEBOY) || defined(PCENGINE) { "vram", T_SECT_VRAM }, #endif { "code", T_SECT_CODE }, { "data", T_SECT_CODE }, #ifdef GAMEBOY { "home", T_SECT_HOME }, { "hram", T_SECT_HRAM }, #endif { NAME_RB, T_POP_RB }, { NAME_RW, T_POP_RW }, #ifdef NAME_RL { NAME_RL, T_POP_RL }, #endif { "equ", T_POP_EQU }, { "equs", T_POP_EQUS }, { "set", T_POP_SET }, { "=", T_POP_SET }, { "pushs", T_POP_PUSHS }, { "pops", T_POP_POPS }, { "pusho", T_POP_PUSHO }, { "popo", T_POP_POPO }, { "opt", T_POP_OPT }, { NULL, 0 } }; struct sLexFloat tNumberToken = { ParseNumber, T_NUMBER }; struct sLexFloat tFixedPointToken = { ParseFixedPoint, T_NUMBER }; struct sLexFloat tIDToken = { ParseSymbol, T_ID }; struct sLexFloat tMacroArgToken = { PutMacroArg, T_LEX_MACROARG }; struct sLexFloat tMacroUniqueToken = { PutUniqueArg, T_LEX_MACROUNIQUE }; void setuplex(void) { ULONG id; lex_Init(); lex_AddStrings(staticstrings); lex_AddStrings(localstrings); // Macro arguments id = lex_FloatAlloc(&tMacroArgToken); lex_FloatAddFirstRange(id, '\\', '\\'); lex_FloatAddSecondRange(id, '0', '9'); id = lex_FloatAlloc(&tMacroUniqueToken); lex_FloatAddFirstRange(id, '\\', '\\'); lex_FloatAddSecondRange(id, '@', '@'); // Decimal constants id = lex_FloatAlloc(&tNumberToken); lex_FloatAddFirstRange(id, '0', '9'); lex_FloatAddSecondRange(id, '0', '9'); lex_FloatAddRange(id, '0', '9'); // Binary constants nBinaryID = id = lex_FloatAlloc(&tNumberToken); lex_FloatAddFirstRange(id, '%', '%'); lex_FloatAddSecondRange(id, CurrentOptions.binary[0], CurrentOptions.binary[0]); lex_FloatAddSecondRange(id, CurrentOptions.binary[1], CurrentOptions.binary[1]); lex_FloatAddRange(id, CurrentOptions.binary[0], CurrentOptions.binary[0]); lex_FloatAddRange(id, CurrentOptions.binary[1], CurrentOptions.binary[1]); // Octal constants id = lex_FloatAlloc(&tNumberToken); lex_FloatAddFirstRange(id, '&', '&'); lex_FloatAddSecondRange(id, '0', '7'); lex_FloatAddRange(id, '0', '7'); // Gameboy gfx constants nGBGfxID = id = lex_FloatAlloc(&tNumberToken); lex_FloatAddFirstRange(id, '`', '`'); lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0]); lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1]); lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2]); lex_FloatAddSecondRange(id, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3]); lex_FloatAddRange(id, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0]); lex_FloatAddRange(id, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1]); lex_FloatAddRange(id, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2]); lex_FloatAddRange(id, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3]); // Hex constants id = lex_FloatAlloc(&tNumberToken); lex_FloatAddFirstRange(id, '$', '$'); lex_FloatAddSecondRange(id, '0', '9'); lex_FloatAddSecondRange(id, 'A', 'F'); lex_FloatAddSecondRange(id, 'a', 'f'); lex_FloatAddRange(id, '0', '9'); lex_FloatAddRange(id, 'A', 'F'); lex_FloatAddRange(id, 'a', 'f'); // ID's id = lex_FloatAlloc(&tIDToken); lex_FloatAddFirstRange(id, 'a', 'z'); lex_FloatAddFirstRange(id, 'A', 'Z'); lex_FloatAddFirstRange(id, '_', '_'); lex_FloatAddSecondRange(id, 'a', 'z'); lex_FloatAddSecondRange(id, 'A', 'Z'); lex_FloatAddSecondRange(id, '0', '9'); lex_FloatAddSecondRange(id, '_', '_'); lex_FloatAddSecondRange(id, '\\', '\\'); lex_FloatAddSecondRange(id, '@', '@'); lex_FloatAddSecondRange(id, '#', '#'); lex_FloatAddRange(id, 'a', 'z'); lex_FloatAddRange(id, 'A', 'Z'); lex_FloatAddRange(id, '0', '9'); lex_FloatAddRange(id, '_', '_'); lex_FloatAddRange(id, '\\', '\\'); lex_FloatAddRange(id, '@', '@'); lex_FloatAddRange(id, '#', '#'); // Local ID id = lex_FloatAlloc(&tIDToken); lex_FloatAddFirstRange(id, '.', '.'); lex_FloatAddSecondRange(id, 'a', 'z'); lex_FloatAddSecondRange(id, 'A', 'Z'); lex_FloatAddSecondRange(id, '_', '_'); lex_FloatAddRange(id, 'a', 'z'); lex_FloatAddRange(id, 'A', 'Z'); lex_FloatAddRange(id, '0', '9'); lex_FloatAddRange(id, '_', '_'); lex_FloatAddRange(id, '\\', '\\'); lex_FloatAddRange(id, '@', '@'); lex_FloatAddRange(id, '#', '#'); // @ ID id = lex_FloatAlloc(&tIDToken); lex_FloatAddFirstRange(id, '@', '@'); // Fixed point constants id = lex_FloatAlloc(&tFixedPointToken); lex_FloatAddFirstRange(id, '.', '.'); lex_FloatAddFirstRange(id, '0', '9'); lex_FloatAddSecondRange(id, '.', '.'); lex_FloatAddSecondRange(id, '0', '9'); lex_FloatAddRange(id, '.', '.'); lex_FloatAddRange(id, '0', '9'); }