refactoring
This commit is contained in:
parent
3173bc21a1
commit
cf8719f58d
9
Makefile
9
Makefile
@ -5,7 +5,7 @@
|
||||
SOURCE.d := source
|
||||
OBJECT.d := object
|
||||
|
||||
SOURCE := main.c assembler.c eaxhla.c unix.c
|
||||
SOURCE := main.c assembler.c eaxhla.c compile.c unix.c
|
||||
OBJECT := $(addprefix ${OBJECT.d}/,${SOURCE})
|
||||
OBJECT := ${OBJECT:.c=.o}
|
||||
|
||||
@ -85,7 +85,12 @@ bootstrap:
|
||||
deepclean: unplug clean
|
||||
|
||||
clean:
|
||||
-rm ${OUT} ${OBJECT} ${GENOBJECT} ${GENSOURCE}
|
||||
-rm ${GENSOURCE}
|
||||
-rm ${GENOBJECT}
|
||||
-rm ${OBJECT}
|
||||
-rm ${OUT}
|
||||
-rm token_dump
|
||||
-rm a.out
|
||||
|
||||
${OUT}: ${PLUGLOCK} ${GENSOURCE} ${GENOBJECT} ${OBJECT} ${LIB}
|
||||
${LINK.c} -o $@ ${OBJECT} ${GENOBJECT} ${LDLIBS} library/tommyds/tommy.o
|
||||
|
136
source/compile.c
Normal file
136
source/compile.c
Normal file
@ -0,0 +1,136 @@
|
||||
#include "compile.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "eaxhla.h"
|
||||
#include "assembler.h"
|
||||
#include "unix.h"
|
||||
#include "debug.h"
|
||||
|
||||
unsigned int * token_array = NULL;
|
||||
unsigned int token_count = 0;
|
||||
|
||||
char * output_file_name = "a.out";
|
||||
|
||||
static
|
||||
void dump_variable_to_assembler(void * data) {
|
||||
variable_t * variable = (variable_t*)data;
|
||||
append_instruction_t4(ASMDIRMEM, variable->_id, ASMDIRIMM, type2size(variable->type));
|
||||
append_instruction_t1(variable->elements);
|
||||
if (variable->elements == 1) {
|
||||
append_instruction_t1(variable->value);
|
||||
} else {
|
||||
for (unsigned long long i = 0; i < variable->elements; i++) {
|
||||
append_instruction_t1((int)*((char*)(variable->array_value + i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void dump_variables_to_assembler(void) {
|
||||
tommy_hashtable_foreach(&variable_table, dump_variable_to_assembler);
|
||||
}
|
||||
|
||||
static
|
||||
int write_output(FILE * file) {
|
||||
// XXX Error checking
|
||||
elf_main_header (1, 1, 1, 0);
|
||||
elf_text_sector (text_sector_size);
|
||||
elf_data_sector (text_sector_size, 12);
|
||||
|
||||
fwrite (elf_main_header_byte, 1UL, ELF_MAIN_HEADER_SIZE, file);
|
||||
fwrite (elf_text_sector_byte, 1UL, ELF_TEXT_SECTOR_SIZE, file);
|
||||
fwrite (elf_data_sector_byte, 1UL, ELF_DATA_SECTOR_SIZE, file);
|
||||
|
||||
//text
|
||||
fwrite (text_sector_byte, sizeof (* text_sector_byte),
|
||||
(size_t) text_sector_size, file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int make_executable(const char * const filename) {
|
||||
// XXX only works on *nix
|
||||
int r = chmod(filename, 0755);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int compile(void) {
|
||||
debug_puts("Compiling output...");
|
||||
|
||||
dump_variables_to_assembler();
|
||||
|
||||
assemble(token_count, token_array);
|
||||
|
||||
FILE * output_file = fopen (output_file_name, "w");
|
||||
write_output(output_file);
|
||||
fclose(output_file);
|
||||
|
||||
make_executable(output_file_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void append_token (int t) {
|
||||
// XXX rewrite this and use memcpy
|
||||
token_array [token_count] = t;
|
||||
token_count += 1;
|
||||
}
|
||||
|
||||
void append_instruction_t1 (int t1) {
|
||||
append_token (t1); // operation
|
||||
}
|
||||
|
||||
void append_instruction_t4 (int t4, int w, int d, int r) {
|
||||
append_token (t4); // operation
|
||||
append_token (w); // width
|
||||
append_token (d); // destination
|
||||
append_token (r); // register
|
||||
}
|
||||
|
||||
void append_instruction_t6 (int t6, int w, int d, int r, int s, int i) {
|
||||
append_token (t6); // operation
|
||||
append_token (w); // width
|
||||
append_token (d); // destination
|
||||
append_token (r); // register
|
||||
append_token (s); // source
|
||||
append_token (i); // immediate
|
||||
}
|
||||
|
||||
// my_label:
|
||||
void append_label (int rel) {
|
||||
append_instruction_t1 (ASMDIRMEM);
|
||||
append_instruction_t1 (rel);
|
||||
}
|
||||
|
||||
// procedure my_procedure ... <argv> ... begin
|
||||
// rel = my_procedure (some unique index)
|
||||
// best if it's count of defined procedures!
|
||||
// it must not be address of it, or huge number!
|
||||
// optimally, it should be number 0 ... 140.
|
||||
// for now, 140 procedures is enough, will expand later!
|
||||
void append_fastcall_begin (int rel) {
|
||||
append_label (rel);
|
||||
}
|
||||
|
||||
// end procedure
|
||||
void append_fastcall_end (void) {
|
||||
append_instruction_t1 (RETN);
|
||||
}
|
||||
|
||||
// append these at the end, postpone it!
|
||||
// this function needs to be called after ALL instructions are parsed.
|
||||
// it has to do with structure of every binary executable file!
|
||||
// we can add it later, it's "triggered" on 'in'.
|
||||
void append_fastcall_arguments (int rel, int wid, int imm) { // TODO
|
||||
append_instruction_t1 (ASMDIRMEM);
|
||||
append_instruction_t1 (rel);
|
||||
append_instruction_t1 (ASMDIRIMM);
|
||||
append_instruction_t1 (wid);
|
||||
append_instruction_t1 (imm);
|
||||
}
|
21
source/compile.h
Normal file
21
source/compile.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef COMPILE_H
|
||||
#define COMPILE_H
|
||||
|
||||
extern unsigned int * token_array;
|
||||
extern unsigned int token_count;
|
||||
|
||||
extern char * output_file_name;
|
||||
|
||||
extern int compile(void);
|
||||
|
||||
extern void append_instruction_t1 (int t1);
|
||||
extern void append_instruction_t4 (int t4, int w, int d, int r);
|
||||
extern void append_instruction_t6 (int t6, int w, int d, int r, int s, int i);
|
||||
|
||||
extern void append_label (int rel);
|
||||
|
||||
extern void append_fastcall_begin (int rel);
|
||||
extern void append_fastcall_end (void);
|
||||
extern void append_fastcall_arguments (int rel, int wid, int imm);
|
||||
|
||||
#endif
|
@ -6,8 +6,6 @@
|
||||
#include <stdarg.h>
|
||||
#include "eaxhla.h"
|
||||
|
||||
extern tommy_hashtable variable_table;
|
||||
|
||||
# define debug_puts(msg) do { puts(msg); } while (0)
|
||||
|
||||
static // this is less horid than macro varargs
|
||||
@ -43,10 +41,10 @@ void debug_dump_variables(void) {
|
||||
|
||||
static
|
||||
void debug_token_dump(void) {
|
||||
extern unsigned int * t_array;
|
||||
extern unsigned int t_count;
|
||||
extern unsigned int * token_array;
|
||||
extern unsigned int token_count;
|
||||
FILE * o = fopen("token_dump", "wb");
|
||||
fwrite(t_array, sizeof(int), t_count, o);
|
||||
fwrite(token_array, sizeof(int), token_count, o);
|
||||
fclose(o);
|
||||
}
|
||||
|
||||
|
126
source/eaxhla.c
126
source/eaxhla.c
@ -10,18 +10,43 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "eaxhla.tab.h"
|
||||
|
||||
#include "debug.h"
|
||||
#include "assembler.h"
|
||||
#include "compile.h"
|
||||
|
||||
unsigned long long anon_variable_counter = 0;
|
||||
|
||||
tommy_hashtable variable_table;
|
||||
|
||||
int has_encountered_error = 0;
|
||||
int is_program_found = 0;
|
||||
|
||||
char * scope = NULL;
|
||||
int is_program_found = 0;
|
||||
|
||||
char * yyfilename = "";
|
||||
|
||||
|
||||
int eaxhla_init(void) {
|
||||
tommy_hashtable_init(&variable_table, 256);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void free_variable(void * data) {
|
||||
variable_t * variable = (variable_t*)data;
|
||||
free(variable->name);
|
||||
free(variable);
|
||||
}
|
||||
|
||||
int eaxhla_destroy(void) {
|
||||
tommy_hashtable_foreach(&variable_table, free_variable);
|
||||
tommy_hashtable_done(&variable_table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static
|
||||
int table_compare_unsigned(const void * arg, const void * obj) {
|
||||
@ -105,6 +130,7 @@ int type2size(int type) {
|
||||
return D64;
|
||||
}
|
||||
|
||||
issue_error("internal error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -145,23 +171,7 @@ variable_t * get_variable(const char * const name) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int eaxhla_init(void) {
|
||||
tommy_hashtable_init(&variable_table, 256);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void free_variable(void * data) {
|
||||
variable_t * variable = (variable_t*)data;
|
||||
free(variable->name);
|
||||
free(variable);
|
||||
}
|
||||
|
||||
int eaxhla_destroy(void) {
|
||||
tommy_hashtable_foreach(&variable_table, free_variable);
|
||||
tommy_hashtable_done(&variable_table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void issue_warning(const char * const format, ...) {
|
||||
extern char * yyfilename;
|
||||
@ -201,86 +211,6 @@ void issue_error(const char * const format, ...) {
|
||||
free(msg);
|
||||
}
|
||||
|
||||
static
|
||||
void dump_variable_to_assembler(void * data) {
|
||||
variable_t * variable = (variable_t*)data;
|
||||
append_instruction_t4(ASMDIRMEM, variable->_id, ASMDIRIMM, type2size(variable->type));
|
||||
append_instruction_t1(variable->elements);
|
||||
if (variable->elements == 1) {
|
||||
append_instruction_t1(variable->value);
|
||||
} else {
|
||||
for (unsigned long long i = 0; i < variable->elements; i++) {
|
||||
debug_printf("'%d'\n", (int)*(char*)(variable->array_value + i));
|
||||
append_instruction_t1((int)*(char*)(variable->array_value + i));
|
||||
}
|
||||
//memcpy(t_array + t_count, variable->array_value, variable->elements);
|
||||
}
|
||||
}
|
||||
|
||||
void dump_variables_to_assembler(void) {
|
||||
tommy_hashtable_foreach(&variable_table, dump_variable_to_assembler);
|
||||
}
|
||||
|
||||
static
|
||||
void append_token (int t) {
|
||||
// XXX rewrite this and use memcpy
|
||||
t_array [t_count] = t;
|
||||
t_count += 1;
|
||||
}
|
||||
|
||||
void append_instruction_t1 (int t1) {
|
||||
append_token (t1); // operation
|
||||
}
|
||||
|
||||
void append_instruction_t4 (int t4, int w, int d, int r) {
|
||||
append_token (t4); // operation
|
||||
append_token (w); // width
|
||||
append_token (d); // destination
|
||||
append_token (r); // register
|
||||
}
|
||||
|
||||
void append_instruction_t6 (int t6, int w, int d, int r, int s, int i) {
|
||||
append_token (t6); // operation
|
||||
append_token (w); // width
|
||||
append_token (d); // destination
|
||||
append_token (r); // register
|
||||
append_token (s); // source
|
||||
append_token (i); // immediate
|
||||
}
|
||||
|
||||
// my_label:
|
||||
void append_label (int rel) {
|
||||
append_instruction_t1 (ASMDIRMEM);
|
||||
append_instruction_t1 (rel);
|
||||
}
|
||||
|
||||
// procedure my_procedure ... <argv> ... begin
|
||||
// rel = my_procedure (some unique index)
|
||||
// best if it's count of defined procedures!
|
||||
// it must not be address of it, or huge number!
|
||||
// optimally, it should be number 0 ... 140.
|
||||
// for now, 140 procedures is enough, will expand later!
|
||||
void append_fastcall_begin (int rel) {
|
||||
append_label (rel);
|
||||
}
|
||||
|
||||
// end procedure
|
||||
void append_fastcall_end (void) {
|
||||
append_instruction_t1 (RETN);
|
||||
}
|
||||
|
||||
// append these at the end, postpone it!
|
||||
// this function needs to be called after ALL instructions are parsed.
|
||||
// it has to do with structure of every binary executable file!
|
||||
// we can add it later, it's "triggered" on 'in'.
|
||||
void append_fastcall_arguments (int rel, int wid, int imm) { // TODO
|
||||
append_instruction_t1 (ASMDIRMEM);
|
||||
append_instruction_t1 (rel);
|
||||
append_instruction_t1 (ASMDIRIMM);
|
||||
append_instruction_t1 (wid);
|
||||
append_instruction_t1 (imm);
|
||||
}
|
||||
|
||||
int system_type =
|
||||
#if defined(__unix__)
|
||||
UNIX
|
||||
|
@ -17,10 +17,9 @@ typedef struct {
|
||||
tommy_node _node;
|
||||
} variable_t;
|
||||
|
||||
extern unsigned long long anon_variable_counter;
|
||||
extern tommy_hashtable variable_table;
|
||||
|
||||
#define REGISTER64_MASK 0x00;
|
||||
#define REGISTER32_MASK 0x01;
|
||||
extern unsigned long long anon_variable_counter;
|
||||
|
||||
typedef struct {
|
||||
unsigned number : 6;
|
||||
@ -34,8 +33,8 @@ extern int has_encountered_error;
|
||||
|
||||
extern char * scope;
|
||||
|
||||
extern unsigned int * t_array;
|
||||
extern unsigned int t_count;
|
||||
// Used for error reporting
|
||||
extern char * yyfilename;
|
||||
|
||||
extern int eaxhla_init(void);
|
||||
extern int eaxhla_destroy(void);
|
||||
@ -47,80 +46,8 @@ extern int validate_array_size(int size);
|
||||
extern void add_variable(variable_t variable);
|
||||
extern variable_t * get_variable(const char * const name);
|
||||
|
||||
extern void append_instruction_t1 (int t1);
|
||||
extern void append_instruction_t4 (int t4, int w, int d, int r);
|
||||
extern void append_instruction_t6 (int t6, int w, int d, int r, int s, int i);
|
||||
|
||||
extern int type2size(int type);
|
||||
|
||||
/*
|
||||
-- THIS WILL BE REMOVED, HELPER COMMENT FOR ME...
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
fast procedure XXX
|
||||
in u32 AAA
|
||||
in u32 BBB
|
||||
begin
|
||||
{ IMPL }
|
||||
end procedure
|
||||
|
||||
----------------------------------------
|
||||
|
||||
XXX:
|
||||
-- POSTPONE THOSE ARGUMENTS, IMPORTANT...
|
||||
-- BEGIN
|
||||
{ IMPL }
|
||||
-- END
|
||||
ret
|
||||
...
|
||||
XXX_AAA: dd 0 -- NOW WE DEFINE THOSE ARGUMENTS
|
||||
XXX_BBB: dd 0 -- NOW WE DEFINE THOSE ARGUMENTS
|
||||
|
||||
----------------------------------------
|
||||
|
||||
ASMDIRMEM [?] -- IDENTIFIER FOR XXX
|
||||
{ IMPL } -- USAGE OF OTHER 'append_<>' FUNCTIONS...
|
||||
RETN
|
||||
... -- OTHER CODE
|
||||
ASMDIRMEM [?] ASMDIRIMM D32 0 -- IDENTIFIER FOR XXX_AAA
|
||||
ASMDIRMEM [?] ASMDIRIMM D32 0 -- IDENTIFIER FOR XXX_BBB
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
fastcall XXX A B
|
||||
|
||||
----------------------------------------
|
||||
|
||||
mov [XXX_AAA], A
|
||||
mov [XXX_BBB], B
|
||||
call XXX
|
||||
-- mov [XXX_AAA], rax -- OKAY
|
||||
-- mov [XXX_AAA], 24 -- OKAY
|
||||
-- mov [XXX_AAA], MY_REL -- OKAY
|
||||
-- mov [XXX_AAA], [MY_MEM] -- NOT OKAY
|
||||
-- FIX
|
||||
-- mov rax, [MY_MEM]
|
||||
-- mov [XXX_AAA], rax -- NOW OKAY
|
||||
-- NOW FAST PROCEDURE XXX DOES THE WORK...
|
||||
|
||||
----------------------------------------
|
||||
|
||||
MOV D?? MEM [XXX_AAA] REG/MEM/IMM/REL [?]
|
||||
MOV D?? MEM [XXX_BBB] REG/MEM/IMM/REL [?]
|
||||
CALL D32 REL XXX
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
extern void append_label (int rel);
|
||||
|
||||
extern void append_fastcall_begin (int rel);
|
||||
extern void append_fastcall_end (void);
|
||||
extern void append_fastcall_arguments (int rel, int wid, int imm);
|
||||
|
||||
extern void dump_variables_to_assembler(void);
|
||||
|
||||
extern void issue_warning(const char * format, ...);
|
||||
extern void issue_error(const char * format, ...);
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "eaxhla.yy.h"
|
||||
#include "assembler.h"
|
||||
#include "compile.h"
|
||||
#include "eaxhla.h"
|
||||
|
||||
extern void yyfree_leftovers(void);
|
||||
|
@ -1,17 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
unsigned int * t_array = NULL;
|
||||
unsigned int t_count = 0;
|
||||
|
||||
static void dump (const char * file_name);
|
||||
void dump_variables();
|
||||
|
||||
#include "eaxhla.h"
|
||||
#include "eaxhla.yy.h"
|
||||
#include "eaxhla.tab.h"
|
||||
#include "compile.h"
|
||||
#include "assembler.h"
|
||||
#include "unix.h"
|
||||
#include "debug.h"
|
||||
|
||||
void deinit(void) {
|
||||
@ -22,11 +16,9 @@ void deinit(void) {
|
||||
eaxhla_destroy();
|
||||
|
||||
free (text_sector_byte);
|
||||
free (t_array);
|
||||
free (token_array);
|
||||
}
|
||||
|
||||
char * yyfilename;
|
||||
|
||||
signed main(int argc, char * argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("%s: <file>\n", argv[0]);
|
||||
@ -34,7 +26,7 @@ signed main(int argc, char * argv[]) {
|
||||
}
|
||||
|
||||
text_sector_byte = calloc (1440UL, sizeof (* text_sector_byte));
|
||||
t_array = calloc (1440UL, sizeof (* t_array));
|
||||
token_array = calloc (1440UL, sizeof (* token_array));
|
||||
|
||||
#if DEBUG == 1
|
||||
yydebug = 1;
|
||||
@ -54,10 +46,7 @@ signed main(int argc, char * argv[]) {
|
||||
debug_dump_variables();
|
||||
|
||||
if (!has_encountered_error) {
|
||||
dump_variables_to_assembler();
|
||||
assemble (t_count, t_array);
|
||||
debug_puts("Dumping output...");
|
||||
dump ("a.out");
|
||||
compile();
|
||||
}
|
||||
|
||||
if (was_instruction_array_empty) {
|
||||
@ -68,31 +57,3 @@ signed main(int argc, char * argv[]) {
|
||||
|
||||
return has_encountered_error;
|
||||
}
|
||||
|
||||
void dump (const char * file_name) {
|
||||
elf_main_header (1, 1, 1, 0);
|
||||
elf_text_sector (text_sector_size);
|
||||
elf_data_sector (text_sector_size, 12);
|
||||
|
||||
char meme [1024] = "";
|
||||
FILE * file = fopen (file_name, "w");
|
||||
|
||||
fwrite (elf_main_header_byte, 1UL, ELF_MAIN_HEADER_SIZE, file);
|
||||
fwrite (elf_text_sector_byte, 1UL, ELF_TEXT_SECTOR_SIZE, file);
|
||||
fwrite (elf_data_sector_byte, 1UL, ELF_DATA_SECTOR_SIZE, file);
|
||||
|
||||
//text
|
||||
fwrite (text_sector_byte, sizeof (* text_sector_byte),
|
||||
(size_t) text_sector_size, file);
|
||||
|
||||
/*
|
||||
// data
|
||||
fwrite ("heyo world!\n", 1UL, 12UL, file);
|
||||
*/
|
||||
|
||||
snprintf (meme, 1023UL, "chmod +x %s", file_name);
|
||||
|
||||
system (meme);
|
||||
|
||||
fclose (file);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user