mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 21:44:16 +00:00
Made type property of block_t constant and private
Further work towards cleaning up block_t hierarchy
This commit is contained in:
parent
96046ffd30
commit
d788c84440
4 changed files with 168 additions and 142 deletions
50
builtin.cpp
50
builtin.cpp
|
@ -842,8 +842,8 @@ static int builtin_block( parser_t &parser, wchar_t **argv )
|
||||||
case UNSET:
|
case UNSET:
|
||||||
{
|
{
|
||||||
while( block &&
|
while( block &&
|
||||||
block->type != FUNCTION_CALL &&
|
block->type() != FUNCTION_CALL &&
|
||||||
block->type != FUNCTION_CALL_NO_SHADOW )
|
block->type() != FUNCTION_CALL_NO_SHADOW )
|
||||||
block = block->outer;
|
block = block->outer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1530,8 +1530,7 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
|
||||||
|
|
||||||
woptind=0;
|
woptind=0;
|
||||||
|
|
||||||
block_t *newv = new block_t(FUNCTION_DEF);
|
parser.push_block( new function_def_block_t() );
|
||||||
parser.push_block( newv );
|
|
||||||
|
|
||||||
static const struct woption
|
static const struct woption
|
||||||
long_options[] =
|
long_options[] =
|
||||||
|
@ -1663,7 +1662,7 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
|
||||||
{
|
{
|
||||||
block_t *b = parser.current_block;
|
block_t *b = parser.current_block;
|
||||||
|
|
||||||
while( b && (b->type != SUBST) )
|
while( b && (b->type() != SUBST) )
|
||||||
b = b->outer;
|
b = b->outer;
|
||||||
|
|
||||||
if( b )
|
if( b )
|
||||||
|
@ -1730,7 +1729,7 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
parser.pop_block();
|
parser.pop_block();
|
||||||
parser.push_block( new block_t(FAKE) );
|
parser.push_block( new fake_block_t() );
|
||||||
builtin_print_help( parser, argv[0], stdout_buffer );
|
builtin_print_help( parser, argv[0], stdout_buffer );
|
||||||
return STATUS_BUILTIN_OK;
|
return STATUS_BUILTIN_OK;
|
||||||
|
|
||||||
|
@ -1835,7 +1834,7 @@ static int builtin_function( parser_t &parser, wchar_t **argv )
|
||||||
stderr_buffer.push_back(L'\n');
|
stderr_buffer.push_back(L'\n');
|
||||||
|
|
||||||
parser.pop_block();
|
parser.pop_block();
|
||||||
parser.push_block( new block_t(FAKE) );
|
parser.push_block( new fake_block_t() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3204,7 +3203,7 @@ static int builtin_for( parser_t &parser, wchar_t **argv )
|
||||||
|
|
||||||
if( res )
|
if( res )
|
||||||
{
|
{
|
||||||
parser.push_block( new block_t(FAKE) );
|
parser.push_block( new fake_block_t() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3235,7 +3234,7 @@ static int builtin_for( parser_t &parser, wchar_t **argv )
|
||||||
*/
|
*/
|
||||||
static int builtin_begin( parser_t &parser, wchar_t **argv )
|
static int builtin_begin( parser_t &parser, wchar_t **argv )
|
||||||
{
|
{
|
||||||
parser.push_block( new block_t(BEGIN) );
|
parser.push_block( new scope_block_t(BEGIN) );
|
||||||
parser.current_block->tok_pos = parser.get_pos();
|
parser.current_block->tok_pos = parser.get_pos();
|
||||||
return proc_get_last_status();
|
return proc_get_last_status();
|
||||||
}
|
}
|
||||||
|
@ -3266,7 +3265,7 @@ static int builtin_end( parser_t &parser, wchar_t **argv )
|
||||||
*/
|
*/
|
||||||
int kill_block = 1;
|
int kill_block = 1;
|
||||||
|
|
||||||
switch( parser.current_block->type )
|
switch( parser.current_block->type() )
|
||||||
{
|
{
|
||||||
case WHILE:
|
case WHILE:
|
||||||
{
|
{
|
||||||
|
@ -3290,6 +3289,7 @@ static int builtin_end( parser_t &parser, wchar_t **argv )
|
||||||
case IF:
|
case IF:
|
||||||
case SUBST:
|
case SUBST:
|
||||||
case BEGIN:
|
case BEGIN:
|
||||||
|
case SWITCH:
|
||||||
/*
|
/*
|
||||||
Nothing special happens at the end of these commands. The scope just ends.
|
Nothing special happens at the end of these commands. The scope just ends.
|
||||||
*/
|
*/
|
||||||
|
@ -3364,6 +3364,10 @@ static int builtin_end( parser_t &parser, wchar_t **argv )
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(false); //should never get here
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
if( kill_block )
|
if( kill_block )
|
||||||
|
@ -3385,7 +3389,7 @@ static int builtin_else( parser_t &parser, wchar_t **argv )
|
||||||
{
|
{
|
||||||
bool block_ok = false;
|
bool block_ok = false;
|
||||||
if_block_t *if_block = NULL;
|
if_block_t *if_block = NULL;
|
||||||
if (parser.current_block != NULL && parser.current_block->type == IF)
|
if (parser.current_block != NULL && parser.current_block->type() == IF)
|
||||||
{
|
{
|
||||||
if_block = static_cast<if_block_t *>(parser.current_block);
|
if_block = static_cast<if_block_t *>(parser.current_block);
|
||||||
if (if_block->if_expr_evaluated && ! if_block->else_evaluated)
|
if (if_block->if_expr_evaluated && ! if_block->else_evaluated)
|
||||||
|
@ -3441,8 +3445,8 @@ static int builtin_break_continue( parser_t &parser, wchar_t **argv )
|
||||||
|
|
||||||
|
|
||||||
while( (b != 0) &&
|
while( (b != 0) &&
|
||||||
( b->type != WHILE) &&
|
( b->type() != WHILE) &&
|
||||||
(b->type != FOR ) )
|
(b->type() != FOR ) )
|
||||||
{
|
{
|
||||||
b = b->outer;
|
b = b->outer;
|
||||||
}
|
}
|
||||||
|
@ -3457,8 +3461,8 @@ static int builtin_break_continue( parser_t &parser, wchar_t **argv )
|
||||||
}
|
}
|
||||||
|
|
||||||
b = parser.current_block;
|
b = parser.current_block;
|
||||||
while( ( b->type != WHILE) &&
|
while( ( b->type() != WHILE) &&
|
||||||
(b->type != FOR ) )
|
(b->type() != FOR ) )
|
||||||
{
|
{
|
||||||
b->skip=1;
|
b->skip=1;
|
||||||
b = b->outer;
|
b = b->outer;
|
||||||
|
@ -3475,7 +3479,7 @@ static int builtin_break_continue( parser_t &parser, wchar_t **argv )
|
||||||
|
|
||||||
static int builtin_breakpoint( parser_t &parser, wchar_t **argv )
|
static int builtin_breakpoint( parser_t &parser, wchar_t **argv )
|
||||||
{
|
{
|
||||||
parser.push_block( new block_t(BREAKPOINT) );
|
parser.push_block( new breakpoint_block_t() );
|
||||||
|
|
||||||
reader_read( STDIN_FILENO, real_io ? *real_io : io_chain_t() );
|
reader_read( STDIN_FILENO, real_io ? *real_io : io_chain_t() );
|
||||||
|
|
||||||
|
@ -3525,8 +3529,8 @@ static int builtin_return( parser_t &parser, wchar_t **argv )
|
||||||
|
|
||||||
|
|
||||||
while( (b != 0) &&
|
while( (b != 0) &&
|
||||||
( b->type != FUNCTION_CALL &&
|
( b->type() != FUNCTION_CALL &&
|
||||||
b->type != FUNCTION_CALL_NO_SHADOW) )
|
b->type() != FUNCTION_CALL_NO_SHADOW) )
|
||||||
{
|
{
|
||||||
b = b->outer;
|
b = b->outer;
|
||||||
}
|
}
|
||||||
|
@ -3541,10 +3545,10 @@ static int builtin_return( parser_t &parser, wchar_t **argv )
|
||||||
}
|
}
|
||||||
|
|
||||||
b = parser.current_block;
|
b = parser.current_block;
|
||||||
while( ( b->type != FUNCTION_CALL &&
|
while( ( b->type() != FUNCTION_CALL &&
|
||||||
b->type != FUNCTION_CALL_NO_SHADOW ) )
|
b->type() != FUNCTION_CALL_NO_SHADOW ) )
|
||||||
{
|
{
|
||||||
b->type = FAKE;
|
b->mark_as_fake();
|
||||||
b->skip=1;
|
b->skip=1;
|
||||||
b = b->outer;
|
b = b->outer;
|
||||||
}
|
}
|
||||||
|
@ -3571,7 +3575,7 @@ static int builtin_switch( parser_t &parser, wchar_t **argv )
|
||||||
|
|
||||||
builtin_print_help( parser, argv[0], stderr_buffer );
|
builtin_print_help( parser, argv[0], stderr_buffer );
|
||||||
res=1;
|
res=1;
|
||||||
parser.push_block( new block_t(FAKE) );
|
parser.push_block( new fake_block_t() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3593,7 +3597,7 @@ static int builtin_case( parser_t &parser, wchar_t **argv )
|
||||||
int i;
|
int i;
|
||||||
wchar_t *unescaped=0;
|
wchar_t *unescaped=0;
|
||||||
|
|
||||||
if( parser.current_block->type != SWITCH )
|
if( parser.current_block->type() != SWITCH )
|
||||||
{
|
{
|
||||||
append_format(stderr_buffer,
|
append_format(stderr_buffer,
|
||||||
_( L"%ls: 'case' command while not in switch block\n" ),
|
_( L"%ls: 'case' command while not in switch block\n" ),
|
||||||
|
|
132
parser.cpp
132
parser.cpp
|
@ -422,13 +422,13 @@ static int block_count( block_t *b )
|
||||||
|
|
||||||
void parser_t::push_block( block_t *newv )
|
void parser_t::push_block( block_t *newv )
|
||||||
{
|
{
|
||||||
const int type = newv->type;
|
const enum block_type_t type = newv->type();
|
||||||
newv->src_lineno = parser_t::get_lineno();
|
newv->src_lineno = parser_t::get_lineno();
|
||||||
newv->src_filename = parser_t::current_filename()?intern(parser_t::current_filename()):0;
|
newv->src_filename = parser_t::current_filename()?intern(parser_t::current_filename()):0;
|
||||||
|
|
||||||
newv->outer = current_block;
|
newv->outer = current_block;
|
||||||
if (current_block && current_block->skip)
|
if (current_block && current_block->skip)
|
||||||
newv->type = FAKE;
|
newv->mark_as_fake();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
New blocks should be skipped if the outer block is skipped,
|
New blocks should be skipped if the outer block is skipped,
|
||||||
|
@ -458,9 +458,9 @@ void parser_t::push_block( block_t *newv )
|
||||||
|
|
||||||
current_block = newv;
|
current_block = newv;
|
||||||
|
|
||||||
if( (newv->type != FUNCTION_DEF) &&
|
if( (newv->type() != FUNCTION_DEF) &&
|
||||||
(newv->type != FAKE) &&
|
(newv->type() != FAKE) &&
|
||||||
(newv->type != TOP) )
|
(newv->type() != TOP) )
|
||||||
{
|
{
|
||||||
env_push( type == FUNCTION_CALL );
|
env_push( type == FUNCTION_CALL );
|
||||||
newv->wants_pop_env = true;
|
newv->wants_pop_env = true;
|
||||||
|
@ -887,7 +887,7 @@ void parser_t::stack_trace( block_t *b, wcstring &buff)
|
||||||
if( !b )
|
if( !b )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( b->type==EVENT )
|
if( b->type()==EVENT )
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
This is an event handler
|
This is an event handler
|
||||||
|
@ -908,7 +908,7 @@ void parser_t::stack_trace( block_t *b, wcstring &buff)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( b->type == FUNCTION_CALL || b->type==SOURCE || b->type==SUBST)
|
if( b->type() == FUNCTION_CALL || b->type()==SOURCE || b->type()==SUBST)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
These types of blocks should be printed
|
These types of blocks should be printed
|
||||||
|
@ -916,7 +916,7 @@ void parser_t::stack_trace( block_t *b, wcstring &buff)
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
switch( b->type)
|
switch( b->type())
|
||||||
{
|
{
|
||||||
case SOURCE:
|
case SOURCE:
|
||||||
{
|
{
|
||||||
|
@ -936,6 +936,9 @@ void parser_t::stack_trace( block_t *b, wcstring &buff)
|
||||||
append_format( buff, _(L"in command substitution\n") );
|
append_format( buff, _(L"in command substitution\n") );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default: /* Can't get here */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const wchar_t *file = b->src_filename;
|
const wchar_t *file = b->src_filename;
|
||||||
|
@ -953,7 +956,7 @@ void parser_t::stack_trace( block_t *b, wcstring &buff)
|
||||||
_(L"\tcalled on standard input,\n") );
|
_(L"\tcalled on standard input,\n") );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( b->type == FUNCTION_CALL )
|
if( b->type() == FUNCTION_CALL )
|
||||||
{
|
{
|
||||||
const function_block_t *fb = static_cast<const function_block_t *>(b);
|
const function_block_t *fb = static_cast<const function_block_t *>(b);
|
||||||
const process_t * const process = fb->process;
|
const process_t * const process = fb->process;
|
||||||
|
@ -999,7 +1002,7 @@ const wchar_t *parser_t::is_function() const
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if( b->type == FUNCTION_CALL )
|
if( b->type() == FUNCTION_CALL )
|
||||||
{
|
{
|
||||||
const function_block_t *fb = static_cast<const function_block_t *>(b);
|
const function_block_t *fb = static_cast<const function_block_t *>(b);
|
||||||
return fb->name.c_str();
|
return fb->name.c_str();
|
||||||
|
@ -1051,7 +1054,7 @@ const wchar_t *parser_t::current_filename() const
|
||||||
{
|
{
|
||||||
return reader_current_filename();
|
return reader_current_filename();
|
||||||
}
|
}
|
||||||
if( b->type == FUNCTION_CALL )
|
if( b->type() == FUNCTION_CALL )
|
||||||
{
|
{
|
||||||
const function_block_t *fb = static_cast<const function_block_t *>(b);
|
const function_block_t *fb = static_cast<const function_block_t *>(b);
|
||||||
return function_get_definition_file(fb->name);
|
return function_get_definition_file(fb->name);
|
||||||
|
@ -1403,7 +1406,7 @@ void parser_t::parse_job_argument_list( process_t *p,
|
||||||
But if this is in fact a case statement, then it should be evaluated
|
But if this is in fact a case statement, then it should be evaluated
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( (current_block->type == SWITCH) && args.at(0).completion == L"case" && p->type == INTERNAL_BUILTIN )
|
if( (current_block->type() == SWITCH) && args.at(0).completion == L"case" && p->type == INTERNAL_BUILTIN )
|
||||||
{
|
{
|
||||||
skip=0;
|
skip=0;
|
||||||
}
|
}
|
||||||
|
@ -1855,7 +1858,7 @@ int parser_t::parse_job( process_t *p,
|
||||||
tok_next( tok );
|
tok_next( tok );
|
||||||
while_block_t *wb = NULL;
|
while_block_t *wb = NULL;
|
||||||
|
|
||||||
if( ( current_block->type != WHILE ) )
|
if( ( current_block->type() != WHILE ) )
|
||||||
{
|
{
|
||||||
new_block = true;
|
new_block = true;
|
||||||
}
|
}
|
||||||
|
@ -1917,9 +1920,9 @@ int parser_t::parse_job( process_t *p,
|
||||||
block scopes are pushed on function invocation changes,
|
block scopes are pushed on function invocation changes,
|
||||||
then this check will break.
|
then this check will break.
|
||||||
*/
|
*/
|
||||||
if( ( current_block->type == TOP ) &&
|
if( ( current_block->type() == TOP ) &&
|
||||||
( current_block->outer ) &&
|
( current_block->outer ) &&
|
||||||
( current_block->outer->type == FUNCTION_CALL ) )
|
( current_block->outer->type() == FUNCTION_CALL ) )
|
||||||
is_function_call = 1;
|
is_function_call = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2210,7 +2213,7 @@ int parser_t::parse_job( process_t *p,
|
||||||
{
|
{
|
||||||
if( !is_new_block )
|
if( !is_new_block )
|
||||||
{
|
{
|
||||||
current_block->had_command = 1;
|
current_block->had_command = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2249,7 +2252,7 @@ void parser_t::skipped_exec( job_t * j )
|
||||||
( wcscmp( p->argv0(), L"begin" )==0) ||
|
( wcscmp( p->argv0(), L"begin" )==0) ||
|
||||||
( wcscmp( p->argv0(), L"function" )==0))
|
( wcscmp( p->argv0(), L"function" )==0))
|
||||||
{
|
{
|
||||||
this->push_block( new block_t(FAKE) );
|
this->push_block( new fake_block_t() );
|
||||||
}
|
}
|
||||||
else if( wcscmp( p->argv0(), L"end" )==0)
|
else if( wcscmp( p->argv0(), L"end" )==0)
|
||||||
{
|
{
|
||||||
|
@ -2262,7 +2265,7 @@ void parser_t::skipped_exec( job_t * j )
|
||||||
}
|
}
|
||||||
else if( wcscmp( p->argv0(), L"else" )==0)
|
else if( wcscmp( p->argv0(), L"else" )==0)
|
||||||
{
|
{
|
||||||
if( (current_block->type == IF ) &&
|
if( (current_block->type() == IF ) &&
|
||||||
(static_cast<const if_block_t*>(current_block)->if_expr_evaluated))
|
(static_cast<const if_block_t*>(current_block)->if_expr_evaluated))
|
||||||
{
|
{
|
||||||
exec( *this, j );
|
exec( *this, j );
|
||||||
|
@ -2271,7 +2274,7 @@ void parser_t::skipped_exec( job_t * j )
|
||||||
}
|
}
|
||||||
else if( wcscmp( p->argv0(), L"case" )==0)
|
else if( wcscmp( p->argv0(), L"case" )==0)
|
||||||
{
|
{
|
||||||
if(current_block->type == SWITCH)
|
if(current_block->type() == SWITCH)
|
||||||
{
|
{
|
||||||
exec( *this, j );
|
exec( *this, j );
|
||||||
return;
|
return;
|
||||||
|
@ -2395,7 +2398,7 @@ void parser_t::eval_job( tokenizer *tok )
|
||||||
profile_item->exec=(int)(t3-t2);
|
profile_item->exec=(int)(t3-t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( current_block->type == WHILE )
|
if( current_block->type() == WHILE )
|
||||||
{
|
{
|
||||||
while_block_t *wb = static_cast<while_block_t *>(current_block);
|
while_block_t *wb = static_cast<while_block_t *>(current_block);
|
||||||
switch( wb->status )
|
switch( wb->status )
|
||||||
|
@ -2411,7 +2414,7 @@ void parser_t::eval_job( tokenizer *tok )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( current_block->type == IF )
|
if( current_block->type() == IF )
|
||||||
{
|
{
|
||||||
if_block_t *ib = static_cast<if_block_t *>(current_block);
|
if_block_t *ib = static_cast<if_block_t *>(current_block);
|
||||||
if( (! ib->if_expr_evaluated) &&
|
if( (! ib->if_expr_evaluated) &&
|
||||||
|
@ -2543,7 +2546,7 @@ int parser_t::eval( const wcstring &cmdStr, const io_chain_t &io, enum block_typ
|
||||||
|
|
||||||
eval_level++;
|
eval_level++;
|
||||||
|
|
||||||
this->push_block( new block_t(block_type) );
|
this->push_block( new scope_block_t(block_type) );
|
||||||
|
|
||||||
current_tokenizer = new tokenizer;
|
current_tokenizer = new tokenizer;
|
||||||
tok_init( current_tokenizer, cmd, 0 );
|
tok_init( current_tokenizer, cmd, 0 );
|
||||||
|
@ -2580,7 +2583,7 @@ int parser_t::eval( const wcstring &cmdStr, const io_chain_t &io, enum block_typ
|
||||||
//debug( 2, L"Status %d\n", proc_get_last_status() );
|
//debug( 2, L"Status %d\n", proc_get_last_status() );
|
||||||
|
|
||||||
debug( 1,
|
debug( 1,
|
||||||
L"%ls", parser_t::get_block_desc( current_block->type ) );
|
L"%ls", parser_t::get_block_desc( current_block->type() ) );
|
||||||
debug( 1,
|
debug( 1,
|
||||||
BLOCK_END_ERR_MSG );
|
BLOCK_END_ERR_MSG );
|
||||||
fwprintf( stderr, L"%ls", parser_t::current_line() );
|
fwprintf( stderr, L"%ls", parser_t::current_line() );
|
||||||
|
@ -3617,16 +3620,15 @@ int parser_t::test( const wchar_t * buff,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
block_t::block_t(int t) :
|
block_t::block_t(block_type_t t) :
|
||||||
type(t),
|
block_type(t),
|
||||||
|
made_fake(false),
|
||||||
skip(),
|
skip(),
|
||||||
tok_pos(),
|
|
||||||
had_command(),
|
had_command(),
|
||||||
|
tok_pos(),
|
||||||
loop_status(),
|
loop_status(),
|
||||||
job(),
|
job(),
|
||||||
function_data(),
|
function_data(),
|
||||||
state1_ptr(),
|
|
||||||
state2_ptr(),
|
|
||||||
src_filename(),
|
src_filename(),
|
||||||
src_lineno(),
|
src_lineno(),
|
||||||
wants_pop_env(false),
|
wants_pop_env(false),
|
||||||
|
@ -3637,8 +3639,74 @@ block_t::block_t(int t) :
|
||||||
|
|
||||||
block_t::~block_t()
|
block_t::~block_t()
|
||||||
{
|
{
|
||||||
if (state1_ptr != NULL)
|
}
|
||||||
delete state1_ptr;
|
|
||||||
if (state2_ptr != NULL)
|
/* Various block constructors */
|
||||||
delete state2_ptr;
|
|
||||||
|
if_block_t::if_block_t() :
|
||||||
|
if_expr_evaluated(false),
|
||||||
|
if_expr_result(false),
|
||||||
|
else_evaluated(false),
|
||||||
|
block_t(IF)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
event_block_t::event_block_t(const event_t *evt) :
|
||||||
|
block_t(EVENT),
|
||||||
|
event(evt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
function_block_t::function_block_t(process_t *p, const wcstring &n, bool shadows) :
|
||||||
|
process(p),
|
||||||
|
name(n),
|
||||||
|
block_t( shadows ? FUNCTION_CALL : FUNCTION_CALL_NO_SHADOW )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
source_block_t::source_block_t(const wchar_t *src) :
|
||||||
|
source_file(src),
|
||||||
|
block_t(SOURCE)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
for_block_t::for_block_t(const wcstring &var) :
|
||||||
|
variable(var),
|
||||||
|
sequence(),
|
||||||
|
block_t(FOR)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
while_block_t::while_block_t() :
|
||||||
|
status(0),
|
||||||
|
block_t(WHILE)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_block_t::switch_block_t(const wcstring &sv) :
|
||||||
|
switch_taken(false),
|
||||||
|
switch_value(sv),
|
||||||
|
block_t(SWITCH)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fake_block_t::fake_block_t() :
|
||||||
|
block_t(FAKE)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
function_def_block_t::function_def_block_t() :
|
||||||
|
block_t(FUNCTION_DEF)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
scope_block_t::scope_block_t(block_type_t type) :
|
||||||
|
block_t(type)
|
||||||
|
{
|
||||||
|
assert(type == BEGIN || type == TOP || type == SUBST);
|
||||||
|
}
|
||||||
|
|
||||||
|
breakpoint_block_t::breakpoint_block_t() :
|
||||||
|
block_t(BREAKPOINT)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
126
parser.h
126
parser.h
|
@ -68,27 +68,28 @@ enum block_type_t
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
/** Block state template, to replace the discriminated union */
|
|
||||||
struct block_state_base_t {
|
|
||||||
public:
|
|
||||||
virtual ~block_state_base_t() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct block_state_t : public block_state_base_t {
|
|
||||||
T value;
|
|
||||||
block_state_t() : value() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
block_t represents a block of commands.
|
block_t represents a block of commands.
|
||||||
*/
|
*/
|
||||||
struct block_t
|
struct block_t
|
||||||
{
|
{
|
||||||
int type; /**< Type of block. Can be one of WHILE, FOR, IF and FUNCTION, or FAKE */
|
protected:
|
||||||
int skip; /**< Whether execution of the commands in this block should be skipped */
|
/** Protected constructor. Use one of the subclasses below. */
|
||||||
|
block_t(block_type_t t);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const block_type_t block_type; /**< Type of block. */
|
||||||
|
bool made_fake;
|
||||||
|
|
||||||
|
public:
|
||||||
|
block_type_t type() const { return this->made_fake ? FAKE : this->block_type; }
|
||||||
|
|
||||||
|
/** Mark a block as fake; this is used by the return statement. */
|
||||||
|
void mark_as_fake() { this->made_fake = true; }
|
||||||
|
|
||||||
|
bool skip; /**< Whether execution of the commands in this block should be skipped */
|
||||||
|
bool had_command; /**< Set to non-zero once a command has been executed in this block */
|
||||||
int tok_pos; /**< The start index of the block */
|
int tok_pos; /**< The start index of the block */
|
||||||
int had_command; /**< Set to non-zero once a command has been executed in this block */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Status for the current loop block. Can be any of the values from the loop_status enum.
|
Status for the current loop block. Can be any of the values from the loop_status enum.
|
||||||
|
@ -118,41 +119,6 @@ struct block_t
|
||||||
} param1;
|
} param1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** First block type specific variable */
|
|
||||||
block_state_base_t *state1_ptr;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T& state1_NOPE(void) {
|
|
||||||
block_state_t<T> *state;
|
|
||||||
if (state1_ptr == NULL) {
|
|
||||||
state = new block_state_t<T>();
|
|
||||||
state1_ptr = state;
|
|
||||||
} else {
|
|
||||||
state = dynamic_cast<block_state_t<T> *>(state1_ptr);
|
|
||||||
if (state == NULL) {
|
|
||||||
printf("Expected type %s, but instead got type %s\n", typeid(T).name(), typeid(*state1_ptr).name());
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Second block type specific variable */
|
|
||||||
block_state_base_t *state2_ptr;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T& state2_NOPE(void) {
|
|
||||||
block_state_t<T> *state;
|
|
||||||
if (state2_ptr == NULL) {
|
|
||||||
state = new block_state_t<T>();
|
|
||||||
state2_ptr = state;
|
|
||||||
} else {
|
|
||||||
state = dynamic_cast<block_state_t<T> *>(state2_ptr);
|
|
||||||
assert(state != NULL);
|
|
||||||
}
|
|
||||||
return state->value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Name of file that created this block
|
Name of file that created this block
|
||||||
*/
|
*/
|
||||||
|
@ -173,10 +139,7 @@ struct block_t
|
||||||
Next outer block
|
Next outer block
|
||||||
*/
|
*/
|
||||||
block_t *outer;
|
block_t *outer;
|
||||||
|
|
||||||
/** Constructor */
|
|
||||||
block_t(int t);
|
|
||||||
|
|
||||||
/** Destructor */
|
/** Destructor */
|
||||||
virtual ~block_t();
|
virtual ~block_t();
|
||||||
};
|
};
|
||||||
|
@ -185,65 +148,56 @@ struct if_block_t : public block_t {
|
||||||
bool if_expr_evaluated; // whether the clause of the if statement has been tested
|
bool if_expr_evaluated; // whether the clause of the if statement has been tested
|
||||||
bool if_expr_result; // if so, whether it evaluated to true
|
bool if_expr_result; // if so, whether it evaluated to true
|
||||||
bool else_evaluated; // whether we've encountered a terminal else block
|
bool else_evaluated; // whether we've encountered a terminal else block
|
||||||
if_block_t() :
|
if_block_t();
|
||||||
if_expr_evaluated(false),
|
|
||||||
if_expr_result(false),
|
|
||||||
else_evaluated(false),
|
|
||||||
block_t(IF)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct event_block_t : public block_t {
|
struct event_block_t : public block_t {
|
||||||
const event_t * const event;
|
const event_t * const event;
|
||||||
event_block_t(const event_t *evt) : block_t(EVENT), event(evt)
|
event_block_t(const event_t *evt);
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct function_block_t : public block_t {
|
struct function_block_t : public block_t {
|
||||||
process_t *process;
|
process_t *process;
|
||||||
wcstring name;
|
wcstring name;
|
||||||
|
function_block_t(process_t *p, const wcstring &n, bool shadows);
|
||||||
function_block_t(process_t *p, const wcstring &n, bool shadows) :
|
|
||||||
process(p),
|
|
||||||
name(n),
|
|
||||||
block_t( shadows ? FUNCTION_CALL : FUNCTION_CALL_NO_SHADOW )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct source_block_t : public block_t {
|
struct source_block_t : public block_t {
|
||||||
const wchar_t * const source_file;
|
const wchar_t * const source_file;
|
||||||
source_block_t(const wchar_t *src) : source_file(src), block_t(SOURCE)
|
source_block_t(const wchar_t *src);
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct for_block_t : public block_t {
|
struct for_block_t : public block_t {
|
||||||
wcstring variable; // the variable that will be assigned each value in the sequence
|
wcstring variable; // the variable that will be assigned each value in the sequence
|
||||||
wcstring_list_t sequence; // the sequence of values
|
wcstring_list_t sequence; // the sequence of values
|
||||||
for_block_t(const wcstring &var) :
|
for_block_t(const wcstring &var);
|
||||||
variable(var),
|
|
||||||
sequence(),
|
|
||||||
block_t(FOR)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct while_block_t : public block_t {
|
struct while_block_t : public block_t {
|
||||||
int status;
|
int status;
|
||||||
while_block_t() : status(0), block_t(WHILE)
|
while_block_t();
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct switch_block_t : public block_t {
|
struct switch_block_t : public block_t {
|
||||||
bool switch_taken;
|
bool switch_taken;
|
||||||
const wcstring switch_value;
|
const wcstring switch_value;
|
||||||
switch_block_t(const wcstring &sv) : switch_taken(false), switch_value(sv), block_t(SWITCH)
|
switch_block_t(const wcstring &sv);
|
||||||
{
|
};
|
||||||
}
|
|
||||||
|
struct fake_block_t : public block_t {
|
||||||
|
fake_block_t();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct function_def_block_t : public block_t {
|
||||||
|
function_def_block_t();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct scope_block_t : public block_t {
|
||||||
|
scope_block_t(block_type_t type); //must be BEGIN, TOP or SUBST
|
||||||
|
};
|
||||||
|
|
||||||
|
struct breakpoint_block_t : public block_t {
|
||||||
|
breakpoint_block_t();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2390,7 +2390,7 @@ static void handle_end_loop()
|
||||||
b;
|
b;
|
||||||
b = b->outer )
|
b = b->outer )
|
||||||
{
|
{
|
||||||
if( b->type == BREAKPOINT )
|
if( b->type() == BREAKPOINT )
|
||||||
{
|
{
|
||||||
is_breakpoint = 1;
|
is_breakpoint = 1;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue