This commit is contained in:
anon
2024-07-15 19:55:52 +02:00
parent 0ac0e2904a
commit 2cf6d79edd
18 changed files with 476 additions and 176 deletions

View File

@ -15,7 +15,7 @@ LIBS := $(addprefix ${OBJECT.d}/,${LIBS.source})
GENSOURCE := eaxhla.yy.c eaxhla.tab.c GENSOURCE := eaxhla.yy.c eaxhla.tab.c
GENSOURCE := $(addprefix ${OBJECT.d}/,${GENSOURCE}) GENSOURCE := $(addprefix ${OBJECT.d}/,${GENSOURCE})
GENOBJECT := $(subst .c,.o,${GENSOURCE}) GENOBJECT := $(subst .c,.o,${GENSOURCE})
PLUGLOCK := token_list.pluglock scanner_instructions.pluglock parser_rules.pluglock PLUGLOCK := instruction_token_list.pluglock instruction_scanner_instructions.pluglock instruction_parser_rules.pluglock register_token_list.pluglock register_scanner_instructions.pluglock register_parser_rules.pluglock
PLUGLOCK := $(addprefix ${OBJECT.d}/,${PLUGLOCK}) PLUGLOCK := $(addprefix ${OBJECT.d}/,${PLUGLOCK})
PLUGFILES := ${SOURCE.d}/eaxhla.y ${SOURCE.d}/eaxhla.l PLUGFILES := ${SOURCE.d}/eaxhla.y ${SOURCE.d}/eaxhla.l
@ -64,16 +64,12 @@ ${OBJECT.d}/%.tab.o: ${OBJECT.d}/%.tab.c
${OBJECT.d}/%.o: ${SOURCE.d}/%.c ${OBJECT.d}/%.o: ${SOURCE.d}/%.c
${COMPILE.c} -o $@ $< ${COMPILE.c} -o $@ $<
${OBJECT.d}/%.pp: tool/instruction_generator/%.tcl tool/instruction_generator/instructions.tcl ${OBJECT.d}/%.pp: tool/generators/%.tcl tool/generators/instructions.tcl tool/generators/registers.tcl
tclsh $< > $@ tclsh $< > $@
unplug: unplug:
-rm ${PLUGLOCK} -rm ${PLUGLOCK}
${PLUG} -u -d token_list '' -d scanner_instructions '' -d parser_rules '' source/eaxhla.l source/eaxhla.y ${PLUG} -u -a source/eaxhla.l source/eaxhla.y
#plug: ${PLUGDEF}
# ${PLUG} -g -e token_list ${OBJECT.d}/token_list.pp source/eaxhla.y
# ${PLUG} -g -e scanner_instructions ${OBJECT.d}/scanner_instructions.pp source/eaxhla.l
${OBJECT.d}/%.pluglock: ${OBJECT.d}/%.pp ${OBJECT.d}/%.pluglock: ${OBJECT.d}/%.pp
${PLUG} -g -e $* $< ${PLUGFILES} ${PLUG} -g -e $* $< ${PLUGFILES}
@ -86,7 +82,9 @@ test: ${OUT}
bootstrap: bootstrap:
./library/bootstrap.sh ./library/bootstrap.sh
clean: unplug deepclean: unplug clean
clean:
-rm ${OUT} ${OBJECT} ${GENOBJECT} ${GENSOURCE} -rm ${OUT} ${OBJECT} ${GENOBJECT} ${GENSOURCE}
${OUT}: ${PLUGLOCK} ${GENSOURCE} ${GENOBJECT} ${OBJECT} ${LIB} ${OUT}: ${PLUGLOCK} ${GENSOURCE} ${GENOBJECT} ${OBJECT} ${LIB}

View File

@ -27,10 +27,10 @@ void dump_variable(void * data) {
variable->value variable->value
); );
} else { } else {
printf("{ .name = '%s', .elements = '%d', .array_value = \"%.*s\" }\n", printf("{ .name = '%s', .elements = '%llu', .array_value = \"%.*s\" }\n",
variable->name, variable->name,
variable->elements, variable->elements,
variable->elements, (int)variable->elements,
(char*)variable->array_value (char*)variable->array_value
); );
} }

View File

@ -14,6 +14,8 @@
#include "eaxhla.tab.h" #include "eaxhla.tab.h"
#include "assembler.h" #include "assembler.h"
unsigned long long anon_variable_counter = 0;
tommy_hashtable variable_table; tommy_hashtable variable_table;
int has_encountered_error = 0; int has_encountered_error = 0;
@ -85,6 +87,14 @@ int can_fit(int type, long long value) {
return value > 0 ? (unsigned long long)value <= max : value >= min; return value > 0 ? (unsigned long long)value <= max : value >= min;
} }
int validate_array_size(int size) {
if (size < 1) {
issue_error("cannot create an array of size '%d', because its less than 1", size);
return 1;
}
return 0;
}
char * make_scoped_name(const char * const scope, char * name) { char * make_scoped_name(const char * const scope, char * name) {
if (!scope) { if (!scope) {
return name; return name;

View File

@ -9,12 +9,14 @@ typedef struct {
long value; long value;
void * array_value; void * array_value;
}; };
int elements; unsigned long long elements;
char * name; char * name;
unsigned _hash; unsigned _hash;
tommy_node _node; tommy_node _node;
} variable_t; } variable_t;
extern unsigned long long anon_variable_counter;
#define REGISTER64_MASK 0x00; #define REGISTER64_MASK 0x00;
#define REGISTER32_MASK 0x01; #define REGISTER32_MASK 0x01;
@ -35,6 +37,7 @@ extern int eaxhla_destroy(void);
extern char * make_scoped_name(const char * const scope, char * name); extern char * make_scoped_name(const char * const scope, char * name);
extern int can_fit(int type, long long value); extern int can_fit(int type, long long value);
extern int validate_array_size(int size);
extern void add_variable(variable_t variable); extern void add_variable(variable_t variable);
extern variable_t * get_variable(const char * const name); extern variable_t * get_variable(const char * const name);

View File

@ -47,7 +47,7 @@ machine { return MACHINE; }
library { return LIBRARY; } library { return LIBRARY; }
break { return BREAK; } break { return BREAK; }
UNTIL { return UNTIL; } until { return UNTIL; }
exit { return EXIT; } exit { return EXIT; }
end { BEGIN IN_END; } end { BEGIN IN_END; }
@ -55,48 +55,8 @@ end { BEGIN IN_END; }
fast { return FAST; } fast { return FAST; }
unix { return UNIX; } unix { return UNIX; }
rax { return RAX; } /* #placeholder<register_scanner_instructions> END
rbx { return RBX; } */
rcx { return RCX; }
rdx { return RDX; }
rbp { return RBP; }
rsp { return RSP; }
rip { return RIP; }
rsi { return RSI; }
rdi { return RDI; }
r8 { return RG8; }
r9 { return RG9; }
r10 { return RG10; }
r11 { return RG11; }
r12 { return RG12; }
r13 { return RG13; }
r14 { return RG14; }
xmm0 { return RGXMM0; }
xmm1 { return RGXMM1; }
xmm2 { return RGXMM2; }
xmm3 { return RGXMM3; }
xmm4 { return RGXMM4; }
xmm5 { return RGXMM5; }
xmm6 { return RGXMM6; }
xmm7 { return RGXMM7; }
eax { return EAX; }
ebx { return EBX; }
ecx { return ECX; }
edx { return EDX; }
ebp { return EBP; }
esp { return ESP; }
eip { return EIP; }
esi { return ESI; }
edi { return EDI; }
r8d { return RG8D; }
r9d { return RG9D; }
r10d { return RG10D; }
r11d { return RG11D; }
r12d { return RG12D; }
r13d { return RG13D; }
r14d { return RG14D; }
in { return TIN; } in { return TIN; }
\= { return '='; } \= { return '='; }
@ -124,39 +84,112 @@ u64 { return U64; }
fastcall { return FASTCALL; } fastcall { return FASTCALL; }
/* --- Registers begin here --- */
/* #placeholder<register_scanner_instructions> BEGIN
*/
rax { return RAX; }
rbx { return RBX; }
rcx { return RCX; }
rdx { return RDX; }
rsi { return RSI; }
rdi { return RDI; }
rbp { return RBP; }
rsp { return RSP; }
rg8 { return RG8; }
rg9 { return RG9; }
rg10 { return RG10; }
rg11 { return RG11; }
rg12 { return RG12; }
rg13 { return RG13; }
rg14 { return RG14; }
rg15 { return RG15; }
eax { return EAX; }
ebx { return EBX; }
ecx { return ECX; }
edx { return EDX; }
esi { return ESI; }
edi { return EDI; }
ebp { return EBP; }
esp { return ESP; }
rg8d { return RG8D; }
rg9d { return RG9D; }
rg10d { return RG10D; }
rg11d { return RG11D; }
rg12d { return RG12D; }
rg13d { return RG13D; }
rg14d { return RG14D; }
rg15d { return RG15D; }
ax { return AX; }
bx { return BX; }
cx { return CX; }
dx { return DX; }
si { return SI; }
di { return DI; }
bp { return BP; }
sp { return SP; }
r8w { return R8W; }
r9w { return R9W; }
r10w { return R10W; }
r11w { return R11W; }
r12w { return R12W; }
r13w { return R13W; }
r14w { return R14W; }
r15w { return R15W; }
al { return AL; }
bl { return BL; }
cl { return CL; }
dl { return DL; }
sil { return SIL; }
dil { return DIL; }
bpl { return BPL; }
spl { return SPL; }
r8b { return R8B; }
r9b { return R9B; }
r10b { return R10B; }
r11b { return R11B; }
r12b { return R12B; }
r13b { return R13B; }
r14b { return R14B; }
r15b { return R15B; }
/* #placeholder<register_scanner_instructions> END
*/
/* --- Registers end here --- */
/* --- Instrunctions begin here --- */ /* --- Instrunctions begin here --- */
nop { return INOP; } nop { return INOP; }
/* #placeholder<scanner_instructions> BEGIN /* #placeholder<instruction_scanner_instructions> BEGIN
*/ */
adc { return ITADC; } adc { return ITADC; }
add { return ITADD; } add { return ITADD; }
and { return ITAND; } and { return ITAND; }
cmp { return ITCMP; } cmp { return ITCMP; }
dec { return ITDEC; } dec { return ITDEC; }
div { return ITDIV; } div { return ITDIV; }
hlt { return ITHLT; } hlt { return ITHLT; }
idiv { return ITIDIV; } idiv { return ITIDIV; }
imul { return ITIMUL; } imul { return ITIMUL; }
inc { return ITINC; } inc { return ITINC; }
leave { return ITLEAVE; } leave { return ITLEAVE; }
lock { return ITLOCK; } lock { return ITLOCK; }
mov { return ITMOV; } mov { return ITMOV; }
mul { return ITMUL; } mul { return ITMUL; }
neg { return ITNEG; } neg { return ITNEG; }
not { return ITNOT; } not { return ITNOT; }
or { return ITOR; } or { return ITOR; }
pause { return ITPAUSE; } pause { return ITPAUSE; }
retf { return ITRETF; } retf { return ITRETF; }
retn { return ITRETN; } retn { return ITRETN; }
sbb { return ITSBB; } sar { return ITSAR; }
sub { return ITSUB; } sbb { return ITSBB; }
syscall { return ITSYSCALL; } sub { return ITSUB; }
sysenter { return ITSYSENTER; } syscall { return ITSYSCALL; }
sysexit { return ITSYSEXIT; } sysenter { return ITSYSENTER; }
sysret { return ITSYSRET; } sysexit { return ITSYSEXIT; }
xor { return ITXOR; } sysret { return ITSYSRET; }
xor { return ITXOR; }
/* #placeholder<scanner_instructions> END /* #placeholder<instruction_scanner_instructions> END
*/ */
/* --- Instrunctions end here --- */ /* --- Instrunctions end here --- */
@ -185,9 +218,9 @@ library { BEGIN INITIAL; return END_LIBRARY; }
return LITERAL; return LITERAL;
} }
string_literal_ensure_surplus(1); yylval.blobval.data = malloc(string_litral_buffer_size);
string_literal_buffer[string_litral_buffer_size+1] = '\0'; memcpy(yylval.blobval.data, string_literal_buffer, string_litral_buffer_size);
yylval.strval = strdup(string_literal_buffer); yylval.blobval.len = string_litral_buffer_size;
string_litral_buffer_size = 0; string_litral_buffer_size = 0;
return ARRAY_LITERAL; return ARRAY_LITERAL;
} }

View File

@ -20,6 +20,10 @@
%union{ %union{
long intval; long intval;
char * strval; char * strval;
struct {
unsigned long long len;
void * data;
} blobval;
variable_t varval; variable_t varval;
cpuregister_t regval; cpuregister_t regval;
} }
@ -43,12 +47,12 @@
%token<strval> IDENTIFIER LABEL %token<strval> IDENTIFIER LABEL
%type<intval> immediate %type<intval> immediate
%type<intval> memory dereference %type<intval> memory dereference
%type<intval> artimetric_block artimetric_expression artimetric_operand %type<intval> artimetric_block artimetric_expression artimetric_operand
%type<intval> value %type<intval> value
%token<intval> LITERAL %token<intval> LITERAL
%token<strval> ARRAY_LITERAL %token<blobval> ARRAY_LITERAL
// Specifiers // Specifiers
%token FAST %token FAST
@ -66,26 +70,24 @@
%token U8 U16 U32 U64 %token U8 U16 U32 U64
%type<intval> type %type<intval> type
%type<varval> declaration %type<varval> declaration
%type<varval> anon_variable
// Registers // Registers
%type<regval> register register64 register32 %type<regval> register register64s register32s register16s register8s
%token RBP RSP RIP // #placeholder<register_token_list> BEGIN
%token RAX RBX RCX RDX %token RAX RBX RCX RDX RSI RDI RBP RSP RG8 RG9 RG10 RG11 RG12 RG13 RG14 RG15
%token RSI RDI %token EAX EBX ECX EDX ESI EDI EBP ESP RG8D RG9D RG10D RG11D RG12D RG13D RG14D RG15D
%token RG8 RG9 RG10 RG11 RG12 RG13 RG14 RG15 %token AX BX CX DX SI DI BP SP R8W R9W R10W R11W R12W R13W R14W R15W
%token RGXMM0 RGXMM1 RGXMM2 RGXMM3 RGXMM4 RGXMM5 RGXMM6 RGXMM7 %token AL BL CL DL SIL DIL BPL SPL R8B R9B R10B R11B R12B R13B R14B R15B
%token EBP ESP EIP // #placeholder<register_token_list> END
%token EAX EBX ECX EDX
%token ESI EDI
%token RG8D RG9D RG10D RG11D RG12D RG13D RG14D RG15D
// Instructions // Instructions
%token INOP %token INOP
// #placeholder<token_list> BEGIN // #placeholder<instruction_token_list> BEGIN
%token ITADC ITADD ITAND ITCMP ITDEC ITDIV ITHLT ITIDIV ITIMUL ITINC ITLEAVE ITLOCK ITMOV ITMUL ITNEG ITNOT ITOR ITPAUSE ITRETF ITRETN ITSBB ITSUB ITSYSCALL ITSYSENTER ITSYSEXIT ITSYSRET ITXOR %token ITADC ITADD ITAND ITCMP ITDEC ITDIV ITHLT ITIDIV ITIMUL ITINC ITLEAVE ITLOCK ITMOV ITMUL ITNEG ITNOT ITOR ITPAUSE ITRETF ITRETN ITSAR ITSBB ITSUB ITSYSCALL ITSYSENTER ITSYSEXIT ITSYSRET ITXOR
// #placeholder<token_list> END // #placeholder<instruction_token_list> END
// Instruction-likes // Instruction-likes
%token FASTCALL %token FASTCALL
@ -151,14 +153,29 @@ declaration:
add_variable($$); add_variable($$);
} }
| variable_specifier type '<' value '>' IDENTIFIER { | variable_specifier type '<' value '>' IDENTIFIER {
if (validate_array_size($4)) {
break;
}
$$.name = make_scoped_name(scope, $6); $$.name = make_scoped_name(scope, $6);
$$.elements = $4; $$.elements = $4;
add_variable($$); add_variable($$);
} }
| variable_specifier type '<' value '>' IDENTIFIER '=' ARRAY_LITERAL { | variable_specifier type '<' value '>' IDENTIFIER '=' ARRAY_LITERAL {
if (validate_array_size($4)) {
break;
}
if ($4 < $8.len) {
issue_warning("you are a nigger");
}
$$.name = make_scoped_name(scope, $6); $$.name = make_scoped_name(scope, $6);
$$.elements = $4; $$.elements = $4;
$$.array_value = $8; $$.array_value = $8.data;
add_variable($$);
}
| variable_specifier type '<' '>' IDENTIFIER '=' ARRAY_LITERAL {
$$.name = make_scoped_name(scope, $5);
$$.elements = $7.len;
$$.array_value = $7.data;
add_variable($$); add_variable($$);
} }
; ;
@ -183,6 +200,7 @@ immediate: LITERAL
memory: artimetric_block memory: artimetric_block
| dereference | dereference
| IDENTIFIER
; ;
dereference: '[' IDENTIFIER '+' value ']' { $$ = 0; /* XXX: how the fuck do i dereference? */ } dereference: '[' IDENTIFIER '+' value ']' { $$ = 0; /* XXX: how the fuck do i dereference? */ }
@ -199,6 +217,15 @@ value: artimetric_block
} }
; ;
anon_variable: ARRAY_LITERAL {
$$.array_value = $1.data;
$$.elements = $1.len;
int ignore = asprintf(&$$.name, "_anon_%llu", anon_variable_counter++);
(void)ignore;
add_variable($$);
}
;
code: %empty code: %empty
| error code { /*yyerrok;*/ } | error code { /*yyerrok;*/ }
| repeat code | repeat code
@ -259,56 +286,91 @@ arguments: %empty
| LITERAL arguments | LITERAL arguments
| register arguments | register arguments
| artimetric_block arguments | artimetric_block arguments
| anon_variable arguments
; ;
register: register64 { $$ = $1; $$.size = D64; } register: register64s { $$ = $1; $$.size = D64; }
| register32 { $$ = $1; $$.size = D32; } | register32s { $$ = $1; $$.size = D32; }
| register16s { $$ = $1; $$.size = D16; }
| register8s { $$ = $1; $$.size = D8; }
; ;
register64: RAX { $$.number = R0; } // #placeholder<register_parser_rules> BEGIN
| RBX { $$.number = R1; } register64s: RAX { $$.number = R0; }
| RCX { $$.number = R2; } | RBX { $$.number = R1; }
| RDX { $$.number = R3; } | RCX { $$.number = R2; }
| RSI { $$.number = R4; } | RDX { $$.number = R3; }
| RDI { $$.number = R5; } | RSI { $$.number = R4; }
| RBP { $$.number = R6; } | RDI { $$.number = R5; }
| RSP { $$.number = R7; } | RBP { $$.number = R6; }
| RG8 { $$.number = R8; } | RSP { $$.number = R7; }
| RG9 { $$.number = R9; } | RG8 { $$.number = R8; }
| RG10 { $$.number = R10; } | RG9 { $$.number = R9; }
| RG11 { $$.number = R11; } | RG10 { $$.number = R10; }
| RG12 { $$.number = R12; } | RG11 { $$.number = R11; }
| RG13 { $$.number = R13; } | RG12 { $$.number = R12; }
| RG14 { $$.number = R14; } | RG13 { $$.number = R13; }
| RG15 { $$.number = R15; } | RG14 { $$.number = R14; }
| RGXMM0 { $$.number = 0; } /* XXX */ | RG15 { $$.number = R15; }
| RGXMM1 { $$.number = 0; }
| RGXMM2 { $$.number = 0; }
| RGXMM3 { $$.number = 0; }
| RGXMM4 { $$.number = 0; }
| RGXMM5 { $$.number = 0; }
| RGXMM6 { $$.number = 0; }
| RGXMM7 { $$.number = 0; }
; ;
register32: EAX { $$.number = R0; } register32s: EAX { $$.number = R0; }
| EBX { $$.number = R3; } | EBX { $$.number = R1; }
| ECX { $$.number = R1; } | ECX { $$.number = R2; }
| EDX { $$.number = R2; } | EDX { $$.number = R3; }
| ESI { $$.number = R6; } | ESI { $$.number = R4; }
| EDI { $$.number = R7; } | EDI { $$.number = R5; }
| EBP { $$.number = R5; } | EBP { $$.number = R6; }
| ESP { $$.number = R4; } | ESP { $$.number = R7; }
| RG8D { $$.number = R8; } | RG8D { $$.number = R8; }
| RG9D { $$.number = R9; } | RG9D { $$.number = R9; }
| RG10D { $$.number = R10; } | RG10D { $$.number = R10; }
| RG11D { $$.number = R11; } | RG11D { $$.number = R11; }
| RG12D { $$.number = R12; } | RG12D { $$.number = R12; }
| RG13D { $$.number = R13; } | RG13D { $$.number = R13; }
| RG14D { $$.number = R14; } | RG14D { $$.number = R14; }
| RG15D { $$.number = R15; } | RG15D { $$.number = R15; }
; ;
register16s: AX { $$.number = R0; }
| BX { $$.number = R1; }
| CX { $$.number = R2; }
| DX { $$.number = R3; }
| SI { $$.number = R4; }
| DI { $$.number = R5; }
| BP { $$.number = R6; }
| SP { $$.number = R7; }
| R8W { $$.number = R8; }
| R9W { $$.number = R9; }
| R10W { $$.number = R10; }
| R11W { $$.number = R11; }
| R12W { $$.number = R12; }
| R13W { $$.number = R13; }
| R14W { $$.number = R14; }
| R15W { $$.number = R15; }
;
register8s: AL { $$.number = R0; }
| BL { $$.number = R1; }
| CL { $$.number = R2; }
| DL { $$.number = R3; }
| SIL { $$.number = R4; }
| DIL { $$.number = R5; }
| BPL { $$.number = R6; }
| SPL { $$.number = R7; }
| R8B { $$.number = R8; }
| R9B { $$.number = R9; }
| R10B { $$.number = R10; }
| R11B { $$.number = R11; }
| R12B { $$.number = R12; }
| R13B { $$.number = R13; }
| R14B { $$.number = R14; }
| R15B { $$.number = R15; }
;
// #placeholder<register_parser_rules> END
artimetric_block: '{' artimetric_expression '}' { $$ = $2; } artimetric_block: '{' artimetric_expression '}' { $$ = $2; }
; ;
@ -329,6 +391,7 @@ artimetric_operand: LITERAL
exit: EXIT value exit: EXIT value
; ;
/* XXX */
library: LIBRARY declaration_section MYBEGIN library_code END_LIBRARY library: LIBRARY declaration_section MYBEGIN library_code END_LIBRARY
; ;
@ -337,11 +400,7 @@ library_code: %empty
; ;
instruction: INOP { append_instruction_t1(NOP); } instruction: INOP { append_instruction_t1(NOP); }
/* // #placeholder<instruction_parser_rules> BEGIN
| ISYSCALL { append_instruction_t1 (SYSCALL); }
| IMOV register immediate { append_instruction_t6 (MOV, $2.size, REG, $2.number, IMM, (int) $3); }
*/
// #placeholder<parser_rules> BEGIN
| ITSYSCALL { append_instruction_t1(SYSCALL); } | ITSYSCALL { append_instruction_t1(SYSCALL); }
| ITSYSRET { append_instruction_t1(SYSRET); } | ITSYSRET { append_instruction_t1(SYSRET); }
| ITSYSEXIT { append_instruction_t1(SYSEXIT); } | ITSYSEXIT { append_instruction_t1(SYSEXIT); }
@ -376,9 +435,11 @@ instruction: INOP { append_instruction_t1(NOP); }
| ITSUB register register { append_instruction_t6( SUB, $2.size, REG, $2.number, REG, $3.number ); } | ITSUB register register { append_instruction_t6( SUB, $2.size, REG, $2.number, REG, $3.number ); }
| ITXOR register register { append_instruction_t6( XOR, $2.size, REG, $2.number, REG, $3.number ); } | ITXOR register register { append_instruction_t6( XOR, $2.size, REG, $2.number, REG, $3.number ); }
| ITCMP register register { append_instruction_t6( CMP, $2.size, REG, $2.number, REG, $3.number ); } | ITCMP register register { append_instruction_t6( CMP, $2.size, REG, $2.number, REG, $3.number ); }
| ITSAR register immediate { append_instruction_t6( SAR, $2.size, REG, $2.number, IMM, (int)$3 ); }
| ITMOV register register { append_instruction_t6( MOV, $2.size, REG, $2.number, REG, $3.number ); }
| ITMOV register immediate { append_instruction_t6( MOV, $2.size, REG, $2.number, IMM, (int)$3 ); } | ITMOV register immediate { append_instruction_t6( MOV, $2.size, REG, $2.number, IMM, (int)$3 ); }
// #placeholder<parser_rules> END // #placeholder<instruction_parser_rules> END
; ;
%% %%

View File

@ -13,7 +13,16 @@ static void dump (const char * file_name);
#include "unix.h" #include "unix.h"
#include "debug.h" #include "debug.h"
extern void yyfree_leftovers(void); void free_n(void) {
extern void yyfree_leftovers(void);
yyfree_leftovers();
eaxhla_destroy();
free (text_sector_byte);
free (t_array);
}
char * yyfilename; char * yyfilename;
@ -51,12 +60,7 @@ signed main(int argc, char * argv[]) {
issue_warning("the input did not contain any instructions"); issue_warning("the input did not contain any instructions");
} }
yyfree_leftovers(); free_n();
eaxhla_destroy();
free (text_sector_byte);
free (t_array);
return has_encountered_error; return has_encountered_error;
} }

View File

@ -1,4 +1,5 @@
program main program main
u8<10> myarray u8<10> myarray
u8<> myarray2 = "test test test\0"
begin begin
end program end program

View File

@ -40,6 +40,7 @@ procedure read
in s32 file in s32 file
in u64 data in u64 data
in u64 size in u64 size
u8 <> fatal_message = "> failed to read from the file!\n\0"
begin begin
mov eax system_call_read mov eax system_call_read
mov edi file mov edi file
@ -48,7 +49,7 @@ begin
syscall syscall
if eax = -1 then if eax = -1 then
fastcall fatal "> failed to read from the file!\n\0" fastcall fatal fatal_message
end if end if
end procedure end procedure
@ -59,6 +60,7 @@ procedure write
in s32 file in s32 file
in u64 data in u64 data
in u64 size in u64 size
u8 <> fatal_message = "> failed to write to the file!\n\0"
begin begin
mov eax system_call_write mov eax system_call_write
mov edi file mov edi file
@ -67,7 +69,7 @@ begin
syscall syscall
if eax = -1 then if eax = -1 then
fastcall fatal "> failed to write to the file!\n\0" fastcall fatal fatal_message
end if end if
end procedure end procedure
@ -75,9 +77,9 @@ end procedure
fast fast
procedure open procedure open
in u64 name in u64 name
in s32 mode in s32 mode
in s32 * file in s32 file
begin begin
mov eax system_call_open mov eax system_call_open
mov rdi name mov rdi name
@ -112,7 +114,7 @@ unix program main
s32 file = 0 s32 file = 0
u8 byte = 0 u8 byte = 0
s8 [] digits = '0123456789abcdef\0' s8 <> digits = "0123456789abcdef\0"
s8 space = 32 s8 space = 32
s8 new_line = 10 s8 new_line = 10
begin begin
@ -120,12 +122,12 @@ begin
fastcall fatal "> argument count must be 2!\n\0" fastcall fatal "> argument count must be 2!\n\0"
end if end if
fastcall open argv [1] 0 file fastcall open argv 1 0 file
until r10 = 0 repeat until r10 = 0 repeat
fastcall read standard_input byte 1 fastcall read standard_input byte 1
// When EOF is reached 'rax', then 'r10' is 0. // When EOF is reached 'rax', then 'r10' is 0.
mov r10, rax mov r10 rax
if u8 [byte] = 0x90 then if u8 [byte] = 0x90 then
fastcall print "\n\0" fastcall print "\n\0"

View File

@ -1,4 +1,4 @@
source tool/instruction_generator/instructions.tcl source tool/generators/instructions.tcl
proc make_parser_rules {is} { proc make_parser_rules {is} {
proc init_iarg {a n} { proc init_iarg {a n} {

View File

@ -1,8 +1,8 @@
source tool/instruction_generator/instructions.tcl source tool/generators/instructions.tcl
proc make_scanner_instructions {is} { proc make_scanner_instructions {is} {
proc make_scanner_instruction {i} { proc make_scanner_instruction {i} {
puts [format "%s { return IT%s; }" \ puts [format "%-12s { return IT%s; }" \
[lindex $i 0] \ [lindex $i 0] \
[string toupper [lindex $i 0]] [string toupper [lindex $i 0]]
] ]

View File

@ -1,4 +1,4 @@
source tool/instruction_generator/instructions.tcl source tool/generators/instructions.tcl
proc make_token_list {is} { proc make_token_list {is} {
proc uniq_instl {is} { proc uniq_instl {is} {

View File

@ -33,6 +33,8 @@ set instructions {
{sub register register} {sub register register}
{xor register register} {xor register register}
{cmp register register} {cmp register register}
{sar register immediate}
{mov register register}
{mov register immediate} {mov register immediate}
} }

View File

@ -0,0 +1,26 @@
source tool/generators/registers.tcl
proc register_parsing {registers} {
proc register_parser_rule {size batch} {
puts [format "register%ss: %s \{ \$\$.number = R0; \}"\
$size\
[string toupper [lindex $batch 0]]\
]
set accumulator 1
foreach register [lrange $batch 1 end] {
puts [format " | %-5s \{ \$\$.number = R%s; \}"\
[string toupper $register]\
$accumulator\
]
incr accumulator
}
puts " ;"
puts ""
}
foreach {key value} $registers {
register_parser_rule $key $value
}
}
register_parsing $registers

View File

@ -0,0 +1,13 @@
source tool/generators/registers.tcl
proc scan_registers {registers} {
foreach {key value} $registers {
foreach {register} $value {
puts [format "%-6s \{ return %s; \}" $register [string toupper $register]]
}
}
}
puts " */"
scan_registers $registers

View File

@ -0,0 +1,13 @@
source tool/generators/registers.tcl
proc register_tokens {registers} {
proc generate_register_token_batch {batch} {
puts [format "%%token %s" [string toupper $batch]]
}
foreach {key value} $registers {
generate_register_token_batch [join $value " "]
}
}
register_tokens $registers

View File

@ -0,0 +1,92 @@
# XXX
#
# | RGXMM0 { $$.number = 0; } /* XXX */
# | RGXMM1 { $$.number = 0; }
# | RGXMM2 { $$.number = 0; }
# | RGXMM3 { $$.number = 0; }
# | RGXMM4 { $$.number = 0; }
# | RGXMM5 { $$.number = 0; }
# | RGXMM6 { $$.number = 0; }
# | RGXMM7 { $$.number = 0; }
set register64s {
rax
rbx
rcx
rdx
rsi
rdi
rbp
rsp
rg8
rg9
rg10
rg11
rg12
rg13
rg14
rg15
}
set register32s {
eax
ebx
ecx
edx
esi
edi
ebp
esp
rg8d
rg9d
rg10d
rg11d
rg12d
rg13d
rg14d
rg15d
}
set register16s {
ax
bx
cx
dx
si
di
bp
sp
r8w
r9w
r10w
r11w
r12w
r13w
r14w
r15w
}
set register8ls {
al
bl
cl
dl
sil
dil
bpl
spl
r8b
r9b
r10b
r11b
r12b
r13b
r14b
r15b
}
set registers [dict create]
dict set registers 64 $register64s
dict set registers 32 $register32s
dict set registers 16 $register16s
dict set registers 8 $register8ls

View File

@ -56,6 +56,7 @@ def usage():
{C[g]}{C[B]}--color{C[n]} {C[B]}{C[b]}never{C[y]}|{C[b]}auto{C[y]}|{C[b]}always{C[n]} : set output coloring option; default: auto {C[g]}{C[B]}--color{C[n]} {C[B]}{C[b]}never{C[y]}|{C[b]}auto{C[y]}|{C[b]}always{C[n]} : set output coloring option; default: auto
{C[g]}{C[B]}-d{C[n]} {C[b]}{C[B]}<name> <value>{C[n]} : define placeholder on the cli {C[g]}{C[B]}-d{C[n]} {C[b]}{C[B]}<name> <value>{C[n]} : define placeholder on the cli
{C[g]}{C[B]}-e{C[n]} {C[b]}{C[B]}<name> <file>{C[n]} : define placeholder as the contents of <file> {C[g]}{C[B]}-e{C[n]} {C[b]}{C[B]}<name> <file>{C[n]} : define placeholder as the contents of <file>
{C[g]}{C[B]}-a{C[n]} : define all undefined placeholders as empty strings
{C[g]}{C[B]}-u{C[n]} : ungenerate placeholders (ie. collapse) {C[g]}{C[B]}-u{C[n]} : ungenerate placeholders (ie. collapse)
{C[g]}{C[B]}-g{C[n]} : generate placeholders (ie. expand) {C[g]}{C[B]}-g{C[n]} : generate placeholders (ie. expand)
Every argument not starting with '-' is considered a file. Every argument not starting with '-' is considered a file.
@ -72,11 +73,22 @@ def usage():
{C[b]}@gnu-tofile-*{C[n]} {C[b]}@gnu-tofile-*{C[n]}
{C[y]}{C[B]}Example:{C[n]} {C[y]}{C[B]}Example:{C[n]}
// XXX REDO THIS WHOLE SECTION {C[g]}$ cat example/ex1.txt{C[n]}
original text
#placeholder<hw> COLLAPSED
some more original text
{C[g]}$ plug -g -d hw 'hello world' example/ex1.txt{C[n]}
{C[g]}$ cat example/ex1.txt{C[n]}
original text
#placeholder<hw> BEGIN
hello world
#placeholder<hw> END
some more original text
'''.format(**globals(), argv0 = sys.argv[0]), end='') '''.format(**globals(), argv0 = sys.argv[0]), end='')
destination_files = [] destination_files = []
operation = "" operation = ""
is_all = False
placeholders = {} placeholders = {}
@ -110,6 +122,8 @@ def builtin_lookup(phl : str) -> str:
return '' return ''
def gen(s : str, phls : [str]) -> str: def gen(s : str, phls : [str]) -> str:
global is_all
s = ungen(s, phls)
for phl in phls: for phl in phls:
buf = '' buf = ''
l = 0 l = 0
@ -122,10 +136,20 @@ def gen(s : str, phls : [str]) -> str:
l = m.end(0) l = m.end(0)
buf += s[l:] buf += s[l:]
s = buf s = buf
if is_all:
buf = ''
l = 0
for m in re_placeholder_collapsed.finditer(s):
buf += s[l : m.start(0)]
buf += m.group(1) + placeholder_expanded_beginning.format(m.group(2)) + '\n'
buf += m.group(1) + placeholder_expanded_ending.format(m.group(2))
l = m.end(0)
buf += s[l:]
s = buf
return s return s
def ungen(s : str, phls : [str]) -> str: def ungen(s : str, phls : [str]) -> str:
global is_all
for phl in phls: for phl in phls:
buf = '' buf = ''
l = 0 l = 0
@ -140,6 +164,19 @@ def ungen(s : str, phls : [str]) -> str:
break break
buf += s[l:] buf += s[l:]
s = buf s = buf
if is_all:
buf = ''
l = 0
for m in re_placeholder_expanded_beginning.finditer(s):
buf += s[l : m.start(0)]
buf += m.group(1) + placeholder_collapsed.format(m.group(2))
l = m.end(0)
for me in re_placeholder_expanded_ending.finditer(s[m.end(0):]):
if(me.group(1) != m.group(2)): continue
l = m.end(0) + me.end(0)
break
buf += s[l:]
s = buf
return s return s
def error_and_quit(e : int, argv : [str]) -> None: def error_and_quit(e : int, argv : [str]) -> None:
@ -159,7 +196,7 @@ def error_and_quit(e : int, argv : [str]) -> None:
# We need this function because getopt does not support a single flag taking 2 arguments # We need this function because getopt does not support a single flag taking 2 arguments
def parse_args(argv : [str]) -> None: def parse_args(argv : [str]) -> None:
global destination_files, operation global destination_files, operation, is_all
def get_param(argv : [str], i : int) -> str: def get_param(argv : [str], i : int) -> str:
try: param = argv[i] try: param = argv[i]
except: error_and_quit(Error.PARAM_MISS, [argv[i-1]]) except: error_and_quit(Error.PARAM_MISS, [argv[i-1]])
@ -180,6 +217,11 @@ def parse_args(argv : [str]) -> None:
i = i + 1 i = i + 1
continue continue
if argv[i] == '-a':
is_all = True
i = i + 1
continue
# 1 param opt # 1 param opt
if argv[i-1] == '--color': if argv[i-1] == '--color':
p = get_param(argv, i) p = get_param(argv, i)