⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expr.cc

📁 This Source-Navigator, an IDE for C/C++/Fortran/Java/Tcl/PHP/Python and a host of other languages.
💻 CC
📖 第 1 页 / 共 3 页
字号:
	return result;	}Value* RecordRefExpr::RefEval( value_type val_type )	{	Value* value_ref = op->RefEval( val_type );	Value* value = value_ref->Deref();	value = value->GetOrCreateRecordElement( field );	if ( val_type == VAL_REF && value->IsConst() )		warn->Report( "record field", this,				" is a \"const\" reference" );	value = new Value( value, val_type );	Unref( value_ref );	return value;	}void RecordRefExpr::Assign( Value* new_value )	{	Value* lhs_value_ref = op->RefEval( VAL_REF );	Value* lhs_value = lhs_value_ref->Deref();	if ( lhs_value->Type() == TYPE_BOOL && lhs_value->Length() == 1 )		// ### assume uninitialized variable		lhs_value->Polymorph( TYPE_RECORD );	if ( lhs_value->VecRefDeref()->Type() == TYPE_RECORD )		lhs_value->AssignRecordElement( field, new_value );	else		error->Report( op, "is not a record" );	Unref( new_value );	Unref( lhs_value_ref );	}void RecordRefExpr::Describe( ostream& s ) const	{	op->Describe( s );	s << "." << field;	}AttributeRefExpr::AttributeRefExpr( Expr *op1 ) : BinaryExpr(op1, 0, "::")	{	field = 0;	}AttributeRefExpr::AttributeRefExpr( Expr* op1, char* attribute ) :		BinaryExpr(op1, 0, "::")	{	field = attribute;	}AttributeRefExpr::AttributeRefExpr( Expr* op1, Expr* op2 ) :		BinaryExpr(op1, op2, "::[]")	{	field = 0;	}Value* AttributeRefExpr::Eval( eval_type etype )	{	const Value* val = left->ReadOnlyEval();	Value* result = 0;	const Value* const_result = 0;	if ( field )		const_result = val->ExistingAttribute( field );	else if ( right )		{		const Value* index_val = right->ReadOnlyEval();		if ( index_val && index_val->Type() == TYPE_STRING &&		     index_val->Length() == 1  )			const_result = val->ExistingAttribute( index_val );		else			const_result = val->AttributeRef( index_val );		right->ReadOnlyDone( index_val );		}	else		{		recordptr new_record = create_record_dict();		const attributeptr aptr = val->AttributePtr();		if ( aptr )			{			IterCookie* c = aptr->InitForIteration();			const Value* member;			const char* key;			while ( (member = aptr->NextEntry( key, c)) )				new_record->Insert( strdup( key ),						   copy_value( member ) );			}		result = new Value( new_record );		}	if ( ! result )		result = CopyOrRefValue( const_result->Deref(), etype );	left->ReadOnlyDone( val );	return result;	}Value* AttributeRefExpr::RefEval( value_type val_type )	{	Value* value_ref = left->RefEval( val_type );	Value* value = value_ref->Deref();	if ( field )		{		value = value->GetOrCreateAttribute( field );		if ( val_type == VAL_REF && value->IsConst() )			warn->Report( "attribute field", this,					" is a \"const\" reference" );		value = new Value( value, val_type );		}	else if ( right )		{		const Value* index_val = right->ReadOnlyEval();		if ( index_val && index_val->Type() == TYPE_STRING &&		     index_val->Length() == 1  )			{			value = value->GetOrCreateAttribute( index_val );			if ( val_type == VAL_REF && value->IsConst() )				warn->Report( "record field", this,						" is a \"const\" reference" );			value = new Value( value, val_type );			}		else			{			warn->Report( this, " invalid attribute access" );			value = error_value();			}		right->ReadOnlyDone( index_val );		}	else		{		warn->Report( this, " invalid attribute access" );		value = error_value();		}	Unref( value_ref );	return value;	}void AttributeRefExpr::Assign( Value* new_value )	{	Value* lhs_value_ref = left->RefEval( VAL_REF );	Value* lhs_value = lhs_value_ref->Deref();	if ( field )		lhs_value->AssignAttribute( field, new_value );	else if ( right )		{		const Value* index_val = right->ReadOnlyEval();		if ( index_val && index_val->Type() == TYPE_STRING &&		     index_val->Length() == 1  )			{			char* str = index_val->StringVal();			lhs_value->AssignAttribute( str, new_value );			delete str;			}		else			warn->Report( this, " invalid attribute access" );		right->ReadOnlyDone( index_val );		}	else		{		if ( new_value->Type() == TYPE_RECORD )			{			if ( new_value->Length() > 0 )				lhs_value->AssignAttributes(					copy_value( new_value ) );			else				lhs_value->AssignAttributes( 0 );			}		else			warn->Report( this, " invalid attribute assignment" );		}	Unref( new_value );	Unref( lhs_value_ref );	}void AttributeRefExpr::Describe( ostream& s ) const	{	left->Describe( s );	if ( field )		s << "::" << field;	else if ( right )		{		s << "::[";		right->Describe( s );		s << "]";		}	}RefExpr::RefExpr( Expr* op, value_type arg_type ) : UnaryExpr(op, "ref")	{	type = arg_type;	}Value* RefExpr::Eval( eval_type /* etype */ )	{	return op->RefEval( type );	}void RefExpr::Assign( Value* new_value )	{	if ( type == VAL_VAL )		{		Value* value = op->RefEval( VAL_REF );		if ( value->Deref()->IsVecRef() )			value->AssignElements( new_value );		else			value->Deref()->TakeValue( new_value );		Unref( value );		}	else		Expr::Assign( new_value );	}void RefExpr::Describe( ostream& s ) const	{	if ( type == VAL_CONST )		s << "const ";	else if ( type == VAL_REF )		s << "ref ";	else		s << "val ";	op->Describe( s );	}RangeExpr::RangeExpr( Expr* op1, Expr* op2 ) : BinaryExpr(op1, op2, ":")	{	}Value* RangeExpr::Eval( eval_type /* etype */ )	{	const Value* left_val = left->ReadOnlyEval();	const Value* right_val = right->ReadOnlyEval();	Value* result;	if ( ! left_val->IsNumeric() || ! right_val->IsNumeric() )		{		error->Report( "non-numeric value in", this );		result = error_value();		}	else if ( left_val->Length() > 1 || right_val->Length() > 1 )		{		error->Report( "non-scalar value in", this );		result = error_value();		}	else		{		int start = left_val->IntVal();		int stop = right_val->IntVal();		int direction = (start > stop) ? -1 : 1;		int num_values = (stop - start) * direction + 1;		int* range = new int[num_values];		int i;		int index = 0;		if ( direction < 0 )			for ( i = start; i >= stop; --i )				range[index++] = i;		else			for ( i = start; i <= stop; ++i )				range[index++] = i;		result = new Value( range, num_values );		}	left->ReadOnlyDone( left_val );	right->ReadOnlyDone( right_val );	return result;	}CallExpr::CallExpr( Expr* func, parameter_list* args_args )    : UnaryExpr(func, "func()")	{	args = args_args;	}Value* CallExpr::Eval( eval_type etype )	{	const Value* func = op->ReadOnlyEval();	Func* func_val = func->FuncVal();	Value* result = 0;	if ( ! func_val || ! (result = func_val->Call( args, etype )) )		{		if ( etype != EVAL_SIDE_EFFECTS )			result = error_value();		}	op->ReadOnlyDone( func );	return result;	}void CallExpr::SideEffectsEval()	{	Value* result = Eval( EVAL_SIDE_EFFECTS );	if ( result )		{		warn->Report( "function return value ignored" );		Unref( result );		}	}void CallExpr::Describe( ostream& s ) const	{	op->Describe( s );	s << "(";	loop_over_list( *args, i )		{		if ( i > 0 )			s << ", ";		(*args)[i]->Describe( s );		}	s << ")";	}SendEventExpr::SendEventExpr( EventDesignator* arg_sender,				parameter_list* arg_args,				int arg_is_request_reply ) : Expr("->")	{	sender = arg_sender;	args = arg_args;	is_request_reply = arg_is_request_reply;	}Value* SendEventExpr::Eval( eval_type etype )	{	Value* result = sender->SendEvent( args, is_request_reply );	if ( etype == EVAL_SIDE_EFFECTS )		{		Unref( result );		return 0;		}	else		return result;	}void SendEventExpr::SideEffectsEval()	{	if ( Eval( EVAL_SIDE_EFFECTS ) )		fatal->Report(	"value unexpectedly returned in SendEventExpr::SideEffectsEval" );	}void SendEventExpr::Describe( ostream& s ) const	{	if ( is_request_reply )		s << "request ";	sender->Describe( s );	s << "->(";	describe_parameter_list( args, s );	s << ")";	}LastEventExpr::LastEventExpr( Sequencer* arg_sequencer,				last_event_type arg_type ) : Expr("$last_event")	{	sequencer = arg_sequencer;	type = arg_type;	}Value* LastEventExpr::Eval( eval_type etype )	{	Notification* n = sequencer->LastNotification();	if ( ! n )		{		warn->Report( this, ": no events have been received" );		return error_value();		}	Value* result;	switch ( type )		{		case EVENT_AGENT:			result = n->notifier->AgentRecord();			if ( etype == EVAL_COPY )				result = copy_value( result );			else				Ref( result );			break;		case EVENT_NAME:			result = new Value( n->field );			break;		case EVENT_VALUE:			result = n->value;			if ( etype == EVAL_COPY )				result = copy_value( result );			else				Ref( result );			break;		default:			fatal->Report( "bad type in LastEventExpr::Eval" );		}	return result;	}Value* LastEventExpr::RefEval( value_type val_type )	{	Notification* n = sequencer->LastNotification();	if ( ! n )		{		warn->Report( this, ": no events have been received" );		return error_value();		}	Value* result;	if ( type == EVENT_AGENT )		result = new Value( n->notifier->AgentRecord(), val_type );	else if ( type == EVENT_NAME )		result = new Value( n->field );	else if ( type == EVENT_VALUE )		{		if ( val_type == VAL_REF && n->value->IsConst() )			warn->Report( this, " is a \"const\" reference" );		result = new Value( n->value, val_type );		}	else		fatal->Report( "bad type in LastEventExpr::RefEval" );	return result;	}void LastEventExpr::Describe( ostream& s ) const	{	if ( type == EVENT_AGENT )		s << "$agent";	else if ( type == EVENT_NAME )		s << "$name";	else if ( type == EVENT_VALUE )		s << "$value";	else		s << "$weird";	}void describe_expr_list( const expr_list* list, ostream& s )	{	if ( list )		loop_over_list( *list, i )			{			if ( i > 0 )				s << ", ";			if ( (*list)[i] )				(*list)[i]->Describe( s );			}	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -