pointer arithmetic
This commit is contained in:
parent
f197671868
commit
cf45cf1e2f
115
boot.c
115
boot.c
@ -156,9 +156,10 @@ void rewind_id(int new_data) {
|
||||
}
|
||||
|
||||
void dedup_id() {
|
||||
char* latest = &id_table[id_lut[id_lut_size - 1]];
|
||||
for (int i = 0; i < id_lut_size - 1; i++) {
|
||||
char* candidate = &id_table[id_lut[i]];
|
||||
int last_id = id_lut_size - 1;
|
||||
char* latest = id_table + id_lut[last_id];
|
||||
for (int i = 0; i < last_id; i++) {
|
||||
char* candidate = id_table + id_lut[i];
|
||||
if (streq(candidate, latest)) {
|
||||
rewind_id(i);
|
||||
return;
|
||||
@ -169,7 +170,7 @@ void dedup_id() {
|
||||
void parse_id_like(int ch) {
|
||||
token_type = TOKEN_ID;
|
||||
token_data = parse_id(ch);
|
||||
char* id = &id_table[id_lut[token_data]];
|
||||
char* id = id_table + id_lut[token_data];
|
||||
if (streq(id, "int")) {
|
||||
token_type = TOKEN_INT;
|
||||
} else if (streq(id, "if")) {
|
||||
@ -367,7 +368,7 @@ void next_token() {
|
||||
}
|
||||
eprintf("token: %d\n", token_type);
|
||||
if (token_type == TOKEN_ID) {
|
||||
const char* name = &id_table[id_lut[token_data]];
|
||||
const char* name = id_table + id_lut[token_data];
|
||||
eprintf(" id: %s\n", name);
|
||||
} else if (token_type == TOKEN_NUMBER) {
|
||||
eprintf(" number: %d\n", token_data);
|
||||
@ -432,6 +433,7 @@ int max_local_id = 2;
|
||||
const int MARKER_TEMP = 0;
|
||||
const int MARKER_SCALAR = 1;
|
||||
const int MARKER_ARRAY = 2;
|
||||
const int MARKER_FUNCTION = 3;
|
||||
|
||||
int local_marker[4096];
|
||||
int global_marker[4096];
|
||||
@ -546,20 +548,28 @@ void load_address(int rd, int id) {
|
||||
|
||||
void load(int rd, int id) {
|
||||
load_address(rd, id);
|
||||
const char* op = "ld";
|
||||
if (local_type_of(id) == TYPE_CHAR && (id & INDIRECTION)) {
|
||||
int type = local_type_of(id);
|
||||
const char* op = "lw"; // int
|
||||
if (type == TYPE_CHAR) {
|
||||
op = "lb";
|
||||
}
|
||||
printf(" %s t%d, 0(t%d) # id: type %d\n", op, rd, rd, local_type_of(id));
|
||||
if (type & TYPE_PTR_MASK) {
|
||||
op = "ld";
|
||||
}
|
||||
printf(" %s t%d, 0(t%d) # id: type %d\n", op, rd, rd, type);
|
||||
}
|
||||
|
||||
void store_t0(int id) {
|
||||
load_address(1, id);
|
||||
const char* op = "sd";
|
||||
if (local_type_of(id) == TYPE_CHAR && (id & INDIRECTION)) {
|
||||
int type = local_type_of(id);
|
||||
const char* op = "sw"; // int
|
||||
if (type == TYPE_CHAR) {
|
||||
op = "sb";
|
||||
}
|
||||
printf(" %s t0, 0(t1) # id: type %d\n", op, local_type_of(id));
|
||||
if (type & TYPE_PTR_MASK) {
|
||||
op = "sd";
|
||||
}
|
||||
printf(" %s t0, 0(t1) # id: type %d\n", op, type);
|
||||
}
|
||||
|
||||
int materialize_t0(int type) {
|
||||
@ -582,13 +592,16 @@ int lookup(int id) {
|
||||
}
|
||||
return local;
|
||||
}
|
||||
const char* name = &id_table[id_lut[id]];
|
||||
const char* name = id_table + id_lut[id];
|
||||
if (global_marker[id]) {
|
||||
printf(" la t0, %s # id: %d\n", name, id);
|
||||
int reg = materialize_t0(global_type[id] | TYPE_PTR_MASK);
|
||||
if (global_marker[id] != MARKER_ARRAY) {
|
||||
if (global_marker[id] == MARKER_SCALAR) {
|
||||
reg = indirection_of(reg);
|
||||
}
|
||||
if (global_marker[id] == MARKER_FUNCTION) {
|
||||
reg = reg | INDIRECTION;
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
eprintf("unresolved identifier: %s\n", name);
|
||||
@ -669,17 +682,44 @@ void asm_pop_label() {
|
||||
|
||||
int step_of(int type) {
|
||||
if (type == TYPE_INT_PTR) {
|
||||
return 8;
|
||||
return 4;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void asm_slli_t0(int type) {
|
||||
if (type == TYPE_INT_PTR) {
|
||||
printf(" slli t0, t0, 3\n");
|
||||
printf(" slli t0, t0, 2\n");
|
||||
}
|
||||
}
|
||||
|
||||
int asm_add(int lhs, int rhs) {
|
||||
int type1 = local_type_of(lhs) & TYPE_PTR_MASK;
|
||||
int type2 = local_type_of(rhs) & TYPE_PTR_MASK;
|
||||
if (type1 != type2) {
|
||||
int ptr;
|
||||
int idx;
|
||||
if (type1) {
|
||||
ptr = lhs;
|
||||
idx = rhs;
|
||||
} else {
|
||||
ptr = rhs;
|
||||
idx = lhs;
|
||||
}
|
||||
int ptr_type = local_type_of(ptr);
|
||||
load(0, idx);
|
||||
load(1, ptr);
|
||||
asm_slli_t0(ptr_type);
|
||||
printf(" add t0, t0, t1\n");
|
||||
return materialize_t0(ptr_type);
|
||||
}
|
||||
if (type1 && type2) {
|
||||
eprintf("operands cannot be both pointers\n");
|
||||
exit(1);
|
||||
}
|
||||
return asm_rr("add", lhs, rhs);
|
||||
}
|
||||
|
||||
// parser
|
||||
int parse_expr();
|
||||
|
||||
@ -728,27 +768,7 @@ int parse_postfix_expr() {
|
||||
} else if (token_type == TOKEN_BRACKET_LEFT) {
|
||||
int rhs = parse_expr();
|
||||
expect_token(TOKEN_BRACKET_RIGHT);
|
||||
int type1 = local_type_of(lhs) & TYPE_PTR_MASK;
|
||||
int type2 = local_type_of(rhs) & TYPE_PTR_MASK;
|
||||
if (type1 == type2) {
|
||||
eprintf("there should be exact one pointer and one integer in array access\n");
|
||||
exit(1);
|
||||
}
|
||||
int ptr;
|
||||
int idx;
|
||||
if (type1) {
|
||||
ptr = lhs;
|
||||
idx = rhs;
|
||||
} else {
|
||||
ptr = rhs;
|
||||
idx = lhs;
|
||||
}
|
||||
int ptr_type = local_type_of(ptr);
|
||||
load(0, idx);
|
||||
load(1, ptr);
|
||||
asm_slli_t0(ptr_type);
|
||||
printf(" add t0, t0, t1\n");
|
||||
return indirection_of(materialize_t0(ptr_type));
|
||||
return indirection_of(asm_add(lhs, rhs));
|
||||
} else if (token_type == TOKEN_PAREN_LEFT) {
|
||||
int arg = 0;
|
||||
int args[8];
|
||||
@ -852,7 +872,7 @@ int parse_add_expr() {
|
||||
next_token();
|
||||
if (token_type == TOKEN_ADD) {
|
||||
int rhs = parse_mul_expr();
|
||||
lhs = asm_rr("add", lhs, rhs);
|
||||
lhs = asm_add(lhs, rhs);
|
||||
} else if (token_type == TOKEN_MINUS) {
|
||||
int rhs = parse_mul_expr();
|
||||
lhs = asm_rr("sub", lhs, rhs);
|
||||
@ -1027,6 +1047,10 @@ void parse_local_variable(int type) {
|
||||
int id = token_data;
|
||||
next_token();
|
||||
if (token_type == TOKEN_BRACKET_LEFT) {
|
||||
if (type & TYPE_PTR_MASK) {
|
||||
eprintf("local variable of array of pointers is not supported\n");
|
||||
exit(1);
|
||||
}
|
||||
expect_token(TOKEN_NUMBER);
|
||||
int size = token_data;
|
||||
expect_token(TOKEN_BRACKET_RIGHT);
|
||||
@ -1238,6 +1262,10 @@ void parse_function(const char* name) {
|
||||
}
|
||||
|
||||
void parse_global_variable(int id, const char* name, int type) {
|
||||
if (type & TYPE_PTR_MASK) {
|
||||
eprintf("global variable of pointer is not supported\n");
|
||||
exit(1);
|
||||
}
|
||||
printf(".data\n");
|
||||
printf(".globl %s\n", name);
|
||||
printf(".align 5\n");
|
||||
@ -1249,10 +1277,14 @@ void parse_global_variable(int id, const char* name, int type) {
|
||||
expect_token(TOKEN_NUMBER);
|
||||
int size = token_data;
|
||||
expect_token(TOKEN_BRACKET_RIGHT);
|
||||
printf(" .zero %d\n", 8 * size);
|
||||
int array_size = 4 * size;
|
||||
if (type == TYPE_CHAR) {
|
||||
array_size = size;
|
||||
}
|
||||
printf(" .zero %d\n", array_size);
|
||||
declare_global(id, MARKER_ARRAY, type);
|
||||
} else {
|
||||
printf(" .zero %d\n", 8);
|
||||
printf(" .zero %d\n", 4);
|
||||
unget_token();
|
||||
}
|
||||
expect_token(TOKEN_SEMICOLON);
|
||||
@ -1261,12 +1293,13 @@ void parse_global_variable(int id, const char* name, int type) {
|
||||
void parse_decl(int type) {
|
||||
expect_token(TOKEN_ID);
|
||||
int id = token_data;
|
||||
declare_global(id, MARKER_SCALAR, type);
|
||||
char* name = &id_table[id_lut[id]];
|
||||
char* name = id_table + id_lut[id];
|
||||
next_token();
|
||||
if (token_type == TOKEN_PAREN_LEFT) {
|
||||
declare_global(id, MARKER_FUNCTION, type);
|
||||
parse_function(name);
|
||||
} else {
|
||||
declare_global(id, MARKER_SCALAR, type);
|
||||
parse_global_variable(id, name, type);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user