summaryrefslogtreecommitdiff
path: root/parser.y
blob: 2177ae802adc1bd4f50ae5782eb458b26b0f7e0b (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
%{

#include <stdio.h>

#include "lexer.h"
#include "mnemonics.h"

void yyerror(const char *msg)
{
	fprintf(stderr, "%s\n", msg);
}

#define INSTRUCTION_ARGS(m,a) (struct instruction) { MNEM_ ## m, a }
#define INSTRUCTION(m)        (struct instruction) { MNEM_ ## m }
#define MKARGS(...)           (struct arguments)   { __VA_ARGS__ }

%}

%output  "parser.c"
%defines "parser.h"

%code requires {
	#include "nqasm.h"
}

%union {
	struct instruction inst;
	struct arguments   args;
	struct argument    arg;
}

%token END 0 "end of file"

%token T_SPACE
%token T_EOL

%token T_ADD
%token T_SUB
%token T_MUL
%token T_DIV
%token T_AND
%token T_OR
%token T_XOR
%token T_LSL
%token T_LSR
%token T_ASL
%token T_ASR
%token T_ROL
%token T_ROR
%token T_NOT
%token T_NEG
%token T_BTC
%token T_BTS
%token T_MOV
%token T_ST_B
%token T_ST_W
%token T_LD_BL
%token T_LD_BH
%token T_LD_W
%token T_LDI_BL
%token T_LDI_BH
%token T_BEQ
%token T_BNE
%token T_BGT
%token T_BGE
%token T_BLT
%token T_BLE
%token T_BRA
%token T_JMP
%token T_ADDPC
%token T_NOP

%token <arg> T_REG
%token <arg> T_REGPTR
%token       T_COMMA    ","

%type <inst> inst
%type <args> reg2
%type <args> reg3
%type <args> regp
%type <args> regp_reg
%type <args> reg_regp

%%

input:	line
	|	input line
	;

line:	T_SPACE inst eol
		{ add_instruction(&$2); }
	|	eol
	;

inst:	T_ADD    reg3      { $$ = INSTRUCTION_ARGS(ADD,    $2); }
	|	T_SUB    reg3      { $$ = INSTRUCTION_ARGS(SUB,    $2); }
	|	T_MUL    reg3      { $$ = INSTRUCTION_ARGS(MUL,    $2); }
	|	T_DIV    reg3      { $$ = INSTRUCTION_ARGS(DIV,    $2); }
	|	T_AND    reg3      { $$ = INSTRUCTION_ARGS(AND,    $2); }
	|	T_OR     reg3      { $$ = INSTRUCTION_ARGS(OR,     $2); }
	|	T_XOR    reg3      { $$ = INSTRUCTION_ARGS(XOR,    $2); }
	|	T_LSL    reg3      { $$ = INSTRUCTION_ARGS(LSL,    $2); }
	|	T_LSR    reg3      { $$ = INSTRUCTION_ARGS(LSR,    $2); }
	|	T_ASL    reg3      { $$ = INSTRUCTION_ARGS(ASL,    $2); }
	|	T_ASR    reg3      { $$ = INSTRUCTION_ARGS(ASR,    $2); }
	|	T_ROL    reg3      { $$ = INSTRUCTION_ARGS(ROL,    $2); }
	|	T_ROR    reg3      { $$ = INSTRUCTION_ARGS(ROR,    $2); }
	|	T_NOT    reg2      { $$ = INSTRUCTION_ARGS(NOT,    $2); }
	|	T_NEG    reg2      { $$ = INSTRUCTION_ARGS(NEG,    $2); }
	|	T_BTC    reg2      { $$ = INSTRUCTION_ARGS(BTC,    $2); }
	|	T_BTS    reg2      { $$ = INSTRUCTION_ARGS(BTS,    $2); }
	|	T_MOV    reg2      { $$ = INSTRUCTION_ARGS(MOV,    $2); }
	|	T_ST_B   regp_reg  { $$ = INSTRUCTION_ARGS(ST_B,   $2); }
	|	T_ST_W   regp_reg  { $$ = INSTRUCTION_ARGS(ST_W,   $2); }
	|	T_LD_BL  reg_regp  { $$ = INSTRUCTION_ARGS(LD_BL,  $2); }
	|	T_LD_BH  reg_regp  { $$ = INSTRUCTION_ARGS(LD_BH,  $2); }
	|	T_LD_W   reg_regp  { $$ = INSTRUCTION_ARGS(LD_W,   $2); }
	|	T_LDI_BL
		{ $$ = INSTRUCTION(LDI_BL); }
	|	T_LDI_BH
		{ $$ = INSTRUCTION(LDI_BH); }
	|	T_BEQ
		{ $$ = INSTRUCTION(BEQ); }
	|	T_BNE
		{ $$ = INSTRUCTION(BNE); }
	|	T_BGT
		{ $$ = INSTRUCTION(BGT); }
	|	T_BGE
		{ $$ = INSTRUCTION(BGE); }
	|	T_BLT
		{ $$ = INSTRUCTION(BLT); }
	|	T_BLE
		{ $$ = INSTRUCTION(BLE); }
	|	T_BRA
		{ $$ = INSTRUCTION(BRA); }
	|	T_JMP    regp      { $$ = INSTRUCTION_ARGS(JMP,    $2); }
	|	T_ADDPC
		{ $$ = INSTRUCTION(ADDPC); }
	|	T_NOP
		{ $$ = INSTRUCTION(NOP); }
	;

reg2:		T_SPACE T_REG "," T_REG              { $$ = MKARGS($2, $4);     }
reg3:		T_SPACE T_REG "," T_REG "," T_REG    { $$ = MKARGS($2, $4, $6); }
regp:		T_SPACE T_REGPTR                     { $$ = MKARGS($2);         }
regp_reg:	T_SPACE T_REGPTR "," T_REG           { $$ = MKARGS($2, $4);     }
reg_regp:	T_SPACE T_REG "," T_REGPTR           { $$ = MKARGS($2, $4);     }

eol:	T_EOL
	|	T_SPACE T_EOL
	;