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() {
|
void dedup_id() {
|
||||||
char* latest = &id_table[id_lut[id_lut_size - 1]];
|
int last_id = id_lut_size - 1;
|
||||||
for (int i = 0; i < id_lut_size - 1; i++) {
|
char* latest = id_table + id_lut[last_id];
|
||||||
char* candidate = &id_table[id_lut[i]];
|
for (int i = 0; i < last_id; i++) {
|
||||||
|
char* candidate = id_table + id_lut[i];
|
||||||
if (streq(candidate, latest)) {
|
if (streq(candidate, latest)) {
|
||||||
rewind_id(i);
|
rewind_id(i);
|
||||||
return;
|
return;
|
||||||
@ -169,7 +170,7 @@ void dedup_id() {
|
|||||||
void parse_id_like(int ch) {
|
void parse_id_like(int ch) {
|
||||||
token_type = TOKEN_ID;
|
token_type = TOKEN_ID;
|
||||||
token_data = parse_id(ch);
|
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")) {
|
if (streq(id, "int")) {
|
||||||
token_type = TOKEN_INT;
|
token_type = TOKEN_INT;
|
||||||
} else if (streq(id, "if")) {
|
} else if (streq(id, "if")) {
|
||||||
@ -367,7 +368,7 @@ void next_token() {
|
|||||||
}
|
}
|
||||||
eprintf("token: %d\n", token_type);
|
eprintf("token: %d\n", token_type);
|
||||||
if (token_type == TOKEN_ID) {
|
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);
|
eprintf(" id: %s\n", name);
|
||||||
} else if (token_type == TOKEN_NUMBER) {
|
} else if (token_type == TOKEN_NUMBER) {
|
||||||
eprintf(" number: %d\n", token_data);
|
eprintf(" number: %d\n", token_data);
|
||||||
@ -432,6 +433,7 @@ int max_local_id = 2;
|
|||||||
const int MARKER_TEMP = 0;
|
const int MARKER_TEMP = 0;
|
||||||
const int MARKER_SCALAR = 1;
|
const int MARKER_SCALAR = 1;
|
||||||
const int MARKER_ARRAY = 2;
|
const int MARKER_ARRAY = 2;
|
||||||
|
const int MARKER_FUNCTION = 3;
|
||||||
|
|
||||||
int local_marker[4096];
|
int local_marker[4096];
|
||||||
int global_marker[4096];
|
int global_marker[4096];
|
||||||
@ -546,20 +548,28 @@ void load_address(int rd, int id) {
|
|||||||
|
|
||||||
void load(int rd, int id) {
|
void load(int rd, int id) {
|
||||||
load_address(rd, id);
|
load_address(rd, id);
|
||||||
const char* op = "ld";
|
int type = local_type_of(id);
|
||||||
if (local_type_of(id) == TYPE_CHAR && (id & INDIRECTION)) {
|
const char* op = "lw"; // int
|
||||||
|
if (type == TYPE_CHAR) {
|
||||||
op = "lb";
|
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) {
|
void store_t0(int id) {
|
||||||
load_address(1, id);
|
load_address(1, id);
|
||||||
const char* op = "sd";
|
int type = local_type_of(id);
|
||||||
if (local_type_of(id) == TYPE_CHAR && (id & INDIRECTION)) {
|
const char* op = "sw"; // int
|
||||||
|
if (type == TYPE_CHAR) {
|
||||||
op = "sb";
|
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) {
|
int materialize_t0(int type) {
|
||||||
@ -582,13 +592,16 @@ int lookup(int id) {
|
|||||||
}
|
}
|
||||||
return local;
|
return local;
|
||||||
}
|
}
|
||||||
const char* name = &id_table[id_lut[id]];
|
const char* name = id_table + id_lut[id];
|
||||||
if (global_marker[id]) {
|
if (global_marker[id]) {
|
||||||
printf(" la t0, %s # id: %d\n", name, id);
|
printf(" la t0, %s # id: %d\n", name, id);
|
||||||
int reg = materialize_t0(global_type[id] | TYPE_PTR_MASK);
|
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);
|
reg = indirection_of(reg);
|
||||||
}
|
}
|
||||||
|
if (global_marker[id] == MARKER_FUNCTION) {
|
||||||
|
reg = reg | INDIRECTION;
|
||||||
|
}
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
eprintf("unresolved identifier: %s\n", name);
|
eprintf("unresolved identifier: %s\n", name);
|
||||||
@ -669,17 +682,44 @@ void asm_pop_label() {
|
|||||||
|
|
||||||
int step_of(int type) {
|
int step_of(int type) {
|
||||||
if (type == TYPE_INT_PTR) {
|
if (type == TYPE_INT_PTR) {
|
||||||
return 8;
|
return 4;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void asm_slli_t0(int type) {
|
void asm_slli_t0(int type) {
|
||||||
if (type == TYPE_INT_PTR) {
|
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
|
// parser
|
||||||
int parse_expr();
|
int parse_expr();
|
||||||
|
|
||||||
@ -728,27 +768,7 @@ int parse_postfix_expr() {
|
|||||||
} else if (token_type == TOKEN_BRACKET_LEFT) {
|
} else if (token_type == TOKEN_BRACKET_LEFT) {
|
||||||
int rhs = parse_expr();
|
int rhs = parse_expr();
|
||||||
expect_token(TOKEN_BRACKET_RIGHT);
|
expect_token(TOKEN_BRACKET_RIGHT);
|
||||||
int type1 = local_type_of(lhs) & TYPE_PTR_MASK;
|
return indirection_of(asm_add(lhs, rhs));
|
||||||
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));
|
|
||||||
} else if (token_type == TOKEN_PAREN_LEFT) {
|
} else if (token_type == TOKEN_PAREN_LEFT) {
|
||||||
int arg = 0;
|
int arg = 0;
|
||||||
int args[8];
|
int args[8];
|
||||||
@ -852,7 +872,7 @@ int parse_add_expr() {
|
|||||||
next_token();
|
next_token();
|
||||||
if (token_type == TOKEN_ADD) {
|
if (token_type == TOKEN_ADD) {
|
||||||
int rhs = parse_mul_expr();
|
int rhs = parse_mul_expr();
|
||||||
lhs = asm_rr("add", lhs, rhs);
|
lhs = asm_add(lhs, rhs);
|
||||||
} else if (token_type == TOKEN_MINUS) {
|
} else if (token_type == TOKEN_MINUS) {
|
||||||
int rhs = parse_mul_expr();
|
int rhs = parse_mul_expr();
|
||||||
lhs = asm_rr("sub", lhs, rhs);
|
lhs = asm_rr("sub", lhs, rhs);
|
||||||
@ -1027,6 +1047,10 @@ void parse_local_variable(int type) {
|
|||||||
int id = token_data;
|
int id = token_data;
|
||||||
next_token();
|
next_token();
|
||||||
if (token_type == TOKEN_BRACKET_LEFT) {
|
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);
|
expect_token(TOKEN_NUMBER);
|
||||||
int size = token_data;
|
int size = token_data;
|
||||||
expect_token(TOKEN_BRACKET_RIGHT);
|
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) {
|
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(".data\n");
|
||||||
printf(".globl %s\n", name);
|
printf(".globl %s\n", name);
|
||||||
printf(".align 5\n");
|
printf(".align 5\n");
|
||||||
@ -1249,10 +1277,14 @@ void parse_global_variable(int id, const char* name, int type) {
|
|||||||
expect_token(TOKEN_NUMBER);
|
expect_token(TOKEN_NUMBER);
|
||||||
int size = token_data;
|
int size = token_data;
|
||||||
expect_token(TOKEN_BRACKET_RIGHT);
|
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);
|
declare_global(id, MARKER_ARRAY, type);
|
||||||
} else {
|
} else {
|
||||||
printf(" .zero %d\n", 8);
|
printf(" .zero %d\n", 4);
|
||||||
unget_token();
|
unget_token();
|
||||||
}
|
}
|
||||||
expect_token(TOKEN_SEMICOLON);
|
expect_token(TOKEN_SEMICOLON);
|
||||||
@ -1261,12 +1293,13 @@ void parse_global_variable(int id, const char* name, int type) {
|
|||||||
void parse_decl(int type) {
|
void parse_decl(int type) {
|
||||||
expect_token(TOKEN_ID);
|
expect_token(TOKEN_ID);
|
||||||
int id = token_data;
|
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();
|
next_token();
|
||||||
if (token_type == TOKEN_PAREN_LEFT) {
|
if (token_type == TOKEN_PAREN_LEFT) {
|
||||||
|
declare_global(id, MARKER_FUNCTION, type);
|
||||||
parse_function(name);
|
parse_function(name);
|
||||||
} else {
|
} else {
|
||||||
|
declare_global(id, MARKER_SCALAR, type);
|
||||||
parse_global_variable(id, name, type);
|
parse_global_variable(id, name, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user