stable 重构文件结构
抽象出Machine Code
This commit is contained in:
144
src/assembler/assembler.c
Normal file
144
src/assembler/assembler.c
Normal file
@@ -0,0 +1,144 @@
|
||||
|
||||
#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] == ' ') {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user