%{ /* ---------------------------------------------------------------------- */ /* Copyright (C) 1992 by Natrlich! */ /* This file is copyrighted! */ /* Refer to the documentation for details. */ /* ---------------------------------------------------------------------- */ /*#define YYDEBUG*/ #include #include "defines.h" #undef DEBUG #include "structs.h" #include "nasm.h" #include "labels.h" #include "code.h" #include "buffer.h" #include "exprfast.h" #include "op.h" #if DEBUG #define bputchar( c) putchar( c) #define dbprintf( s) puts( s) #else #define dbputchar( c) #define dbprintf( s) #endif #ifdef NIL #undef NIL #endif #define NIL ((char *) 0) #define ENIL ((expr *) 0) extern int _in_instr, _in_doteq, _call_macro, wasstrlen, state, fully_mac65; extern buffer huge *bp; extern word __pc; static char undefined[] = { 9, 0, 'u','n','d','e','f','i','n','e','d' }, *lastident; static int footok; static lword fooval; #define adrmod footok /* screws the debugger of course (har har) */ typedef union { lword u; byte *b; char *c; expr *e; lexpr *l; } YYSTYPE; #define _ul lword %} %start file /* ---------------------------------------------------------- */ /* The order of these tokens MIGHT be VERY IMPORTANT */ /* ---------------------------------------------------------- */ %token T_DOTEQ T_IF T_ELSE T_LOCAL T_EOL T_NUMBER T_ZEXT %token T_ENDIF T_ORG T_DS T_WORD T_BYTE T_SBYTE T_OPT %token T_MACRO T_ENDM T_END T_NUM T_OBJ T_MLIST T_INCLUDE %token T_ERROR T_TITLE T_DBYTE T_TAB T_FLOAT T_CBYTE T_XREF %token T_SET T_LIST T_ERR T_ACCU T_CHAR T_NOT T_DEF %token T_REF T_CLIST T_EJECT T_PAGE T_XFLOAT T_UNDEF T_WARN %token T_REPT T_CALL %token T_IDENT T_STRING T_LABEL T_FILE %token T_EXPR %token T_INSTR %type irest s_expr a_expr modif __expr %type t_expr u_expr si_expr mi_expr i_expr fubar ei_expr %left ',' T_NO /* not really... */ %left T_OR %left T_AND %nonassoc T_LEQ T_GEQ '=' T_NEQ '>' '<' %left MIDDLE %left '!' '^' '&' %left '+' '-' %left '*' '/' '\\' %left HIGHEST /* next five tokens are actually not used by YACC, but elsewhere */ %token T_MPARA %token T_MSPARA %token T_MLPARA %token T_MLSPARA %token T_PARA %token REALHIGH %% file : source line | source ; source: source sline { inc_line(); _in_instr = 0; dbputchar( '\n'); } | | error { nterror("unwanted token appeared", yychar); while( (yychar = yylex()) && yychar != T_EOL); inc_line(); if( ! yychar) return; yyerrok; yyclearin; } ; sline : line T_EOL | T_EOL ; line : T_LABEL { enter_pclabel( $1); } nline { dbprintf("T_LABEL nline [done with line]\n\n"); } | T_LABEL '=' '=' __expr { enter_elabel( $1, $4, L_ZERO | L_LINKZERO); dbprintf("T_LABEL == s_expr [done with line]\n\n"); } | T_LABEL '=' __expr { enter_elabel( $1, $3, L_NORMAL); dbprintf("T_LABEL = s_expr [done with line]\n\n"); } | T_LABEL T_DOTEQ { _in_doteq = 1; } __expr { _in_doteq = 0; enter_elabel( $1, $4, L_EQU); dbprintf("T_LABEL .= s_expr [done with line]\n\n"); } | T_LABEL { enter_pclabel( $1); dbprintf("T_LABEL [done with line]\n\n"); } | nline { dbprintf("regular line [done]\n\n"); } ; nline : T_INSTR { _in_instr = 1; } irest { generate( $1,adrmod,$3);} | T_IF __expr { if_treat( $2); } | T_ELSE { else_treat(); } | T_ENDIF { endif_treat(); } | T_ORG __expr { setorg( $2, 0); } | T_DS __expr { reserve( $2); } | T_WORD i_expr { dropwords( $2); } | T_DBYTE i_expr { dropdbytes( $2); } | T_BYTE modif si_expr { dropbytes( $2, $3, 0); } | T_CBYTE modif si_expr { dropbytes( $2, $3, 1); } | T_SBYTE modif si_expr { dropsbytes( $2, $3); } | T_ZEXT T_IDENT { page0decl( $2); } | T_FLOAT f_expr | T_CALL T_IDENT { call_macro( $2); } | T_IDENT { lastident = NIL; _call_macro = 1; } ei_expr { _call_macro = 0; do_macro( $1, $3); } | T_REPT __expr T_IDENT { lastident = NIL; _call_macro = 1; } ei_expr { _call_macro = 0; rept_macro( $2, $3, $5);} | T_TAB i_expr { dbprintf("T_TAB"); } | T_OPT o_expr { dbprintf("T_OPT"); } | T_SET __expr ',' __expr { dbprintf("T_SET"); } | T_UNDEF T_IDENT { undefine( $2); } | T_MACRO T_IDENT { load_macro( $2); dbprintf("*** DONE WITH .MACRO ***"); } | T_INCLUDE '#' T_FILE { footok = yylex(); fooval = yylval.u; include( $3, ".h65"); fix_include( footok, fooval); } | T_END { return( 0); } | T_LOCAL { do_local(); } | T_TITLE T_STRING { dbprintf("TITLE\n"); } | T_PAGE T_STRING { dbprintf("PAGE\n"); } | T_ERROR T_STRING { nerror( $2 + 2); } | T_WARN T_STRING { nwarning( $2 + 2); } ; irest : __expr ',' 'X' { adrmod = C_RELX; } | __expr ',' 'Y' { adrmod = C_RELY; } | '(' __expr ',' 'X' ')' { adrmod = C_INDX; $$ = $2; } | '(' __expr ')' ',' 'Y' { adrmod = C_INDY; $$ = $2; } | '#' __expr { adrmod = C_IMM; $$ = $2; } | '(' __expr ')' { adrmod = C_IND; $$ = $2; } | __expr { adrmod = C_ABS; } | T_ACCU { adrmod = C_ACCU; $$ = ENIL; } | { adrmod = C_IMPL; $$ = ENIL; } ; a_expr: T_NUMBER { $$ = ival_pl( (word) $1); } | T_IDENT { $$ = lval_pl( lastident = $1); } | T_EXPR | '*' {($$ = ival_pl( __pc))->op = O_PCREL;} | T_CHAR { $$ = ival_pl( (word) $1); } | T_DEF T_IDENT { $$ = ival_pl( is_def( $2)); } | T_REF T_IDENT { $$ = ival_pl( is_ref( $2)); } | T_PARA { expr *he; lastident = $1->string + 2; he = copyexpr( $1->expr); he->fix = 0; $$ = he; } ; __expr: s_expr { $1->fix = FIX_NOTHING; } s_expr: '[' s_expr ']' { $$ = $2; } | s_expr T_AND s_expr { $$ = op_pl( O_BAND, $1, $3); } | s_expr T_OR s_expr { $$ = op_pl( O_BOR, $1, $3); } | s_expr T_NEQ s_expr { $$ = op_pl( O_NEQ, $1, $3); } | s_expr T_GEQ s_expr { $$ = op_pl( O_GEQ, $1, $3); } | s_expr T_LEQ s_expr { $$ = op_pl( O_LEQ, $1, $3); } | s_expr '<' s_expr { $$ = op_pl( O_LT, $1, $3); } | s_expr '>' s_expr { $$ = op_pl( O_GT, $1, $3); } | s_expr '+' s_expr { $$ = op_pl( O_ADD, $1, $3); } | s_expr '-' s_expr { $$ = op_pl( O_SUB, $1, $3); } | s_expr '/' s_expr { $$ = op_pl( O_DIV, $1, $3); } | s_expr '*' s_expr { $$ = op_pl( O_MUL, $1, $3); } | s_expr '\\' s_expr { $$ = op_pl( O_MOD, $1, $3); } | s_expr '&' s_expr { $$ = op_pl( O_AND, $1, $3); } | s_expr '!' s_expr { $$ = op_pl( O_OR, $1, $3); } | s_expr '^' s_expr { $$ = op_pl( O_EOR, $1, $3); } | s_expr '=' s_expr { $$ = op_pl( O_EQ, $1, $3); } | T_NOT s_expr %prec HIGHEST { $$ = op_pl( O_BNOT,$2, ENIL); } | '-' s_expr %prec HIGHEST { $$ = op_pl( O_MIN, $2, ENIL); } | '>' s_expr %prec MIDDLE { $$ = op_pl( O_MSB, $2, ENIL); } | '<' s_expr %prec MIDDLE { $$ = op_pl( O_LSB, $2, ENIL); } | a_expr ; fubar : __expr { $$ = lex_pl( NIL, $1); } ; i_expr: fubar | fubar ',' i_expr { $$ = lex_ch( $1, $3); } ; modif : '+' __expr ',' { $$ = $2; } | { $$ = ENIL; } ; t_expr: T_STRING { $$ = lex_pl( $1, ENIL); } | __expr { $$ = lex_pl( NIL, $1); } ; si_expr: t_expr | t_expr ',' si_expr { $$ = lex_ch( $1, $3); } ; u_expr: T_STRING { $$ = lex_pl( $1, ival_pl( wasstrlen)); } | __expr { $$ = lex_pl( lastident ? make_string( lastident) : undefined, $1); } ; mi_expr: u_expr | u_expr ',' { lastident = NIL; } mi_expr { $$ = lex_ch( $1, $4); } ; ei_expr: { $$ = lex_pl( NIL, ival_pl( 0)); } | mi_expr { $$ = slex_ch( lex_pl( NIL, ival_pl( lex_cnt( $1))), $1); } ; f_expr: T_XFLOAT | f_expr ',' T_XFLOAT ; o_expr: op2 | o_expr ',' op2 ; op2 : option | T_NO option ; option: T_OBJ | T_LIST | T_MLIST | T_CLIST | T_XREF | T_ERR | T_EJECT | T_NUM ;