summaryrefslogtreecommitdiff
path: root/lexer.l
blob: 7d44adf453eeaa8cdd144468f3609df62c8524db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
%{

#include <errno.h>
#include <stdlib.h>
#include <string.h>

#include "parser.h"

#define SETVALUE(v) yylval.arg = (struct argument) { .value = (v) }
#define SETSTR(s)   yylval.str = strdup(s)

static int intlit(const char *s, int base, long *out)
{
	errno = 0;
	*out = strtol(s, NULL, base);
	return errno == ERANGE ? T_BADINT : T_INT;
}

%}

%option outfile="lexer.c" header-file="lexer.h"
%option noyywrap never-interactive

%s inst
%s args

LABEL      [_a-zA-Z][_a-zA-Z0-9]*
COMMENT    #[^\n]*
SP         [ \t]
EOI        [ \t\n#]
REGNUM     [0-7]
DEC        [0-9]
HEX        [0-9a-f]

%%

<INITIAL>{SP}+           { BEGIN(inst);    return T_SPACE; }
<INITIAL>{LABEL}         { SETSTR(yytext); return T_LABEL; }
<INITIAL>:{SP}*          { BEGIN(inst);    return T_COLON; }

<inst>add/{EOI}          { BEGIN(args);    return T_ADD;    }
<inst>sub/{EOI}          { BEGIN(args);    return T_SUB;    }
<inst>mul/{EOI}          { BEGIN(args);    return T_MUL;    }
<inst>div/{EOI}          { BEGIN(args);    return T_DIV;    }
<inst>and/{EOI}          { BEGIN(args);    return T_AND;    }
<inst>or/{EOI}           { BEGIN(args);    return T_OR;     }
<inst>xor/{EOI}          { BEGIN(args);    return T_XOR;    }
<inst>lsl/{EOI}          { BEGIN(args);    return T_LSL;    }
<inst>lsr/{EOI}          { BEGIN(args);    return T_LSR;    }
<inst>asl/{EOI}          { BEGIN(args);    return T_ASL;    }
<inst>asr/{EOI}          { BEGIN(args);    return T_ASR;    }
<inst>rol/{EOI}          { BEGIN(args);    return T_ROL;    }
<inst>ror/{EOI}          { BEGIN(args);    return T_ROR;    }
<inst>not/{EOI}          { BEGIN(args);    return T_NOT;    }
<inst>neg/{EOI}          { BEGIN(args);    return T_NEG;    }
<inst>btc/{EOI}          { BEGIN(args);    return T_BTC;    }
<inst>bts/{EOI}          { BEGIN(args);    return T_BTS;    }
<inst>mov/{EOI}          { BEGIN(args);    return T_MOV;    }
<inst>st\.b/{EOI}        { BEGIN(args);    return T_ST_B;   }
<inst>st\.w/{EOI}        { BEGIN(args);    return T_ST_W;   }
<inst>ld\.bl/{EOI}       { BEGIN(args);    return T_LD_BL;  }
<inst>ld\.bh/{EOI}       { BEGIN(args);    return T_LD_BH;  }
<inst>ld\.w/{EOI}        { BEGIN(args);    return T_LD_W;   }
<inst>ldi\.bl/{EOI}      { BEGIN(args);    return T_LDI_BL; }
<inst>ldi\.bh/{EOI}      { BEGIN(args);    return T_LDI_BH; }
<inst>beq/{EOI}          { BEGIN(args);    return T_BEQ;    }
<inst>bne/{EOI}          { BEGIN(args);    return T_BNE;    }
<inst>bgt/{EOI}          { BEGIN(args);    return T_BGT;    }
<inst>bge/{EOI}          { BEGIN(args);    return T_BGE;    }
<inst>blt/{EOI}          { BEGIN(args);    return T_BLT;    }
<inst>ble/{EOI}          { BEGIN(args);    return T_BLE;    }
<inst>bra/{EOI}          { BEGIN(args);    return T_BRA;    }
<inst>jmp/{EOI}          { BEGIN(args);    return T_JMP;    }
<inst>addpc/{EOI}        { BEGIN(args);    return T_ADDPC;  }
<inst>nop/{EOI}          { BEGIN(args);    return T_NOP;    }

<args>r{REGNUM}          { SETVALUE(yytext[1]-'0'); return T_REG;    }
<args>@r{REGNUM}         { SETVALUE(yytext[2]-'0'); return T_REGPTR; }
<args>[-+]?{DEC}+        { return intlit(yytext,   10, &yylval.lval); }
<args>0x{HEX}+           { return intlit(yytext+2, 16, &yylval.lval); }
<args>{SP}*,{SP}*        { return T_COMMA; }
<args>{LABEL}            { SETSTR(yytext); return T_LABEL; }

{SP}*{COMMENT}?\n        { BEGIN(INITIAL); return T_EOL;    }
{SP}*{COMMENT}           { BEGIN(INITIAL); return T_EOL;    }
{SP}+                    {                 return T_SPACE;  }

<INITIAL><<EOF>>         {                 return 0;        }
<<EOF>>                  { BEGIN(INITIAL); return T_EOL;    }

%%