Skip to content

Commit

Permalink
support assignment between structs (#38)
Browse files Browse the repository at this point in the history
* support assignment between structs

* teach struct assignment expression to return value

* evaluate rhs of struct assignment

---------

Co-authored-by: choc <[email protected]>
  • Loading branch information
youbitchoc and youbitchoc authored Jul 22, 2024
1 parent 09f53d0 commit 0a590db
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 4 deletions.
39 changes: 35 additions & 4 deletions src/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ static void gen_addr(Node *node, int depth) {
gen_addr(node->lhs, depth);
emit_add(node->member->offset);
return;
case ND_ASSIGN:
if (node->ty->kind == TY_STRUCT) {
gen_addr(node->rhs, depth);
return;
}
/* fallthrough */
default:
error_tok(node->tok, "not an lvalue");
return;
Expand Down Expand Up @@ -245,10 +251,35 @@ static void gen(Node *node, int depth) {
load(node->ty);
return;
case ND_ASSIGN:
gen(node->rhs, depth);
fix_bool(node->ty);
gen_lval(node->lhs, depth + 2);
store(node->ty);
if (node->rhs->ty->kind == TY_STRUCT) {
gen(node->rhs, depth);
op(POP2);
int i = node->ty->size;
if (i % 2 == 1) {
i--;
gen_lval(node->rhs, depth);
emit_add(i);
op(LDA);
gen_lval(node->lhs, depth);
emit_add(i);
op(STA);
}
while (i > 0) {
i -= 2;
gen_lval(node->rhs, depth);
emit_add(i);
op(LDA2);
gen_lval(node->lhs, depth);
emit_add(i);
op(STA2);
}
lit2(0);
} else {
gen(node->rhs, depth);
fix_bool(node->ty);
gen_lval(node->lhs, depth + 2);
store(node->ty);
}
return;
case ND_TERNARY: {
int seq = labelseq++;
Expand Down
6 changes: 6 additions & 0 deletions tests
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,12 @@ void main() {

assert(0, ({ struct {int a; int b;} x[2]={0,1,2,3}; x[0].a; }), "struct {int a; int b;} x[2]={0,1,2,3}; x[0].a;");
assert(2, ({ struct {int a; int b;} x[2]={0,1,2,3}; x[1].a; }), "struct {int a; int b;} x[2]={0,1,2,3}; x[1].a;");
assert(9, ({ struct {int a; int b; int c;} x = {2,3,4}, y = {0,0,0}; y = x; y.a + y.b + y.c; }),
"struct {int a; int b; int c;} x = {2,3,4}, y = {0,0,0}; y = x; y.a + y.b + y.c;");
assert(2, ({ struct {char a; int b;} x={1,2}, y={0,0}; (y = x).b; }),
"struct {char a; int b;} x={1,2}, y={0,0}; (y = x).b;");
assert(6, ({ struct {char a; int b;} x={1,2}, y={0,0}, z={0,0}; z = y = x; z.a + z.b + y.a + y.b; }),
"struct {char a; int b;} x={1,2}, y={0,0}, z={0,0}; z = y = x; z.a + z.b + y.a + y.b;");

assert(0, strcmp(g15, "foo"), "strcmp(g15, \"foo\")");
assert(0, strcmp(g16[0], "foo"), "strcmp(g16[0], \"foo\")");
Expand Down

0 comments on commit 0a590db

Please sign in to comment.