more void check
This commit is contained in:
parent
fb54211c71
commit
05f6b1906f
141
boot.c
141
boot.c
@ -524,6 +524,10 @@ void asm_addi(const char* rd, const char* rs, int imm) {
|
||||
}
|
||||
|
||||
void load_address(int rd, int id) {
|
||||
if (id == -1) {
|
||||
eprintf("void cannot be arithmetically operated\n");
|
||||
exit(1);
|
||||
}
|
||||
int offset = -id * 8 - 8;
|
||||
if (indirection[id]) {
|
||||
if (check_itype_immediate(offset)) {
|
||||
@ -573,7 +577,7 @@ int materialize_t0(int type) {
|
||||
return reg;
|
||||
}
|
||||
|
||||
int indirection_of(int reg) {
|
||||
int dereference(int reg) {
|
||||
local_type[reg] = local_type[reg] & ~TYPE_PTR_MASK;
|
||||
indirection[reg] = 1;
|
||||
return reg;
|
||||
@ -593,7 +597,7 @@ int lookup(int 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_SCALAR) {
|
||||
reg = indirection_of(reg);
|
||||
reg = dereference(reg);
|
||||
}
|
||||
if (global_marker[id] == MARKER_FUNCTION) {
|
||||
indirection[reg] = 1;
|
||||
@ -703,6 +707,10 @@ int asm_add(int lhs, int rhs) {
|
||||
idx = lhs;
|
||||
}
|
||||
int ptr_type = local_type[ptr];
|
||||
if (ptr_type == TYPE_VOID_PTR) {
|
||||
eprintf("void pointer cannot be arithmetically operated\n");
|
||||
exit(1);
|
||||
}
|
||||
load(0, idx);
|
||||
load(1, ptr);
|
||||
asm_shift_t0("slli", ptr_type);
|
||||
@ -717,14 +725,23 @@ int asm_add(int lhs, int rhs) {
|
||||
}
|
||||
|
||||
int asm_sub(int lhs, int rhs) {
|
||||
int type1 = local_type[lhs] & TYPE_PTR_MASK;
|
||||
int type2 = local_type[rhs] & TYPE_PTR_MASK;
|
||||
int lhs_type = local_type[lhs];
|
||||
int rhs_type = local_type[rhs];
|
||||
int type1 = lhs_type & TYPE_PTR_MASK;
|
||||
int type2 = rhs_type & TYPE_PTR_MASK;
|
||||
if (type1 && type2) {
|
||||
if (lhs_type != rhs_type) {
|
||||
eprintf("pointer type mismatch\n");
|
||||
exit(1);
|
||||
}
|
||||
if (lhs_type == TYPE_VOID_PTR) {
|
||||
eprintf("void pointer cannot be arithmetically operated\n");
|
||||
exit(1);
|
||||
}
|
||||
load(0, lhs);
|
||||
load(1, rhs);
|
||||
int ptr_type = local_type[lhs];
|
||||
printf(" sub t0, t0, t1\n");
|
||||
asm_shift_t0("srli", ptr_type);
|
||||
asm_shift_t0("srli", lhs_type);
|
||||
return materialize_t0(TYPE_INT);
|
||||
}
|
||||
if (type1) {
|
||||
@ -763,6 +780,44 @@ int parse_primary_expr() {
|
||||
}
|
||||
}
|
||||
|
||||
int parse_function_call(int func) {
|
||||
int arg = 0;
|
||||
int args[8];
|
||||
while (1) {
|
||||
next_token();
|
||||
if (token_type == TOKEN_PAREN_RIGHT) {
|
||||
break;
|
||||
}
|
||||
unget_token();
|
||||
if (arg >= 8) {
|
||||
eprintf("too many arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
args[arg++] = parse_expr();
|
||||
next_token();
|
||||
if (token_type == TOKEN_COMMA) {
|
||||
// continue;
|
||||
} else if (token_type == TOKEN_PAREN_RIGHT) {
|
||||
break;
|
||||
} else {
|
||||
eprintf("expecting ',' or ')'\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < arg; ++i) {
|
||||
load(0, args[i]);
|
||||
printf(" mv a%d, t0\n", i);
|
||||
}
|
||||
load_address(0, func);
|
||||
printf(" jalr t0\n");
|
||||
int type = local_type[func];
|
||||
if (type != TYPE_VOID) {
|
||||
printf(" mv t0, a0\n");
|
||||
return materialize_t0(type);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int parse_postfix_expr() {
|
||||
int lhs = parse_primary_expr();
|
||||
while (1) {
|
||||
@ -786,39 +841,9 @@ int parse_postfix_expr() {
|
||||
} else if (token_type == TOKEN_BRACKET_LEFT) {
|
||||
int rhs = parse_expr();
|
||||
expect_token(TOKEN_BRACKET_RIGHT);
|
||||
lhs = indirection_of(asm_add(lhs, rhs));
|
||||
lhs = dereference(asm_add(lhs, rhs));
|
||||
} else if (token_type == TOKEN_PAREN_LEFT) {
|
||||
int arg = 0;
|
||||
int args[8];
|
||||
while (1) {
|
||||
next_token();
|
||||
if (token_type == TOKEN_PAREN_RIGHT) {
|
||||
break;
|
||||
}
|
||||
unget_token();
|
||||
if (arg >= 8) {
|
||||
eprintf("too many arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
args[arg++] = parse_expr();
|
||||
next_token();
|
||||
if (token_type == TOKEN_COMMA) {
|
||||
// continue;
|
||||
} else if (token_type == TOKEN_PAREN_RIGHT) {
|
||||
break;
|
||||
} else {
|
||||
eprintf("expecting ',' or ')'\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < arg; ++i) {
|
||||
load(0, args[i]);
|
||||
printf(" mv a%d, t0\n", i);
|
||||
}
|
||||
load_address(0, lhs);
|
||||
printf(" jalr t0\n");
|
||||
printf(" mv t0, a0\n");
|
||||
lhs = materialize_t0(local_type[lhs]);
|
||||
lhs = parse_function_call(lhs);
|
||||
} else {
|
||||
unget_token();
|
||||
break;
|
||||
@ -829,14 +854,28 @@ int parse_postfix_expr() {
|
||||
|
||||
int parse_prefix_expr() {
|
||||
next_token();
|
||||
if (token_type == TOKEN_AND) {
|
||||
if (token_type == TOKEN_AND) {
|
||||
int reg = parse_postfix_expr();
|
||||
int type = local_type[reg];
|
||||
if (type & TYPE_PTR_MASK) {
|
||||
eprintf("cannot take address of a pointer\n");
|
||||
exit(1);
|
||||
}
|
||||
load_address(0, reg);
|
||||
return materialize_t0(local_type[reg] | TYPE_PTR_MASK);
|
||||
return materialize_t0(type | TYPE_PTR_MASK);
|
||||
} else if (token_type == TOKEN_STAR) {
|
||||
int reg = parse_postfix_expr();
|
||||
int type = local_type[reg];
|
||||
if (!(type & TYPE_PTR_MASK)) {
|
||||
eprintf("cannot dereference a non-pointer\n");
|
||||
exit(1);
|
||||
}
|
||||
if (type == TYPE_VOID_PTR) {
|
||||
eprintf("cannot dereference void pointer\n");
|
||||
exit(1);
|
||||
}
|
||||
load(0, reg);
|
||||
return indirection_of(materialize_t0(local_type[reg]));
|
||||
return dereference(materialize_t0(type));
|
||||
} else if (token_type == TOKEN_MINUS) {
|
||||
int reg = parse_postfix_expr();
|
||||
return asm_r("neg", reg);
|
||||
@ -1314,16 +1353,16 @@ void parse_function(const char* name) {
|
||||
parse_stmt();
|
||||
}
|
||||
asm_j(epilog_label);
|
||||
int shift = max_local_id * 8;
|
||||
if (shift % 16 != 0) {
|
||||
shift = shift + 8;
|
||||
int frame_size = max_local_id * 8;
|
||||
if (frame_size % 16 != 0) {
|
||||
frame_size = frame_size + 8;
|
||||
}
|
||||
// prolog
|
||||
asm_label(prolog_label);
|
||||
asm_addi("sp", "sp", -shift);
|
||||
asm_sd("ra", shift - 8, "sp");
|
||||
asm_sd("fp", shift - 16, "sp");
|
||||
asm_addi("fp", "sp", shift);
|
||||
asm_addi("sp", "sp", -frame_size);
|
||||
asm_sd("ra", frame_size - 8, "sp");
|
||||
asm_sd("fp", frame_size - 16, "sp");
|
||||
asm_addi("fp", "sp", frame_size);
|
||||
for (int i = 0; i < arg; ++i) {
|
||||
printf(" mv t0, a%d\n", i);
|
||||
store_t0(args[i]);
|
||||
@ -1331,9 +1370,9 @@ void parse_function(const char* name) {
|
||||
asm_j(label);
|
||||
// epilog
|
||||
asm_label(epilog_label);
|
||||
asm_ld("fp", shift - 16, "sp");
|
||||
asm_ld("ra", shift - 8, "sp");
|
||||
asm_addi("sp", "sp", shift);
|
||||
asm_ld("fp", frame_size - 16, "sp");
|
||||
asm_ld("ra", frame_size - 8, "sp");
|
||||
asm_addi("sp", "sp", frame_size);
|
||||
printf(" ret\n");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user