Files
scc/src/assembler/assembler.c
ZZY b57f21556a stable 重构文件结构
抽象出Machine Code
2025-04-01 23:27:25 +08:00

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] == ' ') {
}
}