174 lines
4.2 KiB
C
174 lines
4.2 KiB
C
#if (!defined(NTSYS_ASSEMBLER_H___))
|
|
#define NTSYS_ASSEMBLER_H___
|
|
|
|
#define NTSYS_MAX_LABEL_LENGTH 32
|
|
|
|
#include "asm-savers.h"
|
|
|
|
/*
|
|
* :T - тип данных
|
|
* :D - данные
|
|
* :S - строка
|
|
* XX - шестнадцатиричные данные
|
|
*/
|
|
|
|
const size_t ntsys_command_count = 0x26;
|
|
|
|
char* ntsys_asm_table[] = {
|
|
"push=00:T:D",
|
|
"pop=01:T",
|
|
"push.string=02:S",
|
|
|
|
"add=03:T",
|
|
"sub=04:T",
|
|
"mul=05:T",
|
|
"div=06:T",
|
|
|
|
"not=07:T",
|
|
"shr=08:T",
|
|
"shl=09:T",
|
|
"or=0A:T",
|
|
"and=0B:T",
|
|
"xor=0C:T",
|
|
|
|
"jmp=0D",
|
|
|
|
"bnez=0E:T",
|
|
"bez=0F:T",
|
|
"up=10:T",
|
|
"down=11:T",
|
|
"eq=12:T",
|
|
"neq=13:T",
|
|
"upne=14:T",
|
|
"downe=15:T",
|
|
|
|
"mwrt=16:T",
|
|
"mread=17:T",
|
|
|
|
"getsp=18",
|
|
"setsp=19",
|
|
|
|
"syscall=1A",
|
|
|
|
"swap=1B:T",
|
|
"dup=1C:T",
|
|
"copy=1C:T",
|
|
|
|
"set=1D",
|
|
"mov=1E",
|
|
|
|
"global=00:T:D0D",
|
|
"exit=000200000001021A",
|
|
"rcall=00:T:D1F",
|
|
|
|
"call=1F",
|
|
"ret=20",
|
|
|
|
"pass="
|
|
};
|
|
|
|
int ntsys_asm_from_string(size_t* mempos, char* str, FILE* fp, byte_t cycle, ntsys_labels_array_t labels, word_t* labels_pos, size_t* labels_count, dword_t* fsz) {
|
|
ntsys_asm_save_t __save = create_ntsys_asm_save(str);
|
|
ntsys_asm_cache_t __cache = create_ntsys_asm_cache(__save);
|
|
ntsys_argument_parser_t parser = create_ntsys_asm_parser(__cache, fp, str, ntsys_asm_table, ntsys_command_count, labels, labels_pos, labels_count, cycle, fsz);
|
|
return ntsys_run_asm_parser(parser);
|
|
}
|
|
|
|
void ntsys_compile_asm_stadion1(FILE* fp, size_t* lb_size) {
|
|
char* st = NULL;
|
|
while ((st = ntsys_get_str(st, fp)) != NULL) {
|
|
char* cp = st;
|
|
ntsys_asm_save_t __save = create_ntsys_asm_save(cp);
|
|
ntsys_asm_cache_t sv = create_ntsys_asm_cache(__save);
|
|
char* str = ntsys_get_arg(sv);
|
|
if (str[strlen(str) - 1] == ':') {
|
|
*lb_size += 1;
|
|
}
|
|
}
|
|
free(st);
|
|
}
|
|
|
|
int ntsys_compile_asm_stadion2(
|
|
FILE* fp,
|
|
FILE* tmp,
|
|
size_t lb_size,
|
|
size_t* mem_pos,
|
|
char** labels,
|
|
word_t* labels_pos,
|
|
size_t* labels_count,
|
|
dword_t* fsz,
|
|
byte_t num
|
|
) {
|
|
char* st = NULL;
|
|
while ((st = ntsys_get_str(st, fp)) != NULL) {
|
|
if (ntsys_asm_from_string(mem_pos, st, tmp, num, labels, labels_pos, labels_count, fsz) != EXIT_SUCCESS) {
|
|
free(st);
|
|
fclose(fp);
|
|
fclose(tmp);
|
|
size_t i = 0;
|
|
while (i < lb_size) {
|
|
if (labels[i] != NULL) free(labels[i]);
|
|
i ++;
|
|
}
|
|
free(labels);
|
|
free(labels_pos);
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|
|
free(st);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
#define ntsys_load_image_from_file(file, num) ( ntsys_compile_asm_stadion2( \
|
|
fp, (file), lb_size, &mem_pos, \
|
|
labels, labels_pos, &labels_count, &fsz, (num) \
|
|
) != EXIT_SUCCESS )
|
|
|
|
int ntsys_compile_asm(char* filename, char* asm_out) {
|
|
FILE* fp = fopen(filename, "r");
|
|
if (fp == NULL) {
|
|
ntsys_error("Cannot open assembler file!");
|
|
return EXIT_FAILURE;
|
|
}
|
|
size_t mem_pos = 0;
|
|
size_t lb_size = 0;
|
|
ntsys_compile_asm_stadion1(fp, &lb_size);
|
|
char** labels = malloc(sizeof(char*) * lb_size);
|
|
word_t* labels_pos = malloc(sizeof(word_t) * lb_size);
|
|
size_t u = 0;
|
|
while (u < lb_size) {
|
|
labels[u] = NULL;
|
|
u ++;
|
|
}
|
|
rewind(fp);
|
|
size_t labels_count = 0;
|
|
dword_t fsz = 0;
|
|
FILE* tmp = tmpfile();
|
|
if (tmp == NULL) {
|
|
ntsys_error("Cannot create or rewrite output file!");
|
|
fclose(fp);
|
|
return EXIT_FAILURE;
|
|
}
|
|
if (ntsys_load_image_from_file(tmp, 0) != EXIT_SUCCESS) return EXIT_FAILURE;
|
|
fclose(tmp);
|
|
rewind(fp);
|
|
FILE* fw = fopen(asm_out, "wb");
|
|
if (fw == NULL) {
|
|
ntsys_error("Cannot create or rewrite output file!");
|
|
fclose(fp);
|
|
return EXIT_FAILURE;
|
|
}
|
|
if (ntsys_load_image_from_file(fw, 1) != EXIT_SUCCESS) return EXIT_FAILURE;
|
|
fflush(fw);
|
|
fclose(fp);
|
|
size_t i = 0;
|
|
while (i < lb_size) {
|
|
if (labels[i] != NULL) free(labels[i]);
|
|
i ++;
|
|
}
|
|
free(labels);
|
|
free(labels_pos);
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
#endif /* NTSYS_ASSEMBLER_H___ */ |