Пример #1
0
Ref * sysVectorAppend( Ref * pc, class MachineClass * vm ) {

	//	Variables here would be unaffected by a GC.
	unsigned long N;
	unsigned long lhs_n;
	unsigned long rhs_n;

	if ( vm->count != 2 ) throw Ginger::Mishap( "Wrong number of arguments in vectorAppend" );

	{
	
		//	May need to GC so leave on the stack.
		Ref rhs = vm->fastPeek();
		Ref lhs = vm->fastPeek( 1 );
		
		if ( !IsObj( lhs ) || !IsObj( rhs ) ) throw Ginger::Mishap( "Invalid arguments in vectorAppend" );
		
		Ref * lhs_K = RefToPtr4( lhs );
		Ref * rhs_K = RefToPtr4( rhs );
		Ref lhs_key = *lhs_K;
		Ref rhs_key = *rhs_K;
		
		if ( lhs_key != rhs_key || !IsSimpleKey( lhs_key ) || KindOfSimpleKey( lhs_key ) != VECTOR_KIND ) throw Ginger::Mishap( "Invalid arguments in vectorAppend" );
	
		lhs_n = sizeAfterKeyOfVectorLayout( lhs_K );
		rhs_n = sizeAfterKeyOfVectorLayout( rhs_K );
		N = lhs_n + rhs_n;
	
	}
	
	XfrClass xfr( vm->heap().preflight( pc, N + 2 ) );

	//	No risk of GC so safe to pop.
	Ref * rhs_K = RefToPtr4( vm->fastPop() );
	Ref * lhs_K = RefToPtr4( vm->fastPop() );

	xfr.xfrRef( ULongToSmall( N ) );
	xfr.setOrigin();
	xfr.xfrRef( *lhs_K );
	xfr.xfrCopy( lhs_K + 1, lhs_n );
	xfr.xfrCopy( rhs_K + 1, rhs_n );

	vm->fastPush( xfr.makeRef() );
	return pc;

}
Пример #2
0
Ref * sysVectorLength( Ref *pc, class MachineClass * vm ) {
	if ( vm->count != 1 ) throw Ginger::Mishap( "Wrong number of arguments for vectorLength" );
	Ref r = vm->fastPeek();
	if ( !IsVector( r ) ) throw Ginger::Mishap( "Argument mismatch for vectorLength" );
	Ref * obj_K = RefToPtr4( r );
	
	vm->fastPeek() = LongToSmall( sizeAfterKeyOfVectorLayout( obj_K ) );
	return pc;
}
Пример #3
0
//
//	This computes obj_C = obj_Z - obj_A from obj_K
//
unsigned long lengthAfterObjectKey( Ref * obj_K ) {
	//	Keys fall into the following categories: FunctionKey, SimpleKey, Pointer to Keys
	Ref key = *obj_K;
	if ( IsSimpleKey( key ) ) {
		switch ( LayoutOfSimpleKey( key ) ) {
		//switch ( KindOfSimpleKey( key ) ) {
			case RECORD_LAYOUT: {
			//case MAP_KIND:
			//case PAIR_KIND:
			//case RECORD_KIND: {
				assert( LayoutOfSimpleKey( key ) == RECORD_LAYOUT );
				assert( KindOfSimpleKey( key ) == PAIR_KIND || KindOfSimpleKey( key ) == MAP_KIND  || KindOfSimpleKey( key ) == RECORD_KIND );
				return sizeAfterKeyOfRecordLayout( obj_K );
				break;
			}
			case VECTOR_LAYOUT: {
			//case VECTOR_KIND: {
				assert( LayoutOfSimpleKey( key ) == VECTOR_LAYOUT );
				assert( KindOfSimpleKey( key ) == VECTOR_KIND );
				return sizeAfterKeyOfVectorLayout( obj_K );
				break;
			}
			case MIXED_LAYOUT: {
				assert( LayoutOfSimpleKey( key ) == MIXED_LAYOUT );
				return sizeAfterKeyOfMixedLayout( obj_K );
				break;
			}
			case STRING_LAYOUT: {
			//case STRING_KIND: {
				assert( LayoutOfSimpleKey( key ) == STRING_LAYOUT );
				assert( KindOfSimpleKey( key ) == STRING_KIND );
				return sizeAfterKeyOfStringLayout( obj_K );
				break;
			}
			case WRECORD_LAYOUT: {
				assert( LayoutOfSimpleKey( key ) == WRECORD_LAYOUT );
				return sizeAfterKeyOfWRecordLayout( obj_K );
				break;
			}
			default: 
				throw UnreachableError();
		}
	} else if ( IsFunctionKey( key ) ) {
		return sizeAfterKeyOfFn( obj_K );
	} else if ( IsObj( key ) ) {
		return sizeAfterKeyOfInstance( obj_K );
	} else {
		throw Ginger::Mishap( "Cannot take length of this" );
	}
}
Пример #4
0
Ref * sysVectorExplode( Ref *pc, class MachineClass * vm ) {
	if ( vm->count != 1 ) throw Ginger::Mishap( "Wrong number of arguments for vectorExplode" );
	
	Ref r = vm->fastPop();
	
	if ( !IsVector( r ) ) throw Ginger::Mishap( "Argument mismatch for vectorExplode" );
	
	Ref *obj_K = RefToPtr4( r );
	unsigned long n = sizeAfterKeyOfVectorLayout( obj_K );
	vm->checkStackRoom( n );
	memcpy( vm->vp + 1, obj_K + 1, n * sizeof( Ref ));
	vm->vp += n;
	
	return pc;
}
Пример #5
0
Ref * sysFastVectorLength( Ref *pc, class MachineClass * vm ) {
	Ref r = vm->fastPeek();
	Ref * obj_K = RefToPtr4( r );
	vm->fastPeek() = LongToSmall( sizeAfterKeyOfVectorLayout( obj_K ) );
	return pc;
}