From bb41dc548655859964b0cc38a70ea020a5bd92ad Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Wed, 7 Aug 2019 08:34:53 +0000 Subject: [PATCH] enhanced compile_while_expression()/compile_do_while_expression() not to eliminate blocks containing one or more labels --- moo/kernel/test-003.moo | 76 +++++++++++++++++++++++++++++++++++++++-- moo/lib/comp.c | 16 ++++++--- 2 files changed, 84 insertions(+), 8 deletions(-) diff --git a/moo/kernel/test-003.moo b/moo/kernel/test-003.moo index 44a9427..716e3a9 100644 --- a/moo/kernel/test-003.moo +++ b/moo/kernel/test-003.moo @@ -53,7 +53,7 @@ class MyObject(Object) } - method(#class) local_return_001 + method(#class) test_local_return_001 { | a b c d| a := 10. @@ -70,6 +70,74 @@ class MyObject(Object) ^a == 13 and b == 77 and c == 88 and d == 3. } + method(#class) test_if_001 + { + | a b c d e x | + + x := if (false) { X02: a := 55. goto Z02 } + elif (false) { b := 66.} + elif (2 > 1) { c := 77. goto X02 } + elif (true) { d := 88 } + else { Z02: e := 99 }. + + ^c == 77 and a == 55 and e == 99 and b == nil and d == nil and x == 99. + } + + method(#class) test_while_001 + { + | a b i | + + a := 0. + b := #(0 0 0 0 0) copy. + i := 0. + + while (false) + { + X02: + a := a + 1. + b at: i put: 1. + i := i + 1. + goto X03. + }. + goto X02. + + until (false) + { + X03: + a := a + 2. + b at: i put: 2. + i := i + 1. + goto Y01. + }. + + do + { + X04: + a := a + 3. + b at: i put: 3. + i := i + 1. + goto X05. + } + while (true). + Y01: + goto X04. + + do + { + a := a + 4. + b at: i put: 4. + i := i + 1. + break. + X05: + a := a + 5. + b at: i put: 5. + i := i + 1. + } + until (false). + + ^a == 15 and b = #(1 2 3 5 4). + } + method(#class) q { | v | @@ -116,13 +184,15 @@ start: [ [] value == nil ], // 20-24 - [ self local_return_001 ], + [ self test_local_return_001 ], + [ self test_if_001 ], + [ self test_while_001 ], [ (if (1 > 2) { } else { }) == nil. ], [ (if (1 < 2) { } else { }) == nil. ], [ (if (1 > 2) { } else { goto A01. A01: }) == nil ], - [ (if (1 > 2) { } else { 9876. goto A02. A02: }) == 9876 ], // 25-29 + [ (if (1 > 2) { } else { 9876. goto A02. A02: }) == 9876 ], [ [ | a3 | a3:= 20. if (a3 == 21) { a3 := 4321. goto L03 } else { a3 := 1234. goto L03 }. a3 := 8888. L03: a3 ] value == 1234 ], [ [ | a4 | a4:= 21. if (a4 == 21) { a4 := 4321. goto L04 } else { a4 := 1234. goto L04 }. a4 := 8888. L04: a4 ] value == 4321 ] ). diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 166310e..1e46199 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -6462,6 +6462,7 @@ static int compile_while_expression (moo_t* moo) /* or compile_until_expression moo_ioloc_t while_loc, brace_loc, closing_brace_loc; moo_oow_t precondpos, postcondpos, prebbpos, postbbpos; int cond_style = 0, loop_pushed = 0, is_until_loop; + moo_label_t* la, * lb; MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_WHILE || TOKEN_TYPE(moo) == MOO_IOTOK_UNTIL); @@ -6521,12 +6522,14 @@ static int compile_while_expression (moo_t* moo) /* or compile_until_expression GET_TOKEN (moo); /* get { */ brace_loc = *TOKEN_LOC(moo); prebbpos = cc->mth.code.len; + la = cc->mth._label; if (compile_braced_block(moo) <= -1) goto oops; + lb = cc->mth._label; closing_brace_loc = *TOKEN_LOC(moo); GET_TOKEN (moo); /* get the next token after } */ postbbpos = cc->mth.code.len; - if (prebbpos + 1 == postbbpos && cc->mth.code.ptr[prebbpos] == BCODE_PUSH_NIL) + if (la == lb && prebbpos + 1 == postbbpos && cc->mth.code.ptr[prebbpos] == BCODE_PUSH_NIL) { /* optimization - * the braced block is kind of empty as it only pushes nil. @@ -6560,7 +6563,7 @@ static int compile_while_expression (moo_t* moo) /* or compile_until_expression } } - if (cond_style == -1) + if (la == lb && cond_style == -1) { /* optimization - get rid of instructions generated for the while * loop including the conditional as the condition was false */ @@ -6591,6 +6594,7 @@ static int compile_do_while_expression (moo_t* moo) moo_oow_t precondpos, postcondpos, prebbpos, postbbpos; int jbinst = 0, loop_pushed = 0, is_until_loop; moo_loop_t* loop = MOO_NULL; + moo_label_t* la, * lb; MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_DO); do_loc = *TOKEN_LOC(moo); @@ -6603,7 +6607,9 @@ static int compile_do_while_expression (moo_t* moo) if (push_loop(moo, MOO_LOOP_DO_WHILE, prebbpos) <= -1) goto oops; loop_pushed = 1; + la = cc->mth._label; if (compile_braced_block(moo) <= -1) goto oops; + lb = cc->mth._label; closing_brace_loc = *TOKEN_LOC(moo); GET_TOKEN (moo); /* get the next token after } */ @@ -6617,7 +6623,7 @@ static int compile_do_while_expression (moo_t* moo) GET_TOKEN (moo); /* get ( */ postbbpos = cc->mth.code.len; - if (prebbpos + 1 == postbbpos && cc->mth.code.ptr[prebbpos] == BCODE_PUSH_NIL) + if (la == lb && prebbpos + 1 == postbbpos && cc->mth.code.ptr[prebbpos] == BCODE_PUSH_NIL) { /* optimization - * the braced block is kind of empty as it only pushes nil. @@ -6651,14 +6657,14 @@ static int compile_do_while_expression (moo_t* moo) if (cc->mth.code.ptr[precondpos] == (is_until_loop? BCODE_PUSH_FALSE: BCODE_PUSH_TRUE)) { /* the conditional is always true. eliminate PUSH_TRUE and emit an absolute jump */ - eliminate_instructions (moo, precondpos, cc->mth.code.len - 1); + eliminate_instructions (moo, precondpos, precondpos); postcondpos = precondpos; jbinst = BCODE_JUMP_BACKWARD; } else if (cc->mth.code.ptr[precondpos] == (is_until_loop? BCODE_PUSH_TRUE: BCODE_PUSH_FALSE)) { /* the conditional is always false. eliminate PUSH_FALSE and don't emit jump */ - eliminate_instructions (moo, precondpos, cc->mth.code.len - 1); + eliminate_instructions (moo, precondpos, precondpos); postcondpos = precondpos; goto skip_emitting_jump_backward; }