some code for goto handling

This commit is contained in:
hyunghwan.chung 2019-07-26 07:40:58 +00:00
parent bd1d30360e
commit 299faf4a87
5 changed files with 51 additions and 5 deletions

View File

@ -124,6 +124,7 @@ class MyObject(Object)
'break or continue not within a loop' 'break or continue not within a loop'
'break or continue within a block' 'break or continue within a block'
'while expected' 'while expected'
'invalid goto target'
). ).
f := Stdio open: 'generr.out' for: 'w'. f := Stdio open: 'generr.out' for: 'w'.

View File

@ -918,7 +918,7 @@ static int add_to_oow_pool (moo_t* moo, moo_oow_pool_t* pool, moo_oow_t v)
{ {
moo_oow_pool_chunk_t* chunk; moo_oow_pool_chunk_t* chunk;
chunk = moo_allocmem (moo, MOO_SIZEOF(pool->static_chunk)); chunk = (moo_oow_pool_chunk_t*)moo_allocmem(moo, MOO_SIZEOF(pool->static_chunk));
if (!chunk) return -1; if (!chunk) return -1;
chunk->next = MOO_NULL; chunk->next = MOO_NULL;
@ -2785,7 +2785,7 @@ static int push_loop (moo_t* moo, moo_loop_type_t type, moo_oow_t startpos)
{ {
moo_loop_t* loop; moo_loop_t* loop;
loop = moo_callocmem(moo, MOO_SIZEOF(*loop)); loop = (moo_loop_t*)moo_callocmem(moo, MOO_SIZEOF(*loop));
if (!loop) return -1; if (!loop) return -1;
init_oow_pool (moo, &loop->break_ip_pool); init_oow_pool (moo, &loop->break_ip_pool);
@ -6662,6 +6662,43 @@ static int add_label (moo_t* moo, const moo_oocs_t* name)
return 0; return 0;
} }
static int compile_goto_statement (moo_t* moo)
{
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
moo_goto_t* _goto;
moo_oocs_t* target;
moo_ooch_t* nptr;
if (TOKEN_TYPE(moo) != MOO_IOTOK_IDENT)
{
moo_setsynerr (moo, MOO_SYNERR_GOTOTARGETINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
target = TOKEN_NAME(moo);
_goto = (moo_goto_t*)moo_allocmem(moo, MOO_SIZEOF(*_goto) + (target->len + 1) * MOO_SIZEOF(moo_ooch_t));
if (!_goto) return -1;
nptr = (moo_ooch_t*)(_goto + 1);
moo_copy_oochars (nptr, target->ptr, target->len);
nptr[target->len] = '\0';
#if 0
if (add_to_oow_pool(moo, &cc->mth._goto->target_ip_pool, cc->mth.code.len) <= -1 ||
emit_single_param_instruction(moo, BCODE_JUMP_FORWARD_0, MAX_CODE_JUMP, srcloc) <= -1)
{
moo_freemem (moo, _goto);
return -1;
}
#endif
_goto->next = cc->mth._goto;
cc->mth._goto = _goto;
GET_TOKEN (moo); /* read the next token to the target label */
return 0;
}
static int compile_special_statement (moo_t* moo) static int compile_special_statement (moo_t* moo)
{ {
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit; moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
@ -6728,6 +6765,11 @@ MOO_DEBUG2 (moo, "LABEL => %.*js\n", TOKEN_NAME_LEN(moo), TOKEN_NAME_PTR(moo));
GET_TOKEN (moo); GET_TOKEN (moo);
return 8888; /* indicates that non-statement has been seen and processed.*/ return 8888; /* indicates that non-statement has been seen and processed.*/
} }
else if (TOKEN_TYPE(moo) == MOO_IOTOK_GOTO)
{
GET_TOKEN (moo);
return compile_goto_statement(moo);
}
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 */
} }

View File

@ -149,6 +149,7 @@ static moo_ooch_t synerrstr_73[] = {'l','i','t','e','r','a','l',' ','e','x','p',
static moo_ooch_t synerrstr_74[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'}; static moo_ooch_t synerrstr_74[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\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_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[] = 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,
@ -160,7 +161,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_72, synerrstr_73, synerrstr_74, synerrstr_75, synerrstr_76, synerrstr_77
}; };
#endif #endif
/* END: GENERATED WITH generr.moo */ /* END: GENERATED WITH generr.moo */

View File

@ -411,8 +411,9 @@ struct moo_label_t
typedef struct moo_goto_t moo_goto_t; typedef struct moo_goto_t moo_goto_t;
struct moo_goto_t struct moo_goto_t
{ {
moo_ooch_t* label_name; moo_ooch_t* target_name;
moo_oow_t level; moo_oow_t level;
moo_oow_t ip;
moo_goto_t* next; moo_goto_t* next;
}; };

View File

@ -1894,7 +1894,8 @@ enum moo_synerrnum_t
MOO_SYNERR_LITERAL, /* literal expected */ MOO_SYNERR_LITERAL, /* literal expected */
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 */
}; };
typedef enum moo_synerrnum_t moo_synerrnum_t; typedef enum moo_synerrnum_t moo_synerrnum_t;