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

@ -15,7 +15,7 @@ LIBS := $(addprefix ${OBJECT.d}/,${LIBS.source})
GENSOURCE := eaxhla.yy.c eaxhla.tab.c
GENSOURCE := $(addprefix ${OBJECT.d}/,${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})
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
${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 $< > $@
unplug:
-rm ${PLUGLOCK}
${PLUG} -u -d token_list '' -d scanner_instructions '' -d parser_rules '' 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
${PLUG} -u -a source/eaxhla.l source/eaxhla.y
${OBJECT.d}/%.pluglock: ${OBJECT.d}/%.pp
${PLUG} -g -e $* $< ${PLUGFILES}
@ -86,7 +82,9 @@ test: ${OUT}
bootstrap:
./library/bootstrap.sh
clean: unplug
deepclean: unplug clean
clean:
-rm ${OUT} ${OBJECT} ${GENOBJECT} ${GENSOURCE}
${OUT}: ${PLUGLOCK} ${GENSOURCE} ${GENOBJECT} ${OBJECT} ${LIB}

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

@ -14,6 +14,8 @@
#include "eaxhla.tab.h"
#include "assembler.h"
unsigned long long anon_variable_counter = 0;
tommy_hashtable variable_table;
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;
}
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) {
if (!scope) {
return name;

@ -9,12 +9,14 @@ typedef struct {
long value;
void * array_value;
};
int elements;
unsigned long long elements;
char * name;
unsigned _hash;
tommy_node _node;
} variable_t;
extern unsigned long long anon_variable_counter;
#define REGISTER64_MASK 0x00;
#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 int can_fit(int type, long long value);
extern int validate_array_size(int size);
extern void add_variable(variable_t variable);
extern variable_t * get_variable(const char * const name);

@ -47,7 +47,7 @@ machine { return MACHINE; }
library { return LIBRARY; }
break { return BREAK; }
UNTIL { return UNTIL; }
until { return UNTIL; }
exit { return EXIT; }
end { BEGIN IN_END; }
@ -55,48 +55,8 @@ end { BEGIN IN_END; }
fast { return FAST; }
unix { return UNIX; }
rax { return RAX; }
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; }
/* #placeholder<register_scanner_instructions> END
*/
in { return TIN; }
\= { return '='; }
@ -124,39 +84,112 @@ u64 { return U64; }
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 --- */
nop { return INOP; }
/* #placeholder<scanner_instructions> BEGIN
/* #placeholder<instruction_scanner_instructions> BEGIN
*/
adc { return ITADC; }
add { return ITADD; }
and { return ITAND; }
cmp { return ITCMP; }
dec { return ITDEC; }
div { return ITDIV; }
hlt { return ITHLT; }
idiv { return ITIDIV; }
imul { return ITIMUL; }
inc { return ITINC; }
leave { return ITLEAVE; }
lock { return ITLOCK; }
mov { return ITMOV; }
mul { return ITMUL; }
neg { return ITNEG; }
not { return ITNOT; }
or { return ITOR; }
pause { return ITPAUSE; }
retf { return ITRETF; }
retn { return ITRETN; }
sbb { return ITSBB; }
sub { return ITSUB; }
syscall { return ITSYSCALL; }
sysenter { return ITSYSENTER; }
sysexit { return ITSYSEXIT; }
sysret { return ITSYSRET; }
xor { return ITXOR; }
adc { return ITADC; }
add { return ITADD; }
and { return ITAND; }
cmp { return ITCMP; }
dec { return ITDEC; }
div { return ITDIV; }
hlt { return ITHLT; }
idiv { return ITIDIV; }
imul { return ITIMUL; }
inc { return ITINC; }
leave { return ITLEAVE; }
lock { return ITLOCK; }
mov { return ITMOV; }
mul { return ITMUL; }
neg { return ITNEG; }
not { return ITNOT; }
or { return ITOR; }
pause { return ITPAUSE; }
retf { return ITRETF; }
retn { return ITRETN; }
sar { return ITSAR; }
sbb { return ITSBB; }
sub { return ITSUB; }
syscall { return ITSYSCALL; }
sysenter { return ITSYSENTER; }
sysexit { return ITSYSEXIT; }
sysret { return ITSYSRET; }
xor { return ITXOR; }
/* #placeholder<scanner_instructions> END
/* #placeholder<instruction_scanner_instructions> END
*/
/* --- Instrunctions end here --- */
@ -185,9 +218,9 @@ library { BEGIN INITIAL; return END_LIBRARY; }
return LITERAL;
}
string_literal_ensure_surplus(1);
string_literal_buffer[string_litral_buffer_size+1] = '\0';
yylval.strval = strdup(string_literal_buffer);
yylval.blobval.data = malloc(string_litral_buffer_size);
memcpy(yylval.blobval.data, string_literal_buffer, string_litral_buffer_size);
yylval.blobval.len = string_litral_buffer_size;
string_litral_buffer_size = 0;
return ARRAY_LITERAL;
}

@ -20,6 +20,10 @@
%union{
long intval;
char * strval;
struct {
unsigned long long len;
void * data;
} blobval;
variable_t varval;
cpuregister_t regval;
}
@ -43,12 +47,12 @@
%token<strval> IDENTIFIER LABEL
%type<intval> immediate
%type<intval> memory dereference
%type<intval> artimetric_block artimetric_expression artimetric_operand
%type<intval> value
%token<intval> LITERAL
%token<strval> ARRAY_LITERAL
%type<intval> immediate
%type<intval> memory dereference
%type<intval> artimetric_block artimetric_expression artimetric_operand
%type<intval> value
%token<intval> LITERAL
%token<blobval> ARRAY_LITERAL
// Specifiers
%token FAST
@ -66,26 +70,24 @@
%token U8 U16 U32 U64
%type<intval> type
%type<varval> declaration
%type<varval> anon_variable
// Registers
%type<regval> register register64 register32
%type<regval> register register64s register32s register16s register8s
%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
// #placeholder<register_token_list> BEGIN
%token RAX RBX RCX RDX RSI RDI RBP RSP RG8 RG9 RG10 RG11 RG12 RG13 RG14 RG15
%token EAX EBX ECX EDX ESI EDI EBP ESP RG8D RG9D RG10D RG11D RG12D RG13D RG14D RG15D
%token AX BX CX DX SI DI BP SP R8W R9W R10W R11W R12W R13W R14W R15W
%token AL BL CL DL SIL DIL BPL SPL R8B R9B R10B R11B R12B R13B R14B R15B
%token EBP ESP EIP
%token EAX EBX ECX EDX
%token ESI EDI
%token RG8D RG9D RG10D RG11D RG12D RG13D RG14D RG15D
// #placeholder<register_token_list> END
// Instructions
%token INOP
// #placeholder<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
// #placeholder<token_list> END
// #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 ITSAR ITSBB ITSUB ITSYSCALL ITSYSENTER ITSYSEXIT ITSYSRET ITXOR
// #placeholder<instruction_token_list> END
// Instruction-likes
%token FASTCALL
@ -151,14 +153,29 @@ declaration:
add_variable($$);
}
| variable_specifier type '<' value '>' IDENTIFIER {
if (validate_array_size($4)) {
break;
}
$$.name = make_scoped_name(scope, $6);
$$.elements = $4;
add_variable($$);
}
| 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);
$$.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($$);
}
;
@ -183,6 +200,7 @@ immediate: LITERAL
memory: artimetric_block
| dereference
| IDENTIFIER
;
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
| error code { /*yyerrok;*/ }
| repeat code
@ -259,56 +286,91 @@ arguments: %empty
| LITERAL arguments
| register arguments
| artimetric_block arguments
| anon_variable arguments
;
register: register64 { $$ = $1; $$.size = D64; }
| register32 { $$ = $1; $$.size = D32; }
register: register64s { $$ = $1; $$.size = D64; }
| register32s { $$ = $1; $$.size = D32; }
| register16s { $$ = $1; $$.size = D16; }
| register8s { $$ = $1; $$.size = D8; }
;
register64: RAX { $$.number = R0; }
| RBX { $$.number = R1; }
| RCX { $$.number = R2; }
| RDX { $$.number = R3; }
| RSI { $$.number = R4; }
| RDI { $$.number = R5; }
| RBP { $$.number = R6; }
| RSP { $$.number = R7; }
| RG8 { $$.number = R8; }
| RG9 { $$.number = R9; }
| RG10 { $$.number = R10; }
| RG11 { $$.number = R11; }
| RG12 { $$.number = R12; }
| RG13 { $$.number = R13; }
| RG14 { $$.number = R14; }
| RG15 { $$.number = R15; }
| 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; }
// #placeholder<register_parser_rules> BEGIN
register64s: RAX { $$.number = R0; }
| RBX { $$.number = R1; }
| RCX { $$.number = R2; }
| RDX { $$.number = R3; }
| RSI { $$.number = R4; }
| RDI { $$.number = R5; }
| RBP { $$.number = R6; }
| RSP { $$.number = R7; }
| RG8 { $$.number = R8; }
| RG9 { $$.number = R9; }
| RG10 { $$.number = R10; }
| RG11 { $$.number = R11; }
| RG12 { $$.number = R12; }
| RG13 { $$.number = R13; }
| RG14 { $$.number = R14; }
| RG15 { $$.number = R15; }
;
register32: EAX { $$.number = R0; }
| EBX { $$.number = R3; }
| ECX { $$.number = R1; }
| EDX { $$.number = R2; }
| ESI { $$.number = R6; }
| EDI { $$.number = R7; }
| EBP { $$.number = R5; }
| ESP { $$.number = R4; }
| RG8D { $$.number = R8; }
| RG9D { $$.number = R9; }
| RG10D { $$.number = R10; }
| RG11D { $$.number = R11; }
| RG12D { $$.number = R12; }
| RG13D { $$.number = R13; }
| RG14D { $$.number = R14; }
| RG15D { $$.number = R15; }
register32s: EAX { $$.number = R0; }
| EBX { $$.number = R1; }
| ECX { $$.number = R2; }
| EDX { $$.number = R3; }
| ESI { $$.number = R4; }
| EDI { $$.number = R5; }
| EBP { $$.number = R6; }
| ESP { $$.number = R7; }
| RG8D { $$.number = R8; }
| RG9D { $$.number = R9; }
| RG10D { $$.number = R10; }
| RG11D { $$.number = R11; }
| RG12D { $$.number = R12; }
| RG13D { $$.number = R13; }
| RG14D { $$.number = R14; }
| 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; }
;
@ -329,6 +391,7 @@ artimetric_operand: LITERAL
exit: EXIT value
;
/* XXX */
library: LIBRARY declaration_section MYBEGIN library_code END_LIBRARY
;
@ -337,11 +400,7 @@ library_code: %empty
;
instruction: INOP { append_instruction_t1(NOP); }
/*
| ISYSCALL { append_instruction_t1 (SYSCALL); }
| IMOV register immediate { append_instruction_t6 (MOV, $2.size, REG, $2.number, IMM, (int) $3); }
*/
// #placeholder<parser_rules> BEGIN
// #placeholder<instruction_parser_rules> BEGIN
| ITSYSCALL { append_instruction_t1(SYSCALL); }
| ITSYSRET { append_instruction_t1(SYSRET); }
| 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 ); }
| 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 ); }
| 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 ); }
// #placeholder<parser_rules> END
// #placeholder<instruction_parser_rules> END
;
%%

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

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

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

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

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

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

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

@ -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

@ -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

@ -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

@ -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

@ -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]}-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]}-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]}-g{C[n]} : generate placeholders (ie. expand)
Every argument not starting with '-' is considered a file.
@ -72,11 +73,22 @@ def usage():
{C[b]}@gnu-tofile-*{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='')
destination_files = []
operation = ""
is_all = False
placeholders = {}
@ -110,6 +122,8 @@ def builtin_lookup(phl : str) -> str:
return ''
def gen(s : str, phls : [str]) -> str:
global is_all
s = ungen(s, phls)
for phl in phls:
buf = ''
l = 0
@ -122,10 +136,20 @@ def gen(s : str, phls : [str]) -> str:
l = m.end(0)
buf += s[l:]
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
def ungen(s : str, phls : [str]) -> str:
global is_all
for phl in phls:
buf = ''
l = 0
@ -140,6 +164,19 @@ def ungen(s : str, phls : [str]) -> str:
break
buf += s[l:]
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
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
def parse_args(argv : [str]) -> None:
global destination_files, operation
global destination_files, operation, is_all
def get_param(argv : [str], i : int) -> str:
try: param = argv[i]
except: error_and_quit(Error.PARAM_MISS, [argv[i-1]])
@ -180,6 +217,11 @@ def parse_args(argv : [str]) -> None:
i = i + 1
continue
if argv[i] == '-a':
is_all = True
i = i + 1
continue
# 1 param opt
if argv[i-1] == '--color':
p = get_param(argv, i)