primary function call
This commit is contained in:
parent
653d42ccf3
commit
b8108acb2e
2 changed files with 48 additions and 37 deletions
76
boot.c
76
boot.c
|
@ -80,7 +80,6 @@ const int TYPE_INT_PTR = 17;
|
|||
const int TYPE_CHAR_PTR = 18;
|
||||
|
||||
const int TYPE_PTR_MASK = 16;
|
||||
const int TYPE_FUNC_MASK = 32;
|
||||
const int TYPE_TOKEN_MASK = 128;
|
||||
|
||||
int parse_int(int ch) {
|
||||
|
@ -436,6 +435,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];
|
||||
|
@ -552,7 +552,7 @@ void load(int rd, int id) {
|
|||
const char* op = "lw"; // int
|
||||
if (type == TYPE_CHAR) {
|
||||
op = "lb";
|
||||
} else if (type & TYPE_PTR_MASK || type & TYPE_FUNC_MASK) {
|
||||
} else if (type & TYPE_PTR_MASK) {
|
||||
op = "ld";
|
||||
}
|
||||
printf(" %s t%d, 0(t%d) # id: type %d\n", op, rd, rd, type);
|
||||
|
@ -564,7 +564,7 @@ void store_t0(int id) {
|
|||
const char* op = "sw"; // int
|
||||
if (type == TYPE_CHAR) {
|
||||
op = "sb";
|
||||
} else if (type & TYPE_PTR_MASK || type & TYPE_FUNC_MASK) {
|
||||
} else if (type & TYPE_PTR_MASK) {
|
||||
op = "sd";
|
||||
}
|
||||
printf(" %s t0, 0(t1) # id: type %d\n", op, type);
|
||||
|
@ -593,6 +593,10 @@ int lookup(int id) {
|
|||
}
|
||||
const char* name = id_table + id_lut[id];
|
||||
if (global_marker[id]) {
|
||||
if (global_marker[id] == MARKER_FUNCTION) {
|
||||
eprintf("function name must not appear outside function call: %s\n", name);
|
||||
exit(1);
|
||||
}
|
||||
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) {
|
||||
|
@ -631,7 +635,7 @@ int asm_r(const char* op, int rs1) {
|
|||
}
|
||||
|
||||
int asm_r_arith(const char* op, int rs1) {
|
||||
if (local_type[rs1] & TYPE_PTR_MASK || local_type[rs1] & TYPE_FUNC_MASK) {
|
||||
if (local_type[rs1] & TYPE_PTR_MASK) {
|
||||
eprintf("pointer cannot be arithmetically operated by %s\n", op);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -654,8 +658,7 @@ int asm_rr(const char* op, int rs1, int rs2) {
|
|||
}
|
||||
|
||||
int asm_rr_arith(const char* op, int rs1, int rs2) {
|
||||
if (local_type[rs1] & TYPE_PTR_MASK || local_type[rs2] & TYPE_PTR_MASK
|
||||
|| local_type[rs1] & TYPE_FUNC_MASK || local_type[rs2] & TYPE_FUNC_MASK) {
|
||||
if (local_type[rs1] & TYPE_PTR_MASK || local_type[rs2] & TYPE_PTR_MASK) {
|
||||
eprintf("pointer cannot be arithmetically operated by %s\n", op);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -778,29 +781,12 @@ int asm_sub(int lhs, int rhs) {
|
|||
// parser
|
||||
int parse_expr();
|
||||
|
||||
int parse_primary_expr() {
|
||||
next_token();
|
||||
if (token_type == TOKEN_EOF) {
|
||||
exit(1);
|
||||
} else if (token_type == TOKEN_NUMBER) {
|
||||
printf(" li t0, %d\n", token_data);
|
||||
return materialize_t0(TYPE_INT);
|
||||
} else if (token_type == TOKEN_ID) {
|
||||
return lookup(token_data);
|
||||
} else if (token_type == TOKEN_STRING) {
|
||||
printf(" la t0, .LC%d\n", token_data);
|
||||
return materialize_t0(TYPE_CHAR_PTR);
|
||||
} else if (token_type == TOKEN_PAREN_LEFT) {
|
||||
int reg = parse_expr();
|
||||
expect_token(TOKEN_PAREN_RIGHT);
|
||||
return reg;
|
||||
} else {
|
||||
eprintf("unexpected token in primary expression: %d\n", token_type);
|
||||
int parse_function_call(int id) {
|
||||
const char* name = id_table + id_lut[id];
|
||||
if (global_marker[id] != MARKER_FUNCTION) {
|
||||
eprintf("not a function name: %s\n", name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int parse_function_call(int func) {
|
||||
int arg = 0;
|
||||
int args[8];
|
||||
while (1) {
|
||||
|
@ -828,9 +814,8 @@ int parse_function_call(int func) {
|
|||
load(0, args[i]);
|
||||
printf(" mv a%d, t0\n", i);
|
||||
}
|
||||
load_address(0, func);
|
||||
printf(" jalr t0\n");
|
||||
int type = local_type[func];
|
||||
printf(" call %s\n", name);
|
||||
int type = global_type[id];
|
||||
if (type != TYPE_VOID) {
|
||||
printf(" mv t0, a0\n");
|
||||
return materialize_t0(type);
|
||||
|
@ -838,6 +823,33 @@ int parse_function_call(int func) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int parse_primary_expr() {
|
||||
next_token();
|
||||
if (token_type == TOKEN_EOF) {
|
||||
exit(1);
|
||||
} else if (token_type == TOKEN_NUMBER) {
|
||||
printf(" li t0, %d\n", token_data);
|
||||
return materialize_t0(TYPE_INT);
|
||||
} else if (token_type == TOKEN_ID) {
|
||||
next_token();
|
||||
if (token_type == TOKEN_PAREN_LEFT) {
|
||||
return parse_function_call(token_data);
|
||||
}
|
||||
unget_token();
|
||||
return lookup(token_data);
|
||||
} else if (token_type == TOKEN_STRING) {
|
||||
printf(" la t0, .LC%d\n", token_data);
|
||||
return materialize_t0(TYPE_CHAR_PTR);
|
||||
} else if (token_type == TOKEN_PAREN_LEFT) {
|
||||
int reg = parse_expr();
|
||||
expect_token(TOKEN_PAREN_RIGHT);
|
||||
return reg;
|
||||
} else {
|
||||
eprintf("unexpected token in primary expression: %d\n", token_type);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int parse_postfix_expr() {
|
||||
int lhs = parse_primary_expr();
|
||||
while (1) {
|
||||
|
@ -862,8 +874,6 @@ int parse_postfix_expr() {
|
|||
int rhs = parse_expr();
|
||||
expect_token(TOKEN_BRACKET_RIGHT);
|
||||
lhs = dereference(asm_add(lhs, rhs));
|
||||
} else if (token_type == TOKEN_PAREN_LEFT) {
|
||||
lhs = parse_function_call(lhs);
|
||||
} else {
|
||||
unget_token();
|
||||
break;
|
||||
|
@ -1440,7 +1450,7 @@ void parse_global_declaration() {
|
|||
char* name = id_table + id_lut[id];
|
||||
next_token();
|
||||
if (token_type == TOKEN_PAREN_LEFT) {
|
||||
declare_global(id, MARKER_SCALAR, type | TYPE_FUNC_MASK);
|
||||
declare_global(id, MARKER_FUNCTION, type);
|
||||
parse_function(name);
|
||||
} else {
|
||||
declare_global(id, MARKER_SCALAR, type);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue