145 lines
2.9 KiB
C
145 lines
2.9 KiB
C
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
enum asm_symbol_type{
|
|
DATA_BYTE,
|
|
DATA_WORD,
|
|
DATA_HALFWORD,
|
|
DATA_DOUBLEWORD,
|
|
DATA_STRING,
|
|
DATA_SYMBLE,
|
|
TEXT_LABEL,
|
|
UNKNOWN,
|
|
};
|
|
|
|
struct asm_symbol_table {
|
|
const char* name;
|
|
enum asm_symbol_type type;
|
|
union {
|
|
long long data_doubleword;
|
|
long data_word;
|
|
short data_halfword;
|
|
char data_byte;
|
|
char* data_string;
|
|
} data;
|
|
};
|
|
|
|
static const char comments[] = {
|
|
'#',
|
|
};
|
|
|
|
static inline int is_blank(char ch) {
|
|
return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\v' || ch == '\f' || ch == '\r';
|
|
}
|
|
|
|
void parse_line_without_blank(const char* in, const char** out_start, const char** out_end) {
|
|
while (*in == '\0' || is_blank(*in)) {
|
|
in ++;
|
|
}
|
|
*out_start = in;
|
|
while (*in != '\0') {
|
|
if (*in == '\r' || *in == '\n') {
|
|
break;
|
|
}
|
|
for (int i = 0; i < sizeof(comments); i ++) {
|
|
if (*in == comments[i]) {
|
|
break;
|
|
}
|
|
}
|
|
in ++;
|
|
}
|
|
|
|
if (*out_end == *out_start) {
|
|
goto END;
|
|
}
|
|
|
|
while (is_blank(*in)) {
|
|
in --;
|
|
}
|
|
|
|
END:
|
|
*out_end = in;
|
|
return;
|
|
}
|
|
|
|
void parse_data_symbol(const char* start, const char* end, struct asm_symbol_table* table) {
|
|
table->name = start;
|
|
while(start < end) {
|
|
if (*start == ':') {
|
|
|
|
}
|
|
}
|
|
table->type = UNKNOWN;
|
|
}
|
|
|
|
#define TMP_BUFF_SIZE 1024
|
|
|
|
enum parse_state {
|
|
IN_DATA,
|
|
IN_TEXT,
|
|
IN_UNKNOWN,
|
|
};
|
|
void get_symbol_table(FILE* in) {
|
|
enum parse_state state = IN_UNKNOWN;
|
|
fseek(in, 0, SEEK_SET);
|
|
char buf[TMP_BUFF_SIZE];
|
|
|
|
int current_line = 0;
|
|
while (1) {
|
|
current_line ++;
|
|
char *start = fgets(buf, sizeof(buf), in);
|
|
if (start == NULL) {
|
|
return;
|
|
}
|
|
char *end;
|
|
parse_line_without_blank(buf, &start, &end);
|
|
|
|
if (start == end) {
|
|
continue;
|
|
}
|
|
|
|
if (start[0] == '.') {
|
|
// .data .text and so on
|
|
if (strcmp(start, ".data") == 0) {
|
|
state = IN_DATA;
|
|
} else if (strcmp(start, ".text") == 0) {
|
|
state = IN_TEXT;
|
|
} else {
|
|
printf("unknown directive at line %d\n", current_line);
|
|
state = IN_UNKNOWN;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
switch (state) {
|
|
case IN_DATA:
|
|
parse_data_symbol(start, end);
|
|
break;
|
|
case IN_TEXT:
|
|
break;
|
|
case IN_UNKNOWN:
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void assembler(FILE* in, FILE* out, char *start_symble) {
|
|
char buf[TMP_BUFF_SIZE];
|
|
|
|
char *res = fgets(buf, sizeof(buf), in);
|
|
if (res == NULL) {
|
|
return;
|
|
}
|
|
|
|
if (res[0] == '.') {
|
|
// maybe .data .text and so on
|
|
} else if (res[0] == ' ') {
|
|
|
|
}
|
|
|
|
|
|
}
|