
/* ###--------------------------------------------------------------### */
/*									*/
/* file		: dx_dlx.lex						*/
/* date		: Mar 31 1993						*/
/* version	: v0.1							*/
/* author	: Pirouz BAZARGAN SABET					*/
/* description	: DLX assembler - lex rules				*/
/*									*/
/* ###--------------------------------------------------------------### */

%{
#include <stdio.h>
#include MUT_H
#include "dx_type.h"
#include "y.tab.h"
#include "dx_defs.h"
#include "dx_lex.h"
%}

registre		[rR]([0-9]|[12][0-9]|3[01])
digit			[0-9]
hexadecimal_valu	[xX]\"[0-9a-fA-F](_?[0-9a-fA-F])*\"
octal_valu		[oO]\"[0-7](_?[0-7])*\"
binary_valu		[bB]\"[0-1](_?[0-1])*\"
decimal_valu		{digit}+
letter			[a-zA-Z]
letter_or_digit		{letter}|{digit}
ident			(_|{letter_or_digit})+

%%
\n				{
/*printf ("CarriageReturn : %d\n", DLX_LINNUM);*/
			DLX_LINNUM++;
			return (CarriageReturn);
				}
\:				{
/*printf ("Colon\n");*/
			return (Colon);
				}
[ \t]				{
/*printf ("space\n");*/
				}
\&				{
/*printf ("Ampersand\n");*/
			return (Ampersand);
				}
\|				{
/*printf ("Bar\n");*/
			return (Bar);
				}
\^				{
/*printf ("Circomflex\n");*/
			return (Circomflex);
				}
\+				{
/*printf ("Plus\n");*/
			return (Plus);
				}
\*				{
/*printf ("Star\n");*/
			return (Star);
				}
\<\<				{
/*printf ("DoubleLess\n");*/
			return (DoubleLess);
				}
\>\>				{
/*printf ("DoubleGreat\n");*/
			return (DoubleGreat);
				}
\-				{
/*printf ("Minus\n");*/
			return (Minus);
				}
\(				{
/*printf ("LeftParen\n");*/
			return (LeftParen);
				}
\)				{
/*printf ("RightParen\n");*/
			return (RightParen);
				}
\,				{
/*printf ("Comma\n");*/
			return (Comma);
				}
{registre}			{
/*printf ("IntegerRegister : %s\n", yytext);*/
			sscanf (&yytext[1], "%lu", &yylval.valu);
			return (IntegerRegister);
				}
{hexadecimal_valu}		{
/*printf ("Literal (X) : %s\n", yytext);*/
 			yylval.valu = hextoint (yytext);
			return (Litteral);
				}
{octal_valu}			{
/*printf ("Literal (O) : %s\n", yytext);*/
 			yylval.valu = octtoint (yytext);
			return (Litteral);
				}
{binary_valu}			{
/*printf ("Literal (B) : %s\n", yytext);*/
 			yylval.valu = bintoint (yytext);
			return (Litteral);
				}
{decimal_valu}			{
/*printf ("Literal (D) : %s\n", yytext);*/
 			if (sscanf (yytext, "%lu", &yylval.valu) == 0)
			  yylval.valu = 0;
			return (Litteral);
				}

{ident}				{
			int code;

			yylval.text = namealloc (yytext);
			code = dlx_search (yylval.text);
			if (code == -1)
			  {
/*printf ("Identifier : %s\n", yytext);*/
			  return (Identifier);
			  }
			else
			  {
/*printf ("Key Word : %s\n", yytext);*/
			  yylval.valu = code;
			  switch (code)
			    {
			    case _ADD:
			    case _ADDU:
			    case _SUB:
			    case _SUBU:
			    case _SLL:
			    case _SRL:
			    case _SRA:
			    case _AND:
			    case _OR:
			    case _XOR:
			    case _SEQ:
			    case _SNE:
			    case _SGE:
			    case _SLE:
			    case _SGT:
			    case _SLT:
			      return (Codop_std);
			    case _ADDI:
			    case _ADDUI:
			    case _SUBI:
			    case _SUBUI:
			    case _ANDI:
			    case _ORI:
			    case _XORI:
			    case _SLLI:
			    case _SRLI:
			    case _SRAI:
			    case _SEQI:
			    case _SNEI:
			    case _SGEI:
			    case _SLEI:
			    case _SGTI:
			    case _SLTI:
			    case _SW:
			    case _SH:
			    case _SB:
			    case _LW:
			    case _LH:
			    case _LHU:
			    case _LB:
			    case _LBU:
			      return (Codop_sdi);
			    case _MOVS2I:
			      return (Codop_dx);
			    case _MOVI2S:
			      return (Codop_sx);
			    case _BEQZ:
			    case _BNEZ:
			      return (Codop_si);
			    case _LHI:
			      return (Codop_di);
			    case _JR:
			    case _JALR:
			      return (Codop_s);
			    case _J:
			    case _JAL:
			      return (Codop_l);
			    case _TRAP:
			      return (Codop_i);
			    case _RFE:
			      return (Codop_n);
			    case _END :
			    case _START :
			    case _EQU :
			    case _ORG :
			      return (code);
			    case _NOP :
			      return (Macro_n);
			    case _LOADI :
			      return (Macro_di);
			    case _IAR :
			    case _SR :
			    case _TVR :
			      return (SpecialRegister);
			    }
			  }
			}
\;.*$				{
/*printf ("Comment : %s\n", yytext);*/
				}
%%

static int dlx_search (str)

char *str;
  {
  static ht *hashpt = NULL;

  if (hashpt == NULL)
    {
    hashpt = addht (64);

    addhtitem (hashpt, namealloc ("iar"), _IAR );
    addhtitem (hashpt, namealloc ("sr"), _SR );
    addhtitem (hashpt, namealloc ("tvr"), _TVR );

    addhtitem (hashpt, namealloc ("end"), _END );
    addhtitem (hashpt, namealloc ("org"), _ORG );
    addhtitem (hashpt, namealloc ("start"), _START );
    addhtitem (hashpt, namealloc ("equ"), _EQU );

    addhtitem (hashpt, namealloc ("nop"), _NOP);
    addhtitem (hashpt, namealloc ("loadi"), _LOADI);

    addhtitem (hashpt, namealloc ("add"), _ADD);
    addhtitem (hashpt, namealloc ("sub"), _SUB);
    addhtitem (hashpt, namealloc ("addi"), _ADDI);
    addhtitem (hashpt, namealloc ("subi"), _SUBI);

    addhtitem (hashpt, namealloc ("sll"), _SLL);
    addhtitem (hashpt, namealloc ("srl"), _SRL);
    addhtitem (hashpt, namealloc ("sra"), _SRA);
    addhtitem (hashpt, namealloc ("slli"), _SLLI);
    addhtitem (hashpt, namealloc ("srli"), _SRLI);
    addhtitem (hashpt, namealloc ("srai"), _SRAI);
    addhtitem (hashpt, namealloc ("lhi"), _LHI);

    addhtitem (hashpt, namealloc ("seq"), _SEQ);
    addhtitem (hashpt, namealloc ("sne"), _SNE);
    addhtitem (hashpt, namealloc ("sge"), _SGE);
    addhtitem (hashpt, namealloc ("sle"), _SLE);
    addhtitem (hashpt, namealloc ("seqi"), _SEQI);
    addhtitem (hashpt, namealloc ("snei"), _SNEI);
    addhtitem (hashpt, namealloc ("sgei"), _SGEI);
    addhtitem (hashpt, namealloc ("slei"), _SLEI);

    addhtitem (hashpt, namealloc ("sgt"), _SGT);
    addhtitem (hashpt, namealloc ("slt"), _SLT);
    addhtitem (hashpt, namealloc ("sgti"), _SGTI);
    addhtitem (hashpt, namealloc ("slti"), _SLTI);

    addhtitem (hashpt, namealloc ("and"), _AND);
    addhtitem (hashpt, namealloc ("or"), _OR);
    addhtitem (hashpt, namealloc ("xor"), _XOR);
    addhtitem (hashpt, namealloc ("andi"), _ANDI);
    addhtitem (hashpt, namealloc ("ori"), _ORI);
    addhtitem (hashpt, namealloc ("xori"), _XORI);

    addhtitem (hashpt, namealloc ("sw"), _SW);
    addhtitem (hashpt, namealloc ("sb"), _SB);
    addhtitem (hashpt, namealloc ("lw"), _LW);
    addhtitem (hashpt, namealloc ("lb"), _LB);
    addhtitem (hashpt, namealloc ("lbu"), _LBU);

    addhtitem (hashpt, namealloc ("jr"), _JR);
    addhtitem (hashpt, namealloc ("jalr"), _JALR);
    addhtitem (hashpt, namealloc ("movs2i"), _MOVS2I);
    addhtitem (hashpt, namealloc ("movi2s"), _MOVI2S);
    addhtitem (hashpt, namealloc ("beqz"), _BEQZ);
    addhtitem (hashpt, namealloc ("bnez"), _BNEZ);

    addhtitem (hashpt, namealloc ("j"), _J);
    addhtitem (hashpt, namealloc ("jal"), _JAL);
    addhtitem (hashpt, namealloc ("rfe"), _RFE);
    addhtitem (hashpt, namealloc ("trap"), _TRAP);

    if (DLX_ARCHIT == DLX_PIPDFN)
      {
      addhtitem (hashpt, namealloc ("addu"), _ADDU);
      addhtitem (hashpt, namealloc ("subu"), _SUBU);
      addhtitem (hashpt, namealloc ("addui"), _ADDUI);
      addhtitem (hashpt, namealloc ("subui"), _SUBUI);
      addhtitem (hashpt, namealloc ("sh"), _SH);
      addhtitem (hashpt, namealloc ("lh"), _LH);
      addhtitem (hashpt, namealloc ("lhu"), _LHU);
      }

    }
  return (gethtitem (hashpt, str));
  }

static unsigned long hextoint (str)

char *str;

  {
  unsigned long valu = 0;
  char          c    = 0;

  while ((c = *str) != '\0')
    {
    if ((c >= '0') && (c <= '9'))
      valu = (valu << 4) + c - '0';
    else
      if ((c >= 'a') && (c <= 'f'))
        valu = (valu << 4) + c - 'a' + 10;
      else
        if ((c >= 'A') && (c <= 'F'))
          valu = (valu << 4) + c - 'A' + 10;
    str++;
    }

  return (valu);
  }

static unsigned long octtoint (str)

char *str;

  {
  unsigned long valu = 0;
  char          c    = 0;

  while ((c = *str) != '\0')
    {
    if ((c >= '0') && (c <= '7'))
      valu = (valu << 3) + c - '0';

    str++;
    }

  return (valu);
  }

static unsigned long bintoint (str)

char *str;

  {
  unsigned long valu = 0;
  char          c    = 0;

  while ((c = *str) != '\0')
    {
    if ((c == '0') || (c == '1'))
      valu = (valu << 1) + c - '0';

    str++;
    }

  return (valu);
  }
