ref: 4d06e6de796e9e96f03f419b976bbc3dc19d2afe
dir: /src/asm/globlex.c/
#include "asm.h" #include "symbol.h" #include "rpn.h" #include "asmy.h" #include "symbol.h" #include "main.h" #include "lexer.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, "endm", T_POP_ENDM, // Not needed but we have it here just to protect the name "shift", T_POP_SHIFT, "rept", T_POP_REPT, "endr", T_POP_ENDR, // Not needed but we have it here just to protect the name "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'); }