301 lines
6.9 KiB
Plaintext
301 lines
6.9 KiB
Plaintext
%code requires {
|
|
#include "eaxhla.h"
|
|
}
|
|
%{
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
#include "eaxhla.yy.h"
|
|
#include "assembler.h"
|
|
#include "eaxhla.h"
|
|
|
|
extern void yyfree_leftovers(void);
|
|
extern char * yyfilename;
|
|
|
|
void yyerror(const char * errmsg) {
|
|
issue_error("%s near \033[1m'%s'\033[0m", errmsg, yytext);
|
|
}
|
|
|
|
long new_static(int size) { // XXX might not be required
|
|
(void)size;
|
|
return 0;
|
|
}
|
|
%}
|
|
|
|
%union{
|
|
long intval;
|
|
char * strval;
|
|
variable_t varval;
|
|
}
|
|
|
|
/* XXX NOTE: while naming, if my name collided with something in assembler.h i just
|
|
* added a 'T' prefix. this is obviously horrible and should be fixed,
|
|
* but that will require careful discussion with xolatile.
|
|
* for the time being its fine
|
|
*/
|
|
|
|
%token MYBEGIN
|
|
|
|
%token PROGRAM END_PROGRAM
|
|
%token PROCEDURE END_PROCEDURE
|
|
%token TLOOP END_LOOP
|
|
%token IF THEN ELSE END_IF
|
|
%token MACHINE END_MACHINE
|
|
|
|
%token<strval> IDENTIFIER LABEL
|
|
|
|
%type<intval> immediate
|
|
%type<intval> artimetric_block artimetric_expression artimetric_operand
|
|
%token<intval> LITERAL
|
|
%token<strval> STRING_LITERAL
|
|
|
|
// Specifiers
|
|
%token FAST
|
|
%token UNIX
|
|
|
|
// Logic
|
|
%token NEQ TNOT
|
|
/*
|
|
%token TOR TXOR // these are (in)conveniently instructions too
|
|
*/
|
|
|
|
// Type info
|
|
%token TIN
|
|
%token S8 S16 S32 S64
|
|
%token U8 U16 U32 U64
|
|
%type<intval> type
|
|
%type<varval> declaration
|
|
|
|
// Registers
|
|
%type<intval> register
|
|
|
|
%token RBP RSP RIP
|
|
%token RAX RBX RCX RDX
|
|
%token RSI RDI
|
|
%token RG8 RG9 RG10 RG11 RG12 RG13 RG14 RG15
|
|
%token RGXMM0 RGXMM1 RGXMM2 RGXMM3 RGXMM4 RGXMM5 RGXMM6 RGXMM7
|
|
|
|
// Instructions
|
|
%token TADD TOR TADC TBB TXOR TAND TSUB TCMP TSYSCALL TINC
|
|
%token INOP // better temp prefix?
|
|
%token IADD
|
|
%token ISYSCALL
|
|
%token IMOV
|
|
%token IXOR
|
|
|
|
// Instruction-likes
|
|
%token FASTCALL
|
|
%token EXIT BREAK
|
|
%%
|
|
|
|
hla: %empty // { issue_warning("empty file, noting to be done."); }
|
|
| program hla
|
|
| function hla
|
|
;
|
|
|
|
program: program_head declaration_section MYBEGIN code END_PROGRAM
|
|
;
|
|
|
|
program_head: program_specifier PROGRAM IDENTIFIER {
|
|
if (is_program_found) {
|
|
issue_error("only 1 entry point is allowed and a program block was already found");
|
|
YYERROR;
|
|
}
|
|
is_program_found = 1;
|
|
scope = $3;
|
|
};
|
|
|
|
program_specifier: %empty
|
|
| UNIX
|
|
;
|
|
|
|
function: function_head declaration_section MYBEGIN code END_PROCEDURE
|
|
;
|
|
|
|
function_head: function_specifier PROCEDURE IDENTIFIER { scope = $3; }
|
|
;
|
|
|
|
function_specifier: %empty
|
|
| FAST
|
|
;
|
|
|
|
declaration_section: %empty
|
|
| declaration declaration_section
|
|
| error declaration_section { yyerrok; }
|
|
;
|
|
|
|
declaration:
|
|
variable_specifier type IDENTIFIER {
|
|
$$.name = make_scoped_name(scope, $3);
|
|
add_variable($$);
|
|
}
|
|
| variable_specifier type IDENTIFIER '=' LITERAL {
|
|
$$.name = make_scoped_name(scope, $3);
|
|
if (!can_fit($2, $5)) {
|
|
issue_warning("the value \033[1m'%lld'\033[0m will overflow in assignement", $5);
|
|
}
|
|
$$.value = $5;
|
|
add_variable($$);
|
|
}
|
|
| variable_specifier type IDENTIFIER '=' STRING_LITERAL {
|
|
$$.name = make_scoped_name(scope, $3);
|
|
$$.value = $5;
|
|
add_variable($$);
|
|
}
|
|
;
|
|
|
|
variable_specifier: %empty
|
|
| TIN
|
|
;
|
|
|
|
type: S8 { $$ = S8; }
|
|
| S16 { $$ = S16; }
|
|
| S32 { $$ = S32; }
|
|
| S64 { $$ = S64; }
|
|
| U8 { $$ = U8; }
|
|
| U16 { $$ = U16; }
|
|
| U32 { $$ = U32; }
|
|
| U64 { $$ = U64; }
|
|
;
|
|
|
|
immediate: LITERAL
|
|
| IDENTIFIER
|
|
;
|
|
|
|
memory: artimetric_block
|
|
;
|
|
|
|
value: artimetric_block
|
|
| LITERAL
|
|
| IDENTIFIER
|
|
;
|
|
|
|
code: %empty
|
|
| error code { yyerrok; }
|
|
| loop code
|
|
| if code
|
|
| call code
|
|
| LABEL code { free($1); }
|
|
| machine code
|
|
| BREAK code
|
|
| exit code
|
|
| instruction code
|
|
;
|
|
|
|
instruction: INOP { ; }
|
|
/*
|
|
| TXOR register register code { /* assemble_xor(size_64b, type_register_register, $2, $3); * / }
|
|
| TXOR register immediate code { /* assemble_xor(size_64b, type_register_register, $2, $3); * / }
|
|
| TXOR IDENTIFIER register code { /* assemble_xor(size_64b, type_register_register, $2, $3); * / free($2); }
|
|
| TINC register code
|
|
| TINC IDENTIFIER code { free($2); }
|
|
*/
|
|
| IADD register register
|
|
| IADD register immediate
|
|
| IADD register memory
|
|
| ISYSCALL
|
|
| IMOV register register
|
|
| IMOV memory register
|
|
| IMOV register memory
|
|
| IMOV register immediate
|
|
| IMOV memory immediate
|
|
| IXOR register register
|
|
| IXOR register memory
|
|
;
|
|
|
|
loop: TLOOP code END_LOOP
|
|
;
|
|
|
|
if: IF logic THEN code END_IF
|
|
| IF logic THEN code ELSE code END_IF
|
|
;
|
|
|
|
logic: logical_operand TAND logical_operand
|
|
| logical_operand TOR logical_operand
|
|
| logical_operand TXOR logical_operand
|
|
| logical_operand '=' logical_operand
|
|
| logical_operand NEQ logical_operand
|
|
| TNOT logic
|
|
;
|
|
|
|
logical_operand: sublogic
|
|
| register
|
|
| artimetric_block
|
|
| LITERAL
|
|
| IDENTIFIER
|
|
;
|
|
|
|
sublogic: '(' logic ')'
|
|
;
|
|
|
|
machine: MACHINE machine_code END_MACHINE
|
|
;
|
|
|
|
machine_code: %empty
|
|
| LITERAL machine_code
|
|
| STRING_LITERAL machine_code
|
|
| IDENTIFIER machine_code { free($1); }
|
|
;
|
|
|
|
call: calltype IDENTIFIER arguments { free($2); }
|
|
;
|
|
|
|
calltype: FASTCALL
|
|
;
|
|
|
|
arguments: %empty
|
|
| IDENTIFIER arguments { free($1); }
|
|
| STRING_LITERAL arguments { free($1); }
|
|
| LITERAL arguments
|
|
| register arguments
|
|
| artimetric_block arguments
|
|
;
|
|
|
|
register: RAX { $$ = R0; }
|
|
| RBX { $$ = R1; }
|
|
| RCX { $$ = R2; }
|
|
| RDX { $$ = R3; }
|
|
| RSI { $$ = R4; }
|
|
| RDI { $$ = R5; }
|
|
| RBP { $$ = R6; }
|
|
| RSP { $$ = R7; }
|
|
| RG8 { $$ = R8; }
|
|
| RG9 { $$ = R9; }
|
|
| RG10 { $$ = R10; }
|
|
| RG11 { $$ = R11; }
|
|
| RG12 { $$ = R12; }
|
|
| RG13 { $$ = R13; }
|
|
| RG14 { $$ = R14; }
|
|
| RG15 { $$ = R15; }
|
|
| RGXMM0 { $$ = 0; } /* XXX */
|
|
| RGXMM1 { $$ = 0; }
|
|
| RGXMM2 { $$ = 0; }
|
|
| RGXMM3 { $$ = 0; }
|
|
| RGXMM4 { $$ = 0; }
|
|
| RGXMM5 { $$ = 0; }
|
|
| RGXMM6 { $$ = 0; }
|
|
| RGXMM7 { $$ = 0; }
|
|
;
|
|
|
|
artimetric_block: '[' artimetric_expression ']' { $$ = $2; }
|
|
;
|
|
|
|
artimetric_expression: %empty { $$ = 0; }
|
|
| artimetric_operand
|
|
| artimetric_expression '+' artimetric_operand { $$ = $1 + $3; }
|
|
| artimetric_expression '-' artimetric_operand { $$ = $1 - $3; }
|
|
| artimetric_expression '*' artimetric_operand { $$ = $1 * $3; }
|
|
| artimetric_expression '/' artimetric_operand { $$ = $1 / $3; }
|
|
| artimetric_expression '%' artimetric_operand { $$ = $1 % $3; }
|
|
| artimetric_expression '^' artimetric_operand { $$ = pow($1, $3); }
|
|
;
|
|
|
|
artimetric_operand: LITERAL
|
|
| STRING_LITERAL
|
|
| IDENTIFIER { $$ = 0; /*XXX*/ }
|
|
;
|
|
|
|
exit: EXIT value
|
|
;
|
|
%%
|