home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------------------------------------------------------- */
- /* Copyright (C) 1991 by Natürlich! */
- /* This file is copyrighted! */
- /* Refer to the documentation for details. */
- /* ---------------------------------------------------------------------- */
- #define DEBUG 0
- #define TOKDEBUG 0 /* following set 4 Atari 8MHz */
- #define FINPUT_IO 1 /* yields 15% speed increase */
- #define QINPUT_IO 1 /* yields 20% speed increase */
- #define USEINLINE 0
- #define QSTRING 0 /* 1 == doesn't do much */
- #define QWHITE 1
- #define QCOMMENT 1
- #define QIDENT 1
- #define QIDENT2 0 /* 1 == worsens performance ! */
- #define QLABEL 0 /* 1 == doesn't do anything */
- #define QMACRO 0 /* 1 == same or worse */
- #define QDIRECT 0 /* 1 == doesn't do anything */
-
- /* --------------------------------------------------------- */
- /* SHIT!! FLEX can't digest characters >= 128 */
- /* Now I have to write my own lexer... */
- /* --------------------------------------------------------- */
- #include "defines.h"
- #include "nasm.h"
- #include "y_tab.h"
- #include <stdio.h>
- #if OS == TOS
- #include <osbind.h>
- #endif
- #include <setjmp.h>
-
- #include "debug.h"
- #include "code.h"
- #include NMALLOC_H
- #if VERSION && FINPUT_IO
- extern buffer huge *bp;
- # include "inputfst.h"
- #endif
-
- #define LINESTART 0
- #define INSTRUCTION 1
- #define AFTERINSTR 2
- #define AFTERELSE 3
- #define AFTEROPTION 4
- #define AFTERFLOAT 5
- #define AFTERINCLUDE 6
- #define COMMENT 7
-
- #define E_GARBAGE garbage /* historic */
- #define E_LABELFORM labelform
- #define E_HEXLEN hexlen
- #define E_INTSIZE intsize
-
- static char
- igarbage[] = "Garbage in the instruction field",
- garbage[] = "Totally uncomprehendable garbage",
- labelform[] = "Label starts off with wrong character",
- hexlen[] = "Hex value exceeds 16 Bit (not that good on a 64K machine)",
- intsize[] = "Integer value >= 65536, how would that fit into 2 bytes ?",
- mpara_incomplete[] =
- "Incomplete macro parameter (form %[$]<[0-9]+|(<label>))";
-
- /* --------------------------------------------------------- */
- /* The ultra-clever (har har) way of deciding whether we are */
- /* facing something usable as an identifier character. */
- /* There is a method to this madness: */
- /* Bit7 . Bit6 . Bit5 . Bit4 . Bit3 . Bit2 . Bit1 . Bit0 */
- /* -----+------+------+------+------+------+------+----- */
- /* Lower| | | Foo | A-Z |Float | Hex | No */
- /* -----+------+------+------+------+------+------+----- */
- /* $80 $40 $20 $10 $08 $04 $02 $01 */
- /* */
- /* A question remains, are we losing with this table ?? */
- /* --------------------------------------------------------- */
- #define is_ident( c) (is_what[ (c)])
- #define is_lower( c) ((signed char) is_what[ (c)] < 0)
- #define is_hex( c) (is_what[ (c)] & M_HEX)
- #define is_digit( c) (is_what[ (c)] == DIGIT)
- #define is_letter( c) (is_what[ (c)] & M_LETTER)
- #define is_float( c) (is_what[ (c)] & M_FLOAT)
-
- #define tis_ident( c) (p_table[ (c)])
- #define tis_lower( c) ((signed char) p_table[ (c)] < 0)
- #define tis_hex( c) (p_table[ (c)] & M_HEX)
- #define tis_digit( c) (p_table[ (c)] == DIGIT)
- #define tis_letter( c) (p_table[ (c)] & M_LETTER)
- #define tis_float( c) (p_table[ (c)] & M_FLOAT)
-
- #define M_LOWER 0x80
- #define M_FOO 0x10
- #define M_LETTER 0x08
- #define M_FLOAT 0x04
- #define M_HEX 0x02
- #define M_DIGIT 0x01
-
- #define DIGIT (M_DIGIT | M_HEX | M_FLOAT)
- #define L (M_LETTER | M_LOWER) /* lower */
- #define A M_LETTER /* upper */
- #define H (M_LETTER | M_HEX) /* up&hex */
- #define E (M_LETTER | M_HEX | M_FLOAT)
- #define P M_FLOAT
- #define X M_FOO
- #define N DIGIT
-
-
- byte is_what[] = /* xlat: is' watt !?!? */
- {
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $00 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $10 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,P,0, /* $20 */
- N,N,N,N, N,N,N,N, N,N,X,0, 0,0,0,X, /* $30 */
-
- X,H,H,H, H,E,H,A, A,A,A,A, A,A,A,A, /* $40 */
- A,A,A,A, A,A,A,A, A,A,A,0, 0,0,0,X, /* $50 */
- 0,L,L,L, L,L,L,L, L,L,L,L, L,L,L,L, /* $60 */
- L,L,L,L, L,L,L,L, L,L,L,0, 0,0,0,0, /* $70 */
-
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $80 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $90 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $A0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $B0 */
-
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $C0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $D0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $E0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 /* $F0 */
- };
-
- #undef F
- #undef N
- #undef L
- #undef A
- #undef H
- #undef E
- #undef P
- #undef X
-
-
- #define is_white( c) (white[ (c)])
- #define skip_white(c) while( white[ c]) c = uinput()
- #define tis_white( c) (p_table[ (c)])
- #define tskip_white(c) while( p_table[ c]) c = uinput()
-
- static char white[] = /* ain't no saying whether this actually */
- { /* helps improve the speed */
- 0,0,0,0, 0,0,0,0, 0,1,0,0, 0,1,0,0, /* $00 */
- 0,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,0, /* $10 */ /* $1A for MSDOS */
- 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $20 */ /* whatever that */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $30 */ /* might be */
-
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $40 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $50 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $60 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $70 */
-
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $80 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $90 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $A0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $B0 */
-
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $C0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $D0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $E0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 /* $F0 */
- };
-
- #define A 0x01 /* 'X' */
- #define B 0x02 /* 'Y' */
-
- #define C 0x03 /* '#' */
-
- #define D 0x04 /* '(' */
- #define E 0x05 /* ')' */
- #define F 0x06 /* ',' */
- #define G 0x07 /* '=' */
- #define H 0x08 /* '+' */
- #define I 0x09 /* '-' */
- #define J 0x0A /* '!' */
- #define K 0x0B /* '&' */
- #define L 0x0C /* '*' */
- #define M 0x0D /* '/' */
- #define N 0x0E /* '\\' */
- #define O 0x0F /* '^' */
- #define P 0x10 /* '[' */
- #define Q 0x11 /* ']' */
- #define IREGS 0x02
-
- static byte af1_toks[] =
- {
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $00 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $10 */
- 0,J,0,C, 0,0,K,0, D,E,L,H, F,I,0,M, /* $20 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,G,0,0, /* $30 */
-
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $40 */
- 0,0,0,0, 0,0,0,0, A,B,0,P, N,Q,O,0, /* $50 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $60 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $70 */
-
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $80 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $90 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $A0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $B0 */
-
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $C0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $D0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $E0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 /* $F0 */
- };
-
- static byte af2_toks[] =
- {
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $00 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $10 */
- 0,J,0,0, 0,0,K,0, D,E,L,H, F,I,0,M, /* $20 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,G,0,0, /* $30 */
-
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $40 */
- 0,0,0,0, 0,0,0,0, 0,0,0,P, N,Q,O,0, /* $50 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $60 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $70 */
-
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $80 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $90 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $A0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $B0 */
-
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $C0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $D0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, /* $E0 */
- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 /* $F0 */
- };
- #undef A
- #undef B
- #undef C
- #undef D
- #undef E
- #undef F
- #undef G
- #undef H
- #undef I
- #undef J
- #undef K
- #undef L
- #undef M
- #undef N
- #undef O
- #undef P
- #undef Q
-
-
- #if DEBUG /* Bugs ? Yeah SURE we gottem.. All sizes and shapes! */
- #define dreturn( val) \
- { \
- int foo = (val); \
- prtname( foo); \
- LEAVE(); \
- return( foo); \
- }
-
- #define xreturn( val) \
- { \
- int foo = (val); \
- \
- LEAVE(); \
- return( foo); \
- }
-
- #define fdreturn( val) \
- { \
- int foo = (val); \
- \
- c = uinput(); \
- prtname( foo); \
- LEAVE(); \
- return( foo); \
- }
-
- #else
- #define dreturn return
- #define xreturn return
- #define fdreturn( val) \
- { \
- c = uinput(); \
- return( val); \
- }
- #endif
-
- #define comparators() \
- if( c_ == '<') \
- if( (c_ = uinput()) == '>') \
- { \
- c = c_; \
- fdreturn( T_NEQ); \
- } \
- else \
- if( (c = c_) == '=') \
- { \
- fdreturn( T_LEQ); \
- } \
- else \
- dreturn( '<'); \
- \
- if( c_ == '>') \
- { \
- if( (c = uinput()) == '=') \
- { \
- fdreturn( T_GEQ); \
- } \
- dreturn( '>'); \
- }
-
- extern lword yylval;
- extern freshflag;
-
- static char miss_char[] = "Missing character after \' (quote)",
- yytext[1024];
- int state = LINESTART,
- wasstrlen,
- #if __NSTDC__
- (*gettoken)( void);
- #else
- (*gettoken)();
- #endif
-
- byte c;
- #if VERSION
- static byte tmp;
- #endif
- jmp_buf syn_panic;
-
- #if DEBUG
- int syndebug;
- #endif
-
-
- int nilexer()
- {
- yylval = 0;
- return(0);
- }
-
-
- int yylex()
- {
- ENTER("yylex");
- #if TOKDEBUG
- {
- int i = (*gettoken)();
-
- prtname( i);
- xreturn( i);
- }
- #else
- # if OS == TOS && WITHNOISY
- {
- extern int noisytok, _in_macro;
-
- if( noisytok)
- {
- static unsigned char fx[] =
- {
- 2, 0, 3, 0, 9, 8, 7, 0xFD, 0xFF, 10,
- 7, 0xFF, 0xFF, 0
- };
- int tok = (*gettoken)();
-
-
- fx[1] = tok & 0x3F;
- fx[3] = _in_macro;
- Dosound( fx);
- xreturn( tok);
- }
- }
- # endif
- xreturn((*gettoken)());
- #endif
- }
-
-
- int lexer()
- {
- register byte c_ = c,
- *p_table = (byte *) white;
-
- ENTER( "lexer");
- if( freshflag) /* Have we set syn_panic already ?? */
- {
- freshflag = 0; /* No clr flag */
- #if DEBUG
- SAVESTATE( &syndebug);
- #endif
- if( setjmp( syn_panic)) /* Do the setjmp ONCE */
- {
- #if DEBUG
- SETBACK( syndebug);
- #endif
- MESS("\007\t\tsyntax panic occurred");
- while( c_ != '\n') /* If a longjmp() happens: ignore line */
- c_ = uinput();
- state = LINESTART; /* reset state */
- }
- }
-
-
- if( tis_white( c_)) /* TOS files have white before LF */
- {
- #if VERSION && FINPUT_IO && QINPUT_IO && QWHITE
- register byte huge *pt = bp->p;
- register byte *tab = _uptable;
- register lword rem = bp->remain;
-
- while( tis_white( c_ = quinput( rem, pt, tab)));
- if( bp)
- {
- bp->remain = rem;
- bp->p = pt;
- }
- #else
- while( tis_white( c_ = uinput()));
- #endif
- if( state == LINESTART)
- state = INSTRUCTION;
- }
-
- if( c_ == ';' || state == COMMENT)
- {
- #if VERSION && FINPUT_IO && QINPUT_IO && QCOMMENT
- register byte huge *pt = bp->p;
- register byte *tab = _uptable;
- register lword rem = bp->remain;
-
- while( (c_ = quinput( rem, pt, tab)) != '\n');
- if( bp)
- {
- bp->remain = rem;
- bp->p = pt;
- }
- #else
- while( (c_ = uinput()) != '\n');
- #endif
- }
-
- if( c_ == '\n')
- {
- state = LINESTART;
- c = c_;
- fdreturn( T_EOL);
- }
-
- #if USEINLINE
- switch( state)
- {
- case LINESTART :
- IMESS("[LINESTART] c == %d", (lword) c_, 2);
- state = INSTRUCTION;
- if( is_ident( c = c_))
- {
- xreturn( label_suckin());
- }
- else
- junk_suckin( E_GARBAGE);
-
-
- case INSTRUCTION :
- IMESS("[INSTRUCTION c=='%c']", (lword) c_, 1);
- if( c_ == '.')
- {
- c = c_;
- state = AFTERELSE;
- xreturn( directive_suckin());
- }
- if( is_ident( c = c_))
- {
- state = AFTERINSTR;
- xreturn( macro_suckin()); /* macros and instructions too */
- }
- state = AFTERELSE;
- if( c_ == '=')
- fdreturn( c_);
- if( c_ == '*')
- {
- while( tis_white( c_ = uinput()));
- if( c_ == '=')
- fdreturn( T_ORG);
- c_ = '*';
- }
- yytext[0] = c = c_;
- yytext[1] = 0;
- lsyntax( igarbage);
-
-
- case AFTERINSTR :
- MESS("[AFTERINSTR]");
- switch( c_)
- {
- case '$' : xreturn( hex_suckin());
- case '.' : xreturn( directive_suckin());
- case '%' : xreturn( para_suckin());
- case '\'':
- {
- if( tis_white( c = input()))
- lsyntax(miss_char);
- yylval = (lword) c;
- fdreturn( T_CHAR);
- }
- }
- if( is_digit( c = c_))
- xreturn( int_suckin());
- {
- register int a;
-
- if( a = af1_toks[ c_])
- {
- if( is_ident( c = uinput()) && a <= IREGS)
- xreturn( ident2_suckin( c_));
- dreturn( c_);
- }
- }
- if( is_ident( c_))
- xreturn( ident_suckin());
- comparators();
- junk_suckin( garbage);
-
-
- case AFTERELSE :
- MESS("[AFTERELSE]");
- switch( c_)
- {
- case '%' : xreturn( para_suckin());
- case '"' : xreturn( string_suckin());
- case '$' : xreturn( hex_suckin());
- case '.' : xreturn( directive_suckin());
- case '\'': if( tiswhite( c = input()))
- lsyntax(miss_char);
- yylval = (lword) c;
- fdreturn( T_CHAR);
- }
- if( is_digit( c = c_))
- xreturn( int_suckin());
- if( af2_toks[ c_])
- fdreturn( c_);
- if( is_ident(c_))
- xreturn( ident_suckin());
- comparators();
- junk_suckin( garbage);
-
-
- case AFTEROPTION :
- MESS("[AFTEROPTION]");
- if( c_ == ',')
- fdreturn( c_);
- c = c_;
- xreturn( option_suckin());
-
-
- case AFTERINCLUDE :
- MESS("[AFTERINCLUDE]");
- if( c_ == '#')
- fdreturn( c_);
- c = c_;
- xreturn( file_suckin());
-
- case AFTERFLOAT :
- MESS("[AFTERFLOAT]");
- if( c_ == ',')
- fdreturn( c_);
- c = c_;
- xreturn( float_suckin());
- }
- nierror("problems with the lexer state");
- }
- #else
- switch( state)
- {
- case LINESTART :
- IMESS("[LINESTART] c == %d", (lword) c, 2);
- state = INSTRUCTION;
- if( is_ident(c = c_))
- {
- xreturn( label_suckin());
- }
- else
- junk_suckin( E_GARBAGE);
-
- case INSTRUCTION :
- IMESS("[INSTRUCTION c=='%c']", (lword) c_, 1);
- if( (c = c_) == '.')
- {
- state = AFTERELSE;
- xreturn( directive_suckin());
- }
- if( is_ident( c))
- {
- state = AFTERINSTR;
- xreturn( macro_suckin()); /* macros and instructions too */
- }
- MESS("**HIT THIS***");
- state = AFTERELSE;
- if( c_ == '=')
- fdreturn( c_);
- if( c_ == '*')
- {
- while( tis_white( c_ = uinput()));
- if( c_ == '=')
- fdreturn( T_ORG);
- c_ = '*';
- }
- yytext[0] = c = c_;
- yytext[1] = 0;
- lsyntax( igarbage);
-
-
- case AFTERINSTR :
- {
- register int a;
-
- MESS("[AFTERINSTR]");
- if( a = af1_toks[ c_])
- {
- if( is_ident( c = uinput()) && a <= IREGS)
- xreturn( ident2_suckin( c_));
- dreturn( c_);
- }
- comparators();
- c = c_;
- xreturn( get_itoken());
- }
-
- case AFTERELSE :
- {
- MESS("[AFTERELSE]");
- if( af2_toks[ c_])
- fdreturn( c_);
- comparators();
- c = c_;
- xreturn( get_etoken());
- }
-
- case AFTEROPTION:
- MESS("[AFTEROPTION]");
- if( c_ == ',')
- fdreturn( c_);
- c = c_;
- xreturn( option_suckin());
-
- case AFTERFLOAT:
- MESS("[AFTERFLOAT]");
- if( c_ == ',')
- fdreturn( c_);
- c = c_;
- xreturn( float_suckin());
-
- case AFTERINCLUDE:
- MESS("[AFTERINCLUDE]");
- if( c_ == '#')
- fdreturn( c_);
- c = c_;
- xreturn( file_suckin());
- }
- nierror("problems with the lexer state");
- #if __NSTDC__ && VERY_PRETTY
- return(0);
- #endif
- }
-
- /* ------------------------------------------------------------- */
- /* Stands for: Get after instruction token. */
- /* ------------------------------------------------------------- */
- get_itoken()
- {
- ENTER("get_itoken");
- switch( c)
- {
- case '$' : xreturn( hex_suckin());
- case '.' : xreturn( directive_suckin());
- case '%' : xreturn( para_suckin());
- case '\'': if( is_white( c = input()))
- lsyntax(miss_char);
- yylval = (lword) c;
- fdreturn( T_CHAR);
- }
- if( is_digit(c))
- xreturn( int_suckin());
- if( is_ident( c))
- xreturn( ident_suckin());
- junk_suckin( garbage);
- #if __NSTDC__ && VERY_PRETTY
- return(0);
- #endif
- }
-
- /* ------------------------------------------------------------- */
- /* Stands for: Get after macro call token. */
- /* ------------------------------------------------------------- */
- get_etoken()
- {
- ENTER("get_etoken");
- IMESS("c = '%c'", (lword) c, 1);
- switch( c)
- {
- case '%' : xreturn( para_suckin());
- case '"' : xreturn( string_suckin());
- case '$' : xreturn( hex_suckin());
- case '.' : xreturn( directive_suckin());
- case '\'': if( is_white( c = input()))
- lsyntax(miss_char);
- yylval = (lword) c;
- fdreturn( T_CHAR);
- }
- if( is_digit(c))
- xreturn( int_suckin());
- if( is_ident(c))
- xreturn( ident_suckin());
- junk_suckin( garbage);
- #if __NSTDC__ && VERY_PRETTY
- return(0);
- #endif
- }
- #endif
-
- /* ------------------------------------------------------------- */
- /* Stands for: Get after macro call token. */
- /* ------------------------------------------------------------- */
- para_suckin()
- {
- ENTER("para_suckin");
-
- switch( c = uinput())
- {
- case '(' :
- MESS("way1a");
- while( is_white( c = uinput()));
- if( is_ident( c))
- {
- MESS("way1b");
- ident_suckin();
- skip_white( c);
- if( c == ')')
- fdreturn( T_MLPARA)
- }
- break;
-
- case '$' :
- MESS("way2a");
- if( is_digit( c = uinput()))
- {
- int_suckin();
- dreturn( T_MSPARA);
- }
- if( c == '(')
- {
- MESS("way2b");
- while( is_white( c = uinput()));
- if( is_ident( c))
- {
- MESS("way2c");
- ident_suckin();
- skip_white( c);
- if( c == ')')
- fdreturn( T_MLSPARA)
- }
- }
- break;
-
- default :
- IMESS("way3 c = '%c'", (lword) c, 1);
- if( is_digit( c))
- {
- int_suckin();
- dreturn( T_MPARA);
- }
- }
- lsyntax( mpara_incomplete);
- }
-
-
- ident_suckin()
- {
- register byte *p = (byte *) yytext,
- c_ = c,
- *p_table = is_what;
- register int i = 1;
-
- ENTER("ident_suckin");
- #if VERSION && FINPUT_IO && QINPUT_IO && QIDENT
- {
- register byte huge *pt = bp->p;
- register byte *tab = _uptable;
- register lword rem = bp->remain;
-
- do
- {
- *p++ = c_;
- i++;
- }
- while( tis_ident( c_ = quinput( rem, pt, tab)));
- if( bp)
- {
- bp->remain = rem;
- bp->p = pt;
- }
- }
- #else
- do
- {
- *p++ = c_; /* convert to upper & save */
- i++;
- }
- while( tis_ident( c_ = uinput()));
- #endif
-
- *p = 0;
- c = c_;
- if( state == AFTERINSTR)
- if( ! yytext[1] && yytext[0] == 'A')
- xreturn( T_ACCU);
- yy_txt2val( i);
- dreturn( T_IDENT);
- }
-
-
- ident2_suckin( extra)
- char extra;
- {
- register byte *p = (byte *) yytext,
- c_ = c,
- *p_table = is_what;
- register int i = 2;
-
- ENTER("ident2_suckin");
- *p++ = extra;
-
- #if VERSION && FINPUT_IO && QINPUT_IO && QIDENT2
- {
- register byte huge *pt = bp->p;
- register byte *tab = _uptable;
- register lword rem = bp->remain;
-
- do
- {
- *p++ = c_;
- i++;
- }
- while( tis_ident( c_ = quinput( rem, pt, tab)));
- if( bp)
- {
- bp->remain = rem;
- bp->p = pt;
- }
- }
- #else
- do
- {
- *p++ = c_; /* convert to upper & save */
- i++;
- }
- while( tis_ident(c_ = uinput()));
- #endif
- *p = 0;
- c = c_;
- if( state == AFTERINSTR)
- if( ! yytext[1] && yytext[0] == 'A')
- xreturn( T_ACCU);
- yy_txt2val( i);
- dreturn( T_IDENT);
- }
-
-
- label_suckin()
- {
- register char *p = yytext,
- c_ = c,
- *p_table = (char *) is_what;
- register int i = 1;
-
- ENTER("label_suckin");
- if( c_ == '.' || tis_digit( c_))
- {
- c = c_;
- lsyntax( E_LABELFORM);
- }
-
- #if VERSION && FINPUT_IO && QINPUT_IO && QLABEL
- {
- register byte huge *pt = bp->p;
- register byte *tab = _uptable;
- register lword rem = bp->remain;
-
- while( tis_ident( c_))
- {
- *p++ = c_;
- i++;
- c_ = quinput( rem, pt, tab);
- }
- if( bp)
- {
- bp->remain = rem;
- bp->p = pt;
- }
- }
- #else
- while( tis_ident(c_)) /* Suck in macro call or */
- { /* instruction */
- *p++ = c_; /* convert to upper & save */
- i++;
- c_ = uinput(); /* get fresh input */
- }
- #endif
-
- if( p[-1] == ':' && i > 2) /* kill trailing : for labels */
- {
- --i;
- --p;
- }
- *p = 0;
- c = c_;
- yy_txt2val( i);
- dreturn( T_LABEL);
- }
-
-
- void junk_suckin( error)
- char *error;
- {
- register byte *p = (byte *) yytext;
-
- ENTER("junk_suckin");
- while( c > ' ' && c != ';' && c != ',') /* Errors.. so we don't care */
- { /* about speed anyway. */
- *p++ = c;
- c = uinput();
- }
- *p = 0;
- ALEAVE();
- lsyntax( error);
- }
-
-
- string_suckin()
- {
- register byte *p = (byte *) yytext + 2;
- register unsigned i = 0;
-
- ENTER("string_suckin");
- #if VERSION && FINPUT_IO && QINPUT_IO && QSTRING
- {
- register byte huge *pt = bp->p;
- register lword rem = bp->remain;
-
- while( (*p++ = qinput( rem, pt)) != '\"')
- i++;
- if( bp)
- {
- bp->remain = rem;
- bp->p = pt;
- }
- }
- #else
- while( (*p++ = input()) != '\"')
- i++;
- #endif
- p[-1] = 0;
- dbyte( yytext, wasstrlen = i);
- i += 3; /* 2 for i, 1 for strlen */
- yy_txt2val( i);
- fdreturn( T_STRING);
- }
-
- char *make_string( s)
- register char *s;
- {
- register char *q;
- register int i;
- char *t;
-
- ENTER("make_string");
- {
- register char *src = s;
- for( src = s, i = 0; *src++; i++);
- }
- q = t = str_alloc( i + 3);
- dbyte( q, i);
- q += 2;
-
- while( i > 4)
- {
- *q++ = *s++;
- *q++ = *s++;
- *q++ = *s++;
- *q++ = *s++;
- i -= 4;
- }
- do
- *q++ = *s++;
- while( --i);
-
- LEAVE();
- return( t);
- }
-
- file_suckin()
- {
- register byte *p = (byte *) yytext,
- c_ = (c >= 'A' && c <= 'Z') ? c + 32 : c;
- register int i = 1;
-
- ENTER("file_suckin");
- do
- {
- *p++ = c_;
- i++;
- if ( (c_ = input()) == '/' || c_ == '>')
- c_ = '\\';
- }
- while( is_ident( c_) || c_ == '\\');
- *p = 0;
- c = c_;
- yy_txt2val( i);
- dreturn( T_FILE);
- }
-
- float_suckin()
- {
- char *p = yytext;
- int eflag = 1,
- pflag = 1,
- jflag = 0,
- kflag = 1;
-
- ENTER("float_suckin");
- while( (is_float(c) || ((c == '+' || c == '-') && (jflag || kflag)))
- && (c != '.' || (pflag && eflag))
- && (c != 'E' || eflag))
- {
- if( (c == '+') || (c == '-'))
- kflag = 0;
- if( c == '.')
- pflag = 0;
- jflag = 0;
- if( c == 'E')
- {
- pflag = eflag = 0;
- jflag = 1;
- }
- *p++ = c;
- c = uinput();
- }
- *p = 0;
- dropfloat( yytext);
- dreturn( T_XFLOAT);
- }
-
- /* ---------------------------------------------------------- */
- /* To make this more generic, it would be good to */
- /* parametrize (sp?) this macro a bit more */
- /* ---------------------------------------------------------- */
- #define nextdigit( _recurs) \
- if( tis_digit( c_ = uinput())) \
- { \
- tmp = val + val; \
- val = (tmp << 2) + tmp; \
- val += c_ - '0'; \
- _recurs \
- }
-
- #define finaldigit() \
- if( tis_digit( c_ = uinput())) \
- { \
- if( val >= 6553 && (val > 6553 || c_ >= '6')) /* This looks */ \
- { /* worse than */ \
- c = c_; /* it is */ \
- synerr: \
- lsyntax( E_INTSIZE); \
- } \
- tmp = val + val; \
- val = (tmp << 2) + tmp; \
- yylval = (lword) (val + c_ - '0'); \
- if( tis_digit( c = uinput())) \
- goto synerr; \
- IMESS("Int number is %ld", yylval, 4); \
- xreturn( T_NUMBER); \
- }
-
- /* ---------------------------------------------------------- */
- /* Suck in a int value. Most probably fuinputting the number */
- /* into yytext and converting it later with nextdigit would */
- /* be faster. remains to be tested. */
- /* ---------------------------------------------------------- */
- int_suckin()
- {
- register word val = c - '0', tmp;
- register byte c_,
- *p_table = is_what;
-
- ENTER("int_suckin");
- nextdigit( nextdigit( nextdigit( finaldigit()))); /* can you dig it ? */
- c = c_;
- yylval = (lword) val;
- IMESS("Int number is %ld", yylval, 4);
- xreturn( T_NUMBER);
- }
-
- /* ---------------------------------------------------------- */
- /* Suck in a hex value, we assume that, the '$' has been */
- /* removed before. */
- /* ---------------------------------------------------------- */
- hex_suckin()
- {
- register byte *p = (byte *) yytext,
- c_,
- *p_table = is_what;
- register unsigned val = 0,
- i = 4;
-
- ENTER("hex_suckin");
- do
- if( tis_hex(c_ = uinput()))
- {
- *p++ = c_;
- val <<= 4;
- val += (c_ >= 'A') ? c_ - 'A' + 10 : c_ - '0';
- }
- else
- {
- c = c_;
- if( i == 4)
- lsyntax("That hex number looks mighty strange");
- yylval = (lword) val;
- IMESS("calced hexnumber = %x", (lword) val, 2);
- dreturn( T_NUMBER);
- }
- while( i--);
- c = c_;
- lsyntax(E_HEXLEN);
- }
-
-
- #include "md_suck.c"
-
- /* ---------------------------------------------------------- */
- /* If a lsyntax error occurs, we'll give a nice message and */
- /* then go back to the business at hand. Tokenizing. */
- /* This is not supposed to find EOF errors, that's for the */
- /* I/O routines. */
- /* ---------------------------------------------------------- */
- void lsyntax( err)
- char *err;
- {
- if( yytext[0])
- nserror( err, yytext);
- else
- nterror( err, (int) c);
- longjmp( syn_panic, 1);
- }
-
- /* ---------------------------------------------------------- */
- /* Mallocer for identifier and other strings */
- /* */
- /* (Keeping the fingers crossed that this is faster than a) */
- /* (simple malloc) */
- /* ---------------------------------------------------------- */
- typedef struct _str_m
- {
- lword free;
- char huge *space;
- struct _str_m huge *before;
- } str_m;
-
- static str_m huge *st_h;
-
- char *str_alloc( size)
- int size;
- {
- register str_m huge *p;
- register char huge *q;
- #if STATISTICS
- extern word _a_char, _m_char;
- extern lword _z_char, _s_char;
- #endif
-
- ENTER("str_alloc");
- #if STATISTICS
- _a_char++;
- _z_char += size;
- #endif
- #if DEBUG
- IMESS("Requested size $%lX", (lword) (size_t) size, 4);
- if( st_h)
- {
- IMESS("st_h == $%lX", (lword) st_h, 4);
- IMESS("st_h->free : $%lX", (lword) st_h->free, 4);
- IMESS("st_h->space: $%lX", (lword) st_h->space, 4);
- }
- #endif
- if( (p = st_h) && p->free >= (lword) size)
- {
- letsdoit:
- p->free -= (lword) size;
- q = p->space;
- p->space += (lword) size;
- IMESS("sending $%lX as address", (lword) q, 4);
- IMESS("st_h->space: $%lX", (lword) st_h->space, 4);
- LEAVE();
- return( q);
- }
- #if STATISTICS
- _m_char++;
- _s_char = sizeof(str_m) + STRMAX;
- #endif
- MESS("New big block to allocate");
- p = (str_m huge *) nmalloc( (long) sizeof(str_m) + STRMAX);
- p->free = (lword) STRMAX;
- p->space = (char huge *) p + sizeof( str_m);
- p->before = st_h;
- st_h = p;
- if( size > STRMAX)
- nierror("An unusally large string forces NASM65 to crash");
- goto letsdoit;
- }
-
-
- void yy_txt2val( i)
- register int i;
- {
- register char *src = yytext,
- *q;
-
- #if VERSION
- register str_m huge *p = st_h;
-
- ENTER("yy_txt2val");
- if( p->free >= (lword) i)
- {
- p->free -= (lword) i;
- q = p->space;
- p->space += (lword) i;
- }
- else
- q = str_alloc( i);
- #else
- ENTER("yy_txt2val");
-
- q = str_alloc( i);
- #endif
- yylval = (lword) q;
-
- while( i > 4)
- {
- *q++ = *src++;
- *q++ = *src++;
- *q++ = *src++;
- *q++ = *src++;
- i -= 4;
- }
- do
- *q++ = *src++;
- while( --i);
- IMESS("st_h->space: $%lX", (lword) st_h->space, 4);
- LEAVE();
- }
-
- /* ------------------------------------------------------------
- Words to keep in mind:
-
- "Little green man
- about four foot
- maybe he want
- to kick some butt!" (Vai)
-
- ------------------------------------------------------------ */
-