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

📄 expr.cc

📁 This Source-Navigator, an IDE for C/C++/Fortran/Java/Tcl/PHP/Python and a host of other languages.
💻 CC
📖 第 1 页 / 共 3 页
字号:
// $Header: /cvsroot/sourcenav/src/snavigator/demo/c++_demo/glish/Expr.cc,v 1.1.1.1 2002/04/18 23:35:24 mdejong Exp $#include <stream.h>#include <string.h>#include <stdlib.h>#include "Reporter.h"#include "Sequencer.h"#include "Expr.h"#include "Agent.h"#include "Func.h"void Expr::SideEffectsEval()	{	const Value* v = ReadOnlyEval();	if ( v )		{		glish_type t = v->Type();		ReadOnlyDone( v );		if ( t != TYPE_FUNC )			warn->Report( "expression value ignored:", this );		}	}Value* Expr::RefEval( value_type val_type )	{	Value* value = CopyEval();	Value* result;	if ( val_type == VAL_VAL )		{		result = value;		Ref( value );		}	else		result = new Value( value, val_type );	if ( val_type == VAL_REF && value->IsConst() )		warn->Report( "\"const\" reference converted to \"ref\" in",				this );	Unref( value );	// result is now the only pointer to value	return result;	}void Expr::Assign( Value* /* new_value */ )	{	error->Report( this, "is not a valid target for assignment" );	}int Expr::Invisible() const	{	return 0;	}Value* Expr::CopyOrRefValue( const Value* value, eval_type etype )	{	if ( etype == EVAL_COPY )		return copy_value( value );	else if ( etype == EVAL_READ_ONLY )		{		Value* result = (Value*) value;		Ref( result );		return result;		}	else		{		// EVAL_SIDE_EFFECTS should've been caught earlier; making it		// this far indicates that the function erroneously overrode		// SideEffectsEval().		fatal->Report( "bad eval_type in Expr::CopyOrRefValue" );		return 0;		}	}VarExpr::VarExpr( char* var_id, scope_type var_scope, int var_offset,			Sequencer* var_sequencer ) : Expr(var_id)	{	id = var_id;	scope = var_scope;	frame_offset = var_offset;	sequencer = var_sequencer;	}VarExpr::~VarExpr()	{	delete id;	}Value* VarExpr::Eval( eval_type etype )	{	Value* value = sequencer->FrameElement( scope, frame_offset );	if ( ! value )		{		warn->Report( "uninitialized variable", this, "used" );		value = error_value();		sequencer->SetFrameElement( scope, frame_offset, value );		}	value = value->Deref();	return CopyOrRefValue( value, etype );	}Value* VarExpr::RefEval( value_type val_type )	{	Value* var = sequencer->FrameElement( scope, frame_offset );	if ( ! var )		{		// Presumably we're going to be assigning to a subelement.		var = new Value( glish_false );		sequencer->SetFrameElement( scope, frame_offset, var );		}	if ( val_type == VAL_VAL )		return copy_value( var );	if ( val_type == VAL_REF && var->IsConst() )		warn->Report( this, " is a \"const\" reference" );	return new Value( var, val_type );	}void VarExpr::Assign( Value* new_value )	{	sequencer->SetFrameElement( scope, frame_offset, new_value );	}Value* ValExpr::Eval( eval_type etype )	{	return CopyOrRefValue( val, etype );	}Value* ValExpr::RefEval( value_type val_type )	{	if ( val_type == VAL_REF && val->IsConst() )		warn->Report( this, " is a \"const\" reference" );	return new Value( val, val_type );	}ConstExpr::ConstExpr( const Value* value ) : Expr("constant")	{	const_value = value;	}Value* ConstExpr::Eval( eval_type etype )	{	return CopyOrRefValue( const_value, etype );	}void ConstExpr::DescribeSelf( ostream& s ) const	{	const_value->DescribeSelf( s );	}UnaryExpr::UnaryExpr( Expr* operand, const char* desc ) : Expr(desc)	{	op = operand;	}void UnaryExpr::Describe( ostream& s ) const	{	DescribeSelf( s );	op->Describe( s );	}BinaryExpr::BinaryExpr( Expr* op1, Expr* op2, const char* desc )    : Expr(desc)	{	left = op1;	right = op2;	}void BinaryExpr::Describe( ostream& s ) const	{	s << "(";	left->Describe( s );	s << " ";	DescribeSelf( s );	s << " ";	right->Describe( s );	s << ")";	}NegExpr::NegExpr( Expr* operand ) : UnaryExpr( operand, "-" )	{	}Value* NegExpr::Eval( eval_type /* etype */ )	{	Value* result = op->CopyEval();	result->Negate();	return result;	}NotExpr::NotExpr( Expr* operand ) : UnaryExpr( operand, "!" )	{	}Value* NotExpr::Eval( eval_type /* etype */ )	{	Value* result = op->CopyEval();	result->Not();	return result;	}AssignExpr::AssignExpr( Expr* op1, Expr* op2 ) : BinaryExpr(op1, op2, ":=")	{	}Value* AssignExpr::Eval( eval_type etype )	{	left->Assign( right->CopyEval() );	if ( etype == EVAL_COPY )		return left->CopyEval();	else if ( etype == EVAL_READ_ONLY )		return (Value*) left->ReadOnlyEval();	else		return 0;	}void AssignExpr::SideEffectsEval()	{	if ( Eval( EVAL_SIDE_EFFECTS ) )		fatal->Report(		"value unexpected returnedly in AssignExpr::SideEffectsEval" );	}int AssignExpr::Invisible() const	{	return 1;	}OrExpr::OrExpr( Expr* op1, Expr* op2 ) : BinaryExpr(op1, op2, "||")	{	}Value* OrExpr::Eval( eval_type etype )	{	const Value* left_value = left->ReadOnlyEval();	if ( left_value->BoolVal() )		{		if ( etype == EVAL_COPY )			{			Value* result = copy_value( left_value );			left->ReadOnlyDone( left_value );			return result;			}		else			return (Value*) left_value;		}	else		return right->Eval( etype );	}AndExpr::AndExpr( Expr* op1, Expr* op2 ) : BinaryExpr(op1, op2, "&&")	{	}Value* AndExpr::Eval( eval_type etype )	{	const Value* left_value = left->ReadOnlyEval();	int left_is_true = left_value->BoolVal();	left->ReadOnlyDone( left_value );	if ( etype == EVAL_COPY )		{		if ( left_is_true )			return right->CopyEval();		else			return new Value( glish_false );		}	else		{		if ( left_is_true )			return (Value*) right->ReadOnlyEval();		else			return new Value( glish_false );		}	}ConstructExpr::ConstructExpr( parameter_list* arg_args ) : Expr("[construct]")	{	is_array_constructor = 1;	args = arg_args;	if ( args )		{		loop_over_list( *args, i )			{			if ( (*args)[i]->Name() )				{				if ( i > 0 && is_array_constructor )					{					error->Report(					"mixed array/record constructor: ",							this );					break;					}				is_array_constructor = 0;				}			else if ( ! is_array_constructor )				{				error->Report(					"mixed array/record constructor: ",						this );				is_array_constructor = 1;				break;				}			}		}	}Value* ConstructExpr::Eval( eval_type /* etype */ )	{	if ( ! args )		return create_record();	else if ( args->length() == 0 )		return empty_value();	else if ( is_array_constructor )		return BuildArray();	else		return BuildRecord();	}void ConstructExpr::Describe( ostream& s ) const	{	s << "[";	if ( args )		describe_parameter_list( args, s );	else		s << "=";	s << "]";	}Value* ConstructExpr::BuildArray()	{	Value* result;	typedef const Value* const_value_ptr;	int num_values = 0;	loop_over_list( *args, i )		{		Parameter* arg = (*args)[i];		if ( arg->IsEllipsis() )			num_values += (*args)[i]->NumEllipsisVals();		else			++num_values;		}	const_value_ptr* values = new const_value_ptr[num_values];	int total_length = 0;	for ( i = 0; i < args->length(); ++i )		{		Parameter* arg = (*args)[i];		if ( arg->IsEllipsis() )			{			int len = arg->NumEllipsisVals();			for ( int j = 0; j < len; ++j )				{				values[i+j] = arg->NthEllipsisVal(j)->Deref();				total_length += values[i+j]->Length();				}			}		else			{			values[i] = arg->Arg()->ReadOnlyEval();			total_length += values[i]->Length();			}		}	glish_type max_type;	if ( TypeCheck( values, num_values, max_type ) )		result = ConstructArray( values, num_values, total_length,					max_type );	else		result = error_value();	for ( i = 0; i < args->length(); ++i )		if ( ! (*args)[i]->IsEllipsis() )			(*args)[i]->Arg()->ReadOnlyDone( values[i] );	delete values;	return result;	}int ConstructExpr::TypeCheck( const Value* values[], int num_values,					glish_type& max_type )	{	if ( num_values == 0 )		{		max_type = TYPE_BOOL;	// Compatible with the constant F		return 1;		}	for ( int i = 0; i < num_values; ++i )		{		const Value* v = values[i];		if ( v->Length() > 0 && v->IsNumeric() )			return MaxNumeric( values, num_values, max_type );		}	int result = AllEquivalent( values, num_values, max_type );	if ( max_type == TYPE_RECORD )		{		error->Report( "arrays of records are not supported" );		return 0;		}	return result;	}int ConstructExpr::MaxNumeric( const Value* values[], int num_values,					glish_type& max_type )	{	const Value* v = values[0]->VecRefDeref();	if ( ! v->IsNumeric() )		{		error->Report( "non-numeric type in array constructor",				this );		return 0;		}	max_type = v->Type();	for ( int i = 1; i < num_values; ++i )		{		v = values[i]->VecRefDeref();		if ( ! v->IsNumeric() )			{			error->Report( "non-numeric type in array constructor",					this );			return 0;			}		max_type = max_numeric_type( v->Type(), max_type );		}	return 1;	}int ConstructExpr::AllEquivalent( const Value* values[], int num_values,					glish_type& max_type )	{	max_type = TYPE_BOOL;	// First pick a candidate type.	for ( int i = 0; i < num_values; ++i )		// Ignore empty arrays, as they can be any type.		if ( values[i]->Length() > 0 )			{			max_type = values[i]->VecRefDeref()->Type();			break;			}	// Now check whether all non-empty arrays conform to that type.	for ( i = 0; i < num_values; ++i )		{		const Value* v = values[i]->VecRefDeref();		if ( v->Length() > 0 && v->Type() != max_type )			{			error->Report(				"incompatible types in array constructor",					this );			return 0;			}		}	return 1;	}

⌨️ 快捷键说明

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