stuff
This commit is contained in:
14
Makefile
14
Makefile
@ -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}
|
||||||
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
183
source/eaxhla.l
183
source/eaxhla.l
@ -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;
|
||||||
}
|
}
|
||||||
|
197
source/eaxhla.y
197
source/eaxhla.y
@ -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
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
18
test/nop.eax
18
test/nop.eax
@ -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"
|
||||||
|
@ -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} {
|
@ -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]]
|
||||||
]
|
]
|
@ -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} {
|
@ -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}
|
||||||
}
|
}
|
||||||
|
|
26
tool/generators/register_parser_rules.tcl
Normal file
26
tool/generators/register_parser_rules.tcl
Normal 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
|
13
tool/generators/register_scanner_instructions.tcl
Normal file
13
tool/generators/register_scanner_instructions.tcl
Normal 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
|
13
tool/generators/register_token_list.tcl
Normal file
13
tool/generators/register_token_list.tcl
Normal 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
|
92
tool/generators/registers.tcl
Normal file
92
tool/generators/registers.tcl
Normal 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
|
48
tool/plug
48
tool/plug
@ -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)
|
||||||
|
Reference in New Issue
Block a user