changing how to emit code for square bracked block to solve goto related issues. work still in progress
This commit is contained in:
parent
55bf7e269e
commit
ea69bb8d45
@ -125,6 +125,7 @@ class MyObject(Object)
|
|||||||
'break or continue within a block'
|
'break or continue within a block'
|
||||||
'while expected'
|
'while expected'
|
||||||
'invalid goto target'
|
'invalid goto target'
|
||||||
|
'label at end'
|
||||||
).
|
).
|
||||||
|
|
||||||
f := Stdio open: 'generr.out' for: 'w'.
|
f := Stdio open: 'generr.out' for: 'w'.
|
||||||
|
163
moo/lib/comp.c
163
moo/lib/comp.c
@ -4952,16 +4952,23 @@ static int compile_block_expression (moo_t* moo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#elif 0
|
||||||
code_start = cc->mth.code.len;
|
code_start = cc->mth.code.len;
|
||||||
|
|
||||||
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACK)
|
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACK)
|
||||||
{
|
{
|
||||||
moo_oow_t pop_stacktop_pos = 0;
|
moo_oow_t pop_stacktop_pos = 0;
|
||||||
|
|
||||||
while (TOKEN_TYPE(moo) != MOO_IOTOK_EOF)
|
do
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_EOF)
|
||||||
|
{
|
||||||
|
moo_setsynerr (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
n = compile_block_statement(moo);
|
n = compile_block_statement(moo);
|
||||||
if (n <= -1) return -1;
|
if (n <= -1) return -1;
|
||||||
if (n == 8888)
|
if (n == 8888)
|
||||||
@ -4975,6 +4982,29 @@ static int compile_block_expression (moo_t* moo)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (n == 7777)
|
||||||
|
{
|
||||||
|
/* goto statement -
|
||||||
|
* the goto statement looks like a normal statement, but it never pushes a value.
|
||||||
|
* so no pop_stacktop instruction needs to get injected */
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK)
|
||||||
|
{
|
||||||
|
/* eliminate BCODE_POP_STACKTOP produced in the else block below
|
||||||
|
* becuase the non-steatemnt item is the last item before the closing bracket */
|
||||||
|
if (pop_stacktop_pos > 0) eliminate_instructions (moo, pop_stacktop_pos, cc->mth.code.len - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
||||||
|
{
|
||||||
|
GET_TOKEN (moo);
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK) break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moo_setsynerr (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* a proper statement has been processed in compile_block_statemnt */
|
/* a proper statement has been processed in compile_block_statemnt */
|
||||||
@ -4995,6 +5025,7 @@ static int compile_block_expression (moo_t* moo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cc->mth.code.len == code_start)
|
if (cc->mth.code.len == code_start)
|
||||||
@ -5002,6 +5033,107 @@ static int compile_block_expression (moo_t* moo)
|
|||||||
/* the block is empty */
|
/* the block is empty */
|
||||||
if (emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) return -1;
|
if (emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
moo_oow_t pop_stacktop_pos = INVALID_IP; /* TODO: move this up */
|
||||||
|
|
||||||
|
code_start = cc->mth.code.len;
|
||||||
|
if (emit_byte_instruction(moo, BCODE_PUSH_NIL, TOKEN_LOC(moo)) <= -1) return -1;
|
||||||
|
pop_stacktop_pos = cc->mth.code.len;
|
||||||
|
if (emit_byte_instruction(moo, BCODE_POP_STACKTOP, TOKEN_LOC(moo)) <= -1) return -1;
|
||||||
|
|
||||||
|
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACK)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_EOF)
|
||||||
|
{
|
||||||
|
moo_setsynerr (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = compile_block_statement(moo);
|
||||||
|
if (n <= -1) return -1;
|
||||||
|
if (n == 8888)
|
||||||
|
{
|
||||||
|
/* compile_block_statement() processed non-statement item like a jump label. */
|
||||||
|
MOO_ASSERT (moo, cc->mth._label != MOO_NULL);
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK)
|
||||||
|
{
|
||||||
|
/* the last label inside [] must be followed by a valid statement */
|
||||||
|
moo_oocs_t labname;
|
||||||
|
labname.ptr = (moo_ooch_t*)(cc->mth._label + 1);
|
||||||
|
labname.len = moo_count_oocstr(labname.ptr);
|
||||||
|
moo_setsynerrbfmt (moo, MOO_SYNERR_LABELATEND, &cc->mth._label->loc, &labname, "label at end of square bracketed block");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (n == 7777)
|
||||||
|
{
|
||||||
|
/* goto statement -
|
||||||
|
* the goto statement looks like a normal statement, but it never pushes a value.
|
||||||
|
* so no pop_stacktop instruction needs to get injected */
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK)
|
||||||
|
{
|
||||||
|
/* eliminate BCODE_POP_STACKTOP produced in the else block below
|
||||||
|
* becuase the non-stetment item is the last item before the closing bracket */
|
||||||
|
if (pop_stacktop_pos != INVALID_IP)
|
||||||
|
{
|
||||||
|
eliminate_instructions (moo, pop_stacktop_pos, pop_stacktop_pos);
|
||||||
|
pop_stacktop_pos = INVALID_IP;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
||||||
|
{
|
||||||
|
GET_TOKEN (moo);
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK) break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moo_setsynerr (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* a proper statement has been processed in compile_block_statemnt */
|
||||||
|
pop_stacktop_pos = cc->mth.code.len;
|
||||||
|
if (emit_byte_instruction(moo, BCODE_POP_STACKTOP, TOKEN_LOC(moo)) <= -1) return -1;
|
||||||
|
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK)
|
||||||
|
{
|
||||||
|
eliminate_instructions(moo, pop_stacktop_pos, pop_stacktop_pos);
|
||||||
|
pop_stacktop_pos = INVALID_IP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
||||||
|
{
|
||||||
|
moo_ioloc_t period_loc = *TOKEN_LOC(moo);
|
||||||
|
GET_TOKEN (moo);
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACK)
|
||||||
|
{
|
||||||
|
eliminate_instructions(moo, pop_stacktop_pos, pop_stacktop_pos);
|
||||||
|
pop_stacktop_pos = INVALID_IP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moo_setsynerr (moo, MOO_SYNERR_RBRACK, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (cc->mth.code.len > 2 && cc->mth.code.len - 2 == code_start)
|
||||||
|
{
|
||||||
|
if (cc->mth.code.ptr[code_start] == BCODE_PUSH_NIL
|
||||||
|
}*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (emit_byte_instruction(moo, BCODE_RETURN_FROM_BLOCK, TOKEN_LOC(moo)) <= -1) return -1;
|
if (emit_byte_instruction(moo, BCODE_RETURN_FROM_BLOCK, TOKEN_LOC(moo)) <= -1) return -1;
|
||||||
@ -6053,15 +6185,33 @@ static int compile_braced_block (moo_t* moo)
|
|||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE)
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE)
|
||||||
{
|
{
|
||||||
/* non-statement followed by the closing brace.
|
/* non-statement followed by the closing brace.
|
||||||
* if there is a statement above the non-statement item, the POP_STACKSTOP is procuced.
|
* if there is a statement above the non-statement item, the POP_STACKSTOP is produced.
|
||||||
* it should be eliminated since the block should return the last evalulated value */
|
* it should be eliminated since the block should return the last evalulated value */
|
||||||
if (pop_stacktop_pos > 0) eliminate_instructions (moo, pop_stacktop_pos, cc->mth.code.len - 1);
|
if (pop_stacktop_pos > 0) eliminate_instructions (moo, pop_stacktop_pos, cc->mth.code.len - 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (n == 7777)
|
||||||
|
{
|
||||||
|
/* goto statement */
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE)
|
||||||
|
{
|
||||||
|
if (pop_stacktop_pos > 0) eliminate_instructions (moo, pop_stacktop_pos, cc->mth.code.len - 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
||||||
|
{
|
||||||
|
GET_TOKEN (moo);
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
moo_setsynerr (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) break;
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_RBRACE) break;
|
||||||
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
|
||||||
{
|
{
|
||||||
@ -6693,7 +6843,7 @@ static MOO_INLINE int resolve_goto_label (moo_t* moo, moo_goto_t* _goto)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gtname.len = moo_count_oocstr(gtname.ptr);
|
gtname.len = moo_count_oocstr(gtname.ptr);
|
||||||
moo_setsynerrbfmt (moo, MOO_SYNERR_NAMEUNDEF, &_goto->loc, >name, "undefined goto label - %js", gtname);
|
moo_setsynerrbfmt (moo, MOO_SYNERR_NAMEUNDEF, &_goto->loc, >name, "undefined goto label");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6856,7 +7006,8 @@ static int compile_special_statement (moo_t* moo)
|
|||||||
else if (TOKEN_TYPE(moo) == MOO_IOTOK_GOTO)
|
else if (TOKEN_TYPE(moo) == MOO_IOTOK_GOTO)
|
||||||
{
|
{
|
||||||
GET_TOKEN (moo);
|
GET_TOKEN (moo);
|
||||||
return compile_goto_statement(moo);
|
if (compile_goto_statement(moo) <= -1) return -1;
|
||||||
|
return 7777; /* indicate that a goto statement has been seen and processed */
|
||||||
}
|
}
|
||||||
|
|
||||||
return 9999; /* to indicate that no special statement has been seen and processed */
|
return 9999; /* to indicate that no special statement has been seen and processed */
|
||||||
|
@ -150,6 +150,7 @@ static moo_ooch_t synerrstr_74[] = {'b','r','e','a','k',' ','o','r',' ','c','o',
|
|||||||
static moo_ooch_t synerrstr_75[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'};
|
static moo_ooch_t synerrstr_75[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'};
|
||||||
static moo_ooch_t synerrstr_76[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'};
|
static moo_ooch_t synerrstr_76[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'};
|
||||||
static moo_ooch_t synerrstr_77[] = {'i','n','v','a','l','i','d',' ','g','o','t','o',' ','t','a','r','g','e','t','\0'};
|
static moo_ooch_t synerrstr_77[] = {'i','n','v','a','l','i','d',' ','g','o','t','o',' ','t','a','r','g','e','t','\0'};
|
||||||
|
static moo_ooch_t synerrstr_78[] = {'l','a','b','e','l',' ','a','t',' ','e','n','d','\0'};
|
||||||
static moo_ooch_t* synerrstr[] =
|
static moo_ooch_t* synerrstr[] =
|
||||||
{
|
{
|
||||||
synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7,
|
synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7,
|
||||||
@ -161,7 +162,7 @@ static moo_ooch_t* synerrstr[] =
|
|||||||
synerrstr_48, synerrstr_49, synerrstr_50, synerrstr_51, synerrstr_52, synerrstr_53, synerrstr_54, synerrstr_55,
|
synerrstr_48, synerrstr_49, synerrstr_50, synerrstr_51, synerrstr_52, synerrstr_53, synerrstr_54, synerrstr_55,
|
||||||
synerrstr_56, synerrstr_57, synerrstr_58, synerrstr_59, synerrstr_60, synerrstr_61, synerrstr_62, synerrstr_63,
|
synerrstr_56, synerrstr_57, synerrstr_58, synerrstr_59, synerrstr_60, synerrstr_61, synerrstr_62, synerrstr_63,
|
||||||
synerrstr_64, synerrstr_65, synerrstr_66, synerrstr_67, synerrstr_68, synerrstr_69, synerrstr_70, synerrstr_71,
|
synerrstr_64, synerrstr_65, synerrstr_66, synerrstr_67, synerrstr_68, synerrstr_69, synerrstr_70, synerrstr_71,
|
||||||
synerrstr_72, synerrstr_73, synerrstr_74, synerrstr_75, synerrstr_76, synerrstr_77
|
synerrstr_72, synerrstr_73, synerrstr_74, synerrstr_75, synerrstr_76, synerrstr_77, synerrstr_78
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
/* END: GENERATED WITH generr.moo */
|
/* END: GENERATED WITH generr.moo */
|
||||||
|
@ -1894,7 +1894,8 @@ enum moo_synerrnum_t
|
|||||||
MOO_SYNERR_NOTINLOOP, /* break or continue not within a loop */
|
MOO_SYNERR_NOTINLOOP, /* break or continue not within a loop */
|
||||||
MOO_SYNERR_INBLOCK, /* break or continue within a block */
|
MOO_SYNERR_INBLOCK, /* break or continue within a block */
|
||||||
MOO_SYNERR_WHILE, /* while expected */
|
MOO_SYNERR_WHILE, /* while expected */
|
||||||
MOO_SYNERR_GOTOTARGETINVAL /* invalid goto target */
|
MOO_SYNERR_GOTOTARGETINVAL, /* invalid goto target */
|
||||||
|
MOO_SYNERR_LABELATEND /* label at the end without following statement */
|
||||||
};
|
};
|
||||||
typedef enum moo_synerrnum_t moo_synerrnum_t;
|
typedef enum moo_synerrnum_t moo_synerrnum_t;
|
||||||
|
|
||||||
|
2
moo/t/m/b-001.txt
Normal file
2
moo/t/m/b-001.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[ X02: 20 ] value dump.
|
||||||
|
[ X02: 20 ] value dump. // syntax error X02 is a duplicate label. a label must be uniquie method-wide.
|
2
moo/t/m/b-002.txt
Normal file
2
moo/t/m/b-002.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[ goto X03. ] value dump. /* Unable to jump out of a block */
|
||||||
|
[ goto X02. X01: 9. goto X03. X02: goto X01. X03: 20. ] value dump.
|
38
moo/t/m/r.awk
Normal file
38
moo/t/m/r.awk
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
### THIS SCRIPT NEEDS MUCH MORE ENHANCEMENT.
|
||||||
|
### THE CURRENT CODE IS JUST TEMPORARY.
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
@local pid, workfile, d, f, cmd;
|
||||||
|
|
||||||
|
pid = sys::getpid();
|
||||||
|
workfile = "moo-test." pid;
|
||||||
|
|
||||||
|
d = dir::open (".", dir::SORT);
|
||||||
|
while (dir::read(d, f) > 0)
|
||||||
|
{
|
||||||
|
if (f !~ /.txt$/) continue;
|
||||||
|
|
||||||
|
print "#include \"../../kernel/Moo.moo\"." > workfile;
|
||||||
|
print "class MyObject(Object) {" >> workfile;
|
||||||
|
print "\tmethod(#class) main" >> workfile;
|
||||||
|
print "\t{" >> workfile;
|
||||||
|
|
||||||
|
while ((getline x < f) > 0)
|
||||||
|
{
|
||||||
|
print x >> workfile;
|
||||||
|
}
|
||||||
|
close (f);
|
||||||
|
|
||||||
|
print "\t}" >> workfile;
|
||||||
|
print "\}" >> workfile;
|
||||||
|
close (workfile);
|
||||||
|
|
||||||
|
cmd = "/home/hyung-hwan/xxx/bin/moo " workfile;
|
||||||
|
print "<" f ">";
|
||||||
|
##sys::system ("cat " workfile);
|
||||||
|
sys::system (cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
dir::close(d);
|
||||||
|
sys::unlink (workfile);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user