mirror of
https://github.com/iritmaximus/ttk91-compiler.git
synced 2026-10-12 19:13:40 +03:00
implemented many unit tests
This commit is contained in:
+22
-7
@@ -23,6 +23,23 @@ struct label * label_create_const(char* name) { return label_create(LABEL_
|
||||
struct label * label_create_const_sys(char* name) { return label_create(LABEL_CONST, name, 0); } // FIXME value
|
||||
struct label * label_create_tag(char* name) { return label_create(LABEL_TAG, name, 0); } // FIXME also this
|
||||
|
||||
int label_to_string(char* buffer, size_t size, struct label *l) {
|
||||
if (size < 2) {
|
||||
printf("ERROR: Buffer size too small (label)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!l->name)
|
||||
{
|
||||
printf("ERROR: Label name doesn't exist.\n");
|
||||
snprintf(buffer, size, "???");
|
||||
return VARIABLE_NULL;
|
||||
}
|
||||
|
||||
snprintf(buffer, size, "%s", l->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int label_print_intel_asm(struct label *l)
|
||||
{
|
||||
return label_print(l);
|
||||
@@ -30,18 +47,16 @@ int label_print_intel_asm(struct label *l)
|
||||
|
||||
int label_print(struct label *l)
|
||||
{
|
||||
if (!l->name)
|
||||
{
|
||||
printf("ERROR: Label name doesn't exist.\n");
|
||||
return VARIABLE_NULL;
|
||||
}
|
||||
size_t size = 50;
|
||||
char buffer[size];
|
||||
|
||||
printf("%s", l->name);
|
||||
label_to_string(buffer, size, l);
|
||||
printf("%s", buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void label_free(struct label *l)
|
||||
{
|
||||
if (l->name) free(l->name);
|
||||
// if (l->name) free(l->name);
|
||||
free(l);
|
||||
}
|
||||
|
||||
+101
-50
@@ -1,6 +1,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include "error.h"
|
||||
#include "ttk_register.h"
|
||||
|
||||
@@ -37,8 +39,8 @@ struct ttk_register * ttk_register_create_stack_register(char* name)
|
||||
|
||||
int parse_register_num(char* name, ttk_register_t kind)
|
||||
{
|
||||
if (!name) {
|
||||
printf("Name null while parsing register name.\n");
|
||||
if (!name || strcmp(name, "") == 0) {
|
||||
printf("ERROR: Name null or empty while parsing register name.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -49,87 +51,136 @@ int parse_register_num(char* name, ttk_register_t kind)
|
||||
case TTK_REGISTER:
|
||||
char num = name[1]; // registers have the format RX, 'R' + X 0-7
|
||||
value = num - '0';
|
||||
break;
|
||||
case STACK_TTK_REGISTER:
|
||||
if (strcasecmp("sp", name) == 0)
|
||||
value = 6;
|
||||
if (0 <= value && value <= 8)
|
||||
break;
|
||||
else
|
||||
assert(false && "Incorrect register name value");
|
||||
|
||||
if (strcasecmp("fp", name) == 0)
|
||||
case STACK_TTK_REGISTER:
|
||||
value = -1;
|
||||
|
||||
if (strcasecmp("sp", name) == 0) {
|
||||
value = 6;
|
||||
break;
|
||||
}
|
||||
|
||||
else if (strcasecmp("fp", name) == 0) {
|
||||
value = 7;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
else
|
||||
assert(false && "Stack register not 6 or 7");
|
||||
|
||||
default:
|
||||
free(name);
|
||||
printf("Register type not matched while parsing register name.\n");
|
||||
return -1;
|
||||
assert(false && "Register kind not matched while parsing register name.");
|
||||
break;
|
||||
}
|
||||
|
||||
free(name);
|
||||
return value;
|
||||
}
|
||||
|
||||
int ttk_register_print_intel_asm(struct ttk_register *ttk_reg)
|
||||
{
|
||||
// EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI
|
||||
if (!ttk_reg || !ttk_reg->id)
|
||||
int ttk_register_to_string(char* buffer, size_t size, struct ttk_register *ttk_reg) {
|
||||
if (size < 3) {
|
||||
printf("ERROR: Buffer size too small (ttk_reg_to_string)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ttk_reg)
|
||||
{
|
||||
printf("ttk_register missing while trying to print it.\n");
|
||||
printf("ERROR: ttk_register missing while trying to print it.\n");
|
||||
return VARIABLE_NULL;
|
||||
}
|
||||
|
||||
switch (ttk_reg->id)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
printf("eax");
|
||||
break;
|
||||
case 2:
|
||||
printf("ebx");
|
||||
break;
|
||||
case 3:
|
||||
printf("ecx");
|
||||
break;
|
||||
case 4:
|
||||
printf("edx");
|
||||
break;
|
||||
case 5:
|
||||
printf("esp");
|
||||
snprintf(buffer, size, "R%d", ttk_reg->id);
|
||||
break;
|
||||
case 6:
|
||||
printf("ebp");
|
||||
snprintf(buffer, size, "SP");
|
||||
break;
|
||||
case 7:
|
||||
printf("esi");
|
||||
break;
|
||||
case 0:
|
||||
printf("edi"); // TODO: this is possibly not correct
|
||||
snprintf(buffer, size, "FP");
|
||||
break;
|
||||
default:
|
||||
printf("ERROR: No matching register\n");
|
||||
return SWITCH_NOT_MATCHED;
|
||||
assert(false && "No register id matched\n");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ttk_register_to_intel_asm_string(char* buffer, size_t size, struct ttk_register *ttk_reg)
|
||||
{
|
||||
if (size < 5) {
|
||||
printf("ERROR: Buffer size too small (ttk_reg_to_string)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ttk_reg)
|
||||
{
|
||||
printf("ERROR: ttk_register missing while trying to print it.\n");
|
||||
return VARIABLE_NULL;
|
||||
}
|
||||
|
||||
// TODO: this is possibly not correct
|
||||
// EAX, EBX, ECX, EDX, ESP, EBP, ESI, EDI
|
||||
switch (ttk_reg->id)
|
||||
{
|
||||
case 1:
|
||||
snprintf(buffer, size, "eax");
|
||||
break;
|
||||
case 2:
|
||||
snprintf(buffer, size, "ebx");
|
||||
break;
|
||||
case 3:
|
||||
snprintf(buffer, size, "ecx");
|
||||
break;
|
||||
case 4:
|
||||
snprintf(buffer, size, "edx");
|
||||
break;
|
||||
case 5:
|
||||
snprintf(buffer, size, "esp");
|
||||
break;
|
||||
case 6:
|
||||
snprintf(buffer, size, "ebp");
|
||||
break;
|
||||
case 7:
|
||||
snprintf(buffer, size, "esi");
|
||||
break;
|
||||
case 0:
|
||||
snprintf(buffer, size, "edi");
|
||||
break;
|
||||
default:
|
||||
assert(false && "No matching register");
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ttk_register_print_intel_asm(struct ttk_register *ttk_reg)
|
||||
{
|
||||
size_t size = 5;
|
||||
char buffer[size];
|
||||
|
||||
ttk_register_to_intel_asm_string(buffer, size, ttk_reg);
|
||||
printf("%s", buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ttk_register_print(struct ttk_register *ttk_reg)
|
||||
{
|
||||
if (!ttk_reg || !ttk_reg->id)
|
||||
{
|
||||
printf("ttk_register missing while trying to print it.\n");
|
||||
return VARIABLE_NULL;
|
||||
}
|
||||
switch (ttk_reg->id)
|
||||
{
|
||||
case 6:
|
||||
printf("SP");
|
||||
return 0;
|
||||
case 7:
|
||||
printf("FP");
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
size_t size = 3;
|
||||
char buffer[size];
|
||||
|
||||
printf("R%d", ttk_reg->id);
|
||||
ttk_register_to_string(buffer, size, ttk_reg);
|
||||
printf("%s", buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user