added JUMP2_FORWARD and JUMP2_BACKWARD
This commit is contained in:
		@ -1499,7 +1499,6 @@ static int emit_single_param_instruction (stix_t* stix, int cmd, stix_oow_t para
 | 
			
		||||
		case BCODE_JUMP_BACKWARD_0:
 | 
			
		||||
		case BCODE_JUMP_IF_TRUE_0:
 | 
			
		||||
		case BCODE_JUMP_IF_FALSE_0:
 | 
			
		||||
		case BCODE_JUMP_BY_OFFSET_0:
 | 
			
		||||
			if (param_1 < 4)
 | 
			
		||||
			{
 | 
			
		||||
				bc = (stix_byte_t)(cmd & 0xFC) | (stix_byte_t)param_1;
 | 
			
		||||
@ -1511,6 +1510,11 @@ static int emit_single_param_instruction (stix_t* stix, int cmd, stix_oow_t para
 | 
			
		||||
				bc = cmd | 0x80;
 | 
			
		||||
				goto write_long;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		case BCODE_JUMP2_FORWARD:
 | 
			
		||||
		case BCODE_JUMP2_BACKWARD:
 | 
			
		||||
			bc = cmd;
 | 
			
		||||
			goto write_long;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	stix->errnum = STIX_EINVAL;
 | 
			
		||||
@ -2503,21 +2507,35 @@ printf ("\treturn_from_block\n");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	block_code_size = stix->c->mth.code.len - jump_inst_pos - (STIX_BCODE_LONG_PARAM_SIZE + 1);
 | 
			
		||||
	if (block_code_size > MAX_CODE_BLKCODE)
 | 
			
		||||
	if (block_code_size > MAX_CODE_JUMP * 2)
 | 
			
		||||
	{
 | 
			
		||||
/* TOOD: increate the max block code size and 
 | 
			
		||||
 * if it exceedes the limit for BCODE_JUMP_FORWARD_X, switch to BECODE_JUMP_BY_OFFSET */
 | 
			
		||||
		set_syntax_error (stix, STIX_SYNERR_BLKFLOOD, &block_loc, STIX_NULL); 
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
	else 
 | 
			
		||||
	{
 | 
			
		||||
		stix_size_t jump_offset;
 | 
			
		||||
 | 
			
		||||
		if (block_code_size > MAX_CODE_JUMP)
 | 
			
		||||
		{
 | 
			
		||||
printf ("\tfixed jump to jump2\n");
 | 
			
		||||
			stix->c->mth.code.ptr[jump_inst_pos] = BCODE_JUMP2_FORWARD;
 | 
			
		||||
			jump_offset = block_code_size - MAX_CODE_JUMP;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			jump_offset = block_code_size;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
printf ("\tfixed jump offset to %u\n", (unsigned int)jump_offset);
 | 
			
		||||
 | 
			
		||||
	/* note that the jump offset is a signed number */
 | 
			
		||||
	#if (STIX_BCODE_LONG_PARAM_SIZE == 2)
 | 
			
		||||
	stix->c->mth.code.ptr[jump_inst_pos + 1] = block_code_size >> 8;
 | 
			
		||||
	stix->c->mth.code.ptr[jump_inst_pos + 2] = ((stix_int16_t)block_code_size & 0xFF);
 | 
			
		||||
		stix->c->mth.code.ptr[jump_inst_pos + 1] = jump_offset >> 8;
 | 
			
		||||
		stix->c->mth.code.ptr[jump_inst_pos + 2] = jump_offset & 0xFF;
 | 
			
		||||
	#else
 | 
			
		||||
	stix->c->mth.code.ptr[jump_inst_pos + 1] = block_code_size ;
 | 
			
		||||
		stix->c->mth.code.ptr[jump_inst_pos + 1] = jump_offset;
 | 
			
		||||
	#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* restore the temporary count */
 | 
			
		||||
	stix->c->mth.tmprs.len = saved_tmprs_len;
 | 
			
		||||
 | 
			
		||||
@ -728,6 +728,58 @@ static int primitive_integer_sub (stix_t* stix, stix_ooi_t nargs)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int primitive_integer_mul (stix_t* stix, stix_ooi_t nargs)
 | 
			
		||||
{
 | 
			
		||||
	stix_ooi_t tmp;
 | 
			
		||||
	stix_oop_t rcv, arg;
 | 
			
		||||
 | 
			
		||||
	STIX_ASSERT (nargs == 1);
 | 
			
		||||
 | 
			
		||||
	rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
 | 
			
		||||
	arg = ACTIVE_STACK_GET(stix, stix->sp);
 | 
			
		||||
 | 
			
		||||
	if (STIX_OOP_IS_SMINT(rcv) && STIX_OOP_IS_SMINT(arg))
 | 
			
		||||
	{
 | 
			
		||||
		tmp = STIX_OOP_TO_SMINT(rcv) * STIX_OOP_TO_SMINT(arg);
 | 
			
		||||
		/* TODO: check overflow. if so convert it to LargeInteger */
 | 
			
		||||
 | 
			
		||||
		ACTIVE_STACK_POP (stix);
 | 
			
		||||
		ACTIVE_STACK_SETTOP (stix, STIX_OOP_FROM_SMINT(tmp));
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/* TODO: handle LargeInteger */
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int primitive_integer_eq (stix_t* stix, stix_ooi_t nargs)
 | 
			
		||||
{
 | 
			
		||||
	stix_oop_t rcv, arg;
 | 
			
		||||
 | 
			
		||||
	STIX_ASSERT (nargs == 1);
 | 
			
		||||
 | 
			
		||||
	rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
 | 
			
		||||
	arg = ACTIVE_STACK_GET(stix, stix->sp);
 | 
			
		||||
 | 
			
		||||
	if (STIX_OOP_IS_SMINT(rcv) && STIX_OOP_IS_SMINT(arg))
 | 
			
		||||
	{
 | 
			
		||||
		ACTIVE_STACK_POP (stix);
 | 
			
		||||
		if (STIX_OOP_TO_SMINT(rcv) < STIX_OOP_TO_SMINT(arg))
 | 
			
		||||
		{
 | 
			
		||||
			ACTIVE_STACK_SETTOP (stix, stix->_true);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			ACTIVE_STACK_SETTOP (stix, stix->_false);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
/* TODO: handle LargeInteger */
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int primitive_integer_lt (stix_t* stix, stix_ooi_t nargs)
 | 
			
		||||
{
 | 
			
		||||
	stix_oop_t rcv, arg;
 | 
			
		||||
@ -796,17 +848,19 @@ typedef struct primitive_t primitive_t;
 | 
			
		||||
 | 
			
		||||
static primitive_t primitives[] =
 | 
			
		||||
{
 | 
			
		||||
	{  -1,   primitive_dump                 },
 | 
			
		||||
	{   0,   primitive_new                  },
 | 
			
		||||
	{   1,   primitive_new_with_size        },
 | 
			
		||||
	{   0,   primitive_basic_size           },
 | 
			
		||||
	{   1,   primitive_basic_at             },
 | 
			
		||||
	{   2,   primitive_basic_at_put         },
 | 
			
		||||
	{  -1,   primitive_block_context_value  },
 | 
			
		||||
	{   1,   primitive_integer_add          },
 | 
			
		||||
	{   1,   primitive_integer_sub          },
 | 
			
		||||
	{   1,   primitive_integer_lt           },
 | 
			
		||||
	{   1,   primitive_integer_gt           }
 | 
			
		||||
	{  -1,   primitive_dump                 }, /* 0 */
 | 
			
		||||
	{   0,   primitive_new                  }, /* 1 */
 | 
			
		||||
	{   1,   primitive_new_with_size        }, /* 2 */
 | 
			
		||||
	{   0,   primitive_basic_size           }, /* 3 */
 | 
			
		||||
	{   1,   primitive_basic_at             }, /* 4 */
 | 
			
		||||
	{   2,   primitive_basic_at_put         }, /* 5 */
 | 
			
		||||
	{  -1,   primitive_block_context_value  }, /* 6 */
 | 
			
		||||
	{   1,   primitive_integer_add          }, /* 7 */
 | 
			
		||||
	{   1,   primitive_integer_sub          }, /* 8 */
 | 
			
		||||
	{   1,   primitive_integer_mul          }, /* 9 */
 | 
			
		||||
	{   1,   primitive_integer_eq           }, /* 10 */
 | 
			
		||||
	{   1,   primitive_integer_lt           }, /* 11 */
 | 
			
		||||
	{   1,   primitive_integer_gt           }  /* 12 */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1127,7 +1181,6 @@ printf ("JUMP_BACKWARD %d\n", (int)(bcode & 0x3));
 | 
			
		||||
 | 
			
		||||
			case BCODE_JUMP_IF_TRUE_X:
 | 
			
		||||
			case BCODE_JUMP_IF_FALSE_X:
 | 
			
		||||
			case BCODE_JUMP_BY_OFFSET_X:
 | 
			
		||||
			case BCODE_JUMP_IF_TRUE_0:
 | 
			
		||||
			case BCODE_JUMP_IF_TRUE_1:
 | 
			
		||||
			case BCODE_JUMP_IF_TRUE_2:
 | 
			
		||||
@ -1136,13 +1189,21 @@ printf ("JUMP_BACKWARD %d\n", (int)(bcode & 0x3));
 | 
			
		||||
			case BCODE_JUMP_IF_FALSE_1:
 | 
			
		||||
			case BCODE_JUMP_IF_FALSE_2:
 | 
			
		||||
			case BCODE_JUMP_IF_FALSE_3:
 | 
			
		||||
			case BCODE_JUMP_BY_OFFSET_0:
 | 
			
		||||
			case BCODE_JUMP_BY_OFFSET_1:
 | 
			
		||||
			case BCODE_JUMP_BY_OFFSET_2:
 | 
			
		||||
			case BCODE_JUMP_BY_OFFSET_3:
 | 
			
		||||
printf ("<<<<<<<<<<<<<< JUMP NOT IMPLEMENTED YET >>>>>>>>>>>> \n");
 | 
			
		||||
stix->errnum = STIX_ENOIMPL;
 | 
			
		||||
return -1;
 | 
			
		||||
 | 
			
		||||
			case BCODE_JUMP2_FORWARD:
 | 
			
		||||
				FETCH_PARAM_CODE_TO (stix, b1);
 | 
			
		||||
printf ("JUMP2_FORWARD %d\n", (int)b1);
 | 
			
		||||
				stix->ip += MAX_CODE_JUMP + b1;
 | 
			
		||||
				break;
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			case BCODE_JUMP2_BACKWARD:
 | 
			
		||||
				FETCH_PARAM_CODE_TO (stix, b1);
 | 
			
		||||
printf ("JUMP2_BACKWARD %d\n", (int)b1);
 | 
			
		||||
				stix->ip -= MAX_CODE_JUMP + b1;
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			/* -------------------------------------------------------- */
 | 
			
		||||
 | 
			
		||||
@ -43,7 +43,6 @@
 | 
			
		||||
#define STIX_DEBUG_GC_001  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <stdio.h> /* TODO: delete these header inclusion lines */
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
@ -477,7 +476,7 @@ struct stix_compiler_t
 | 
			
		||||
#	define MAX_CODE_NBLKARGS            (0xFFu)
 | 
			
		||||
#	define MAX_CODE_NBLKTMPRS           (0xFFu)
 | 
			
		||||
#	define MAX_CODE_PRIMNO              (0xFFFFu)
 | 
			
		||||
#	define MAX_CODE_JUMP                (0xFF)
 | 
			
		||||
#	define MAX_CODE_JUMP                (0xFFu)
 | 
			
		||||
#elif defined(STIX_BCODE_LONG_PARAM_SIZE) && (STIX_BCODE_LONG_PARAM_SIZE == 2)
 | 
			
		||||
#	define MAX_CODE_INDEX               (0xFFFFu)
 | 
			
		||||
#	define MAX_CODE_NTMPRS              (0xFFFFu)
 | 
			
		||||
@ -485,14 +484,11 @@ struct stix_compiler_t
 | 
			
		||||
#	define MAX_CODE_NBLKARGS            (0xFFFFu)
 | 
			
		||||
#	define MAX_CODE_NBLKTMPRS           (0xFFFFu)
 | 
			
		||||
#	define MAX_CODE_PRIMNO              (0xFFFFu)
 | 
			
		||||
#	define MAX_CODE_JUMP                (0xFFFF)
 | 
			
		||||
#	define MAX_CODE_JUMP                (0xFFFFu)
 | 
			
		||||
#else
 | 
			
		||||
#	error Unsupported STIX_BCODE_LONG_PARAM_SIZE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define MAX_CODE_BLKCODE             MAX_CODE_JUMP
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
----------------------------------------------------------------------------------------------------------------
 | 
			
		||||
@ -527,8 +523,8 @@ SHORT INSTRUCTION CODE                                        LONG INSTRUCTION C
 | 
			
		||||
72-75    0100 10XX JUMP_BACKWARD                              200  1100 1000 XXXXXXXX JUMP_BACKWARD_X
 | 
			
		||||
76-79    0100 11XX JUMP_IF_TRUE                               204  1100 1100 XXXXXXXX JUMP_IF_TRUE_X
 | 
			
		||||
80-83    0101 00XX JUMP_IF_FALSE                              208  1101 0000 XXXXXXXX JUMP_IF_FALSE_X
 | 
			
		||||
84-87    0101 01XX JUMP_BY_OFFSET                             212  1101 0100 XXXXXXXX JUMP_BY_OFFSET_X
 | 
			
		||||
# for JUMP_BY_OFFSET, XX is an index to literal frame pointing to a small integer.
 | 
			
		||||
 | 
			
		||||
84-87    0101 01XX UNUSED
 | 
			
		||||
 | 
			
		||||
                                                                        vv
 | 
			
		||||
88-91    0101 10XX YYYYYYYY STORE_INTO_CTXTEMPVAR             216  1101 1000 XXXXXXXX YYYYYYYY STORE_INTO_CTXTEMPVAR_X        (bit 3 on, bit 2 off)
 | 
			
		||||
@ -659,15 +655,12 @@ enum stix_bcode_t
 | 
			
		||||
	BCODE_JUMP_IF_TRUE_2           = 0x4E,
 | 
			
		||||
	BCODE_JUMP_IF_TRUE_3           = 0x4F,
 | 
			
		||||
 | 
			
		||||
	BCODE_JUMP_IF_FALSE_0       = 0x50,
 | 
			
		||||
	BCODE_JUMP_IF_FALSE_1       = 0x51,
 | 
			
		||||
	BCODE_JUMP_IF_FALSE_2       = 0x52,
 | 
			
		||||
	BCODE_JUMP_IF_FALSE_3       = 0x53,
 | 
			
		||||
	BCODE_JUMP_IF_FALSE_0          = 0x50, /* 80 */
 | 
			
		||||
	BCODE_JUMP_IF_FALSE_1          = 0x51, /* 81 */
 | 
			
		||||
	BCODE_JUMP_IF_FALSE_2          = 0x52, /* 82 */
 | 
			
		||||
	BCODE_JUMP_IF_FALSE_3          = 0x53, /* 83 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	BCODE_JUMP_BY_OFFSET_0      = 0x54,
 | 
			
		||||
	BCODE_JUMP_BY_OFFSET_1      = 0x55,
 | 
			
		||||
	BCODE_JUMP_BY_OFFSET_2      = 0x56,
 | 
			
		||||
	BCODE_JUMP_BY_OFFSET_3      = 0x57,
 | 
			
		||||
 | 
			
		||||
	BCODE_STORE_INTO_CTXTEMPVAR_0  = 0x58, /* 88 */
 | 
			
		||||
	BCODE_STORE_INTO_CTXTEMPVAR_1  = 0x59, /* 89 */
 | 
			
		||||
@ -729,7 +722,7 @@ enum stix_bcode_t
 | 
			
		||||
	BCODE_JUMP_BACKWARD_X          = 0xC8, /* 200 */
 | 
			
		||||
	BCODE_JUMP_IF_TRUE_X           = 0xCC, /* 204 */
 | 
			
		||||
	BCODE_JUMP_IF_FALSE_X          = 0xD0, /* 208 */
 | 
			
		||||
	BCODE_JUMP_BY_OFFSET_X         = 0xD4, /* 212 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	BCODE_STORE_INTO_CTXTEMPVAR_X  = 0xD8, /* 216 */
 | 
			
		||||
	BCODE_POP_INTO_CTXTEMPVAR_X    = 0xDC, /* 220 */
 | 
			
		||||
@ -743,15 +736,18 @@ enum stix_bcode_t
 | 
			
		||||
	BCODE_SEND_MESSAGE_TO_SUPER_X  = 0xF4, /* 244 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	BCODE_PUSH_RECEIVER            = 0x81,
 | 
			
		||||
	BCODE_PUSH_NIL                 = 0x82,
 | 
			
		||||
	BCODE_PUSH_TRUE                = 0x83,
 | 
			
		||||
	BCODE_PUSH_FALSE               = 0x84,
 | 
			
		||||
	BCODE_PUSH_CONTEXT             = 0x85,
 | 
			
		||||
	BCODE_PUSH_NEGONE              = 0x86,
 | 
			
		||||
	BCODE_PUSH_ZERO                = 0x87,
 | 
			
		||||
	BCODE_PUSH_ONE                 = 0x89,
 | 
			
		||||
	BCODE_PUSH_TWO                 = 0x91,
 | 
			
		||||
	BCODE_JUMP2_FORWARD            = 0xC5, /* 197 */
 | 
			
		||||
	BCODE_JUMP2_BACKWARD           = 0xC9, /* 201 */
 | 
			
		||||
 | 
			
		||||
	BCODE_PUSH_RECEIVER            = 0x81, /* 129 */
 | 
			
		||||
	BCODE_PUSH_NIL                 = 0x82, /* 130 */
 | 
			
		||||
	BCODE_PUSH_TRUE                = 0x83, /* 131 */
 | 
			
		||||
	BCODE_PUSH_FALSE               = 0x84, /* 132 */
 | 
			
		||||
	BCODE_PUSH_CONTEXT             = 0x85, /* 133 */
 | 
			
		||||
	BCODE_PUSH_NEGONE              = 0x86, /* 134 */
 | 
			
		||||
	BCODE_PUSH_ZERO                = 0x87, /* 135 */
 | 
			
		||||
	BCODE_PUSH_ONE                 = 0x89, /* 137 */
 | 
			
		||||
	BCODE_PUSH_TWO                 = 0x8A, /* 138 */
 | 
			
		||||
 | 
			
		||||
	/* UNUSED 0xE8 - 0xF8 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,375 +1,5 @@
 | 
			
		||||
#class Stix(nil)
 | 
			
		||||
{
 | 
			
		||||
	#dcl(#class) sysdic.
 | 
			
		||||
 | 
			
		||||
	#method(#class) yourself
 | 
			
		||||
	{
 | 
			
		||||
		^self.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method yourself
 | 
			
		||||
	{
 | 
			
		||||
		^self.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method(#class) dump
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 0>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method dump
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 0>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method(#class) new
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 1>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method(#class) new: anInteger
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 2>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method basicSize
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 3>
 | 
			
		||||
		^0
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	#method basicAt: anInteger
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 4>
 | 
			
		||||
		## self error: 'out of range'.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method basicAt: anInteger put: anObject
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 5>
 | 
			
		||||
		## self error: 'out of range'.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method badReturnError
 | 
			
		||||
	{
 | 
			
		||||
		## TODO: implement this
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method mustBeBoolean
 | 
			
		||||
	{
 | 
			
		||||
		## TODO: implement this
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method doesNotUnderstand: aMessageSymbol
 | 
			
		||||
	{
 | 
			
		||||
		## TODO: implement this
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method error: anErrorString
 | 
			
		||||
	{
 | 
			
		||||
		anErrorString dump.
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class Object(Stix)
 | 
			
		||||
{
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class NilObject(Stix)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class(#pointer) Class(Stix)
 | 
			
		||||
{
 | 
			
		||||
	#dcl spec selfspec superclass subclasses name instvars classvars classinstvars instmthdic classmthdic.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#class Magnitude(Object)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class Association(Magnitude)
 | 
			
		||||
{
 | 
			
		||||
	#dcl key value.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class Character(Magnitude)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class Number(Magnitude)
 | 
			
		||||
{
 | 
			
		||||
	#method add: aNumber
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 7>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method + aNumber
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 7>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method - aNumber
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 8>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method < aNumber
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 9>
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class SmallInteger(Number)
 | 
			
		||||
{
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class Boolean(Object)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class True(Boolean)
 | 
			
		||||
{
 | 
			
		||||
	#method ifTrue: trueBlock ifFalse: falseBlock
 | 
			
		||||
	{
 | 
			
		||||
		^trueBlock value.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method ifTrue: trueBlock
 | 
			
		||||
	{
 | 
			
		||||
		^trueBlock value.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method ifFalse: falseBlock
 | 
			
		||||
	{
 | 
			
		||||
		^nil.
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class False(Boolean)
 | 
			
		||||
{
 | 
			
		||||
	#method ifTrue: trueBlock ifFalse: falseBlock
 | 
			
		||||
	{
 | 
			
		||||
		^falseBlock value.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method ifTrue: trueBlock
 | 
			
		||||
	{
 | 
			
		||||
		^nil.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method ifFalse: falseBlock
 | 
			
		||||
	{
 | 
			
		||||
		^falseBlock value.
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class Collection(Object)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class(#byte) ByteArray(Collection)
 | 
			
		||||
{
 | 
			
		||||
	#method at: anInteger
 | 
			
		||||
	{
 | 
			
		||||
		^self basicAt: anInteger.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method at: anInteger put: aValue
 | 
			
		||||
	{
 | 
			
		||||
		^self basicAt: anInteger put: aValue.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class(#pointer) Array(Collection)
 | 
			
		||||
{
 | 
			
		||||
	#method at: anInteger
 | 
			
		||||
	{
 | 
			
		||||
		^self basicAt: anInteger.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method at: anInteger put: aValue
 | 
			
		||||
	{
 | 
			
		||||
		^self basicAt: anInteger put: aValue.
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class(#character) String(Array)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class(#character) Symbol(Array)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#class Set(Collection)
 | 
			
		||||
{
 | 
			
		||||
	#dcl tally bucket.
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class SymbolSet(Set)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class Dictionary(Set)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class SystemDictionary(Dictionary)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class MethodDictionary(Dictionary)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class(#pointer) Context(Stix)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class(#pointer) MethodContext(Context)
 | 
			
		||||
{
 | 
			
		||||
	#dcl sender ip sp ntmprs method receiver home origin.
 | 
			
		||||
 | 
			
		||||
	#method pc
 | 
			
		||||
	{
 | 
			
		||||
		^ip
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method pc: anInteger
 | 
			
		||||
	{
 | 
			
		||||
		ip := anInteger.
 | 
			
		||||
		"sp := sp - 1."  "whould this always work??? "
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method sp
 | 
			
		||||
	{
 | 
			
		||||
		^sp.
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
	#method sp: anInteger
 | 
			
		||||
	{
 | 
			
		||||
		sp := anInteger.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method pc: aPC sp: aSP
 | 
			
		||||
	{
 | 
			
		||||
		ip := aPC.
 | 
			
		||||
		sp := aSP.
 | 
			
		||||
		##sp := sp - 1.
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class(#pointer) BlockContext(Context)
 | 
			
		||||
{
 | 
			
		||||
	#dcl caller ip sp ntmprs nargs source  home origin.
 | 
			
		||||
 | 
			
		||||
	#method value
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 6>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method value: a 
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 6>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method value: a value: b
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 6>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method value: a value: b value: c
 | 
			
		||||
	{
 | 
			
		||||
		<primitive: 6>
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method whileTrue: aBlock
 | 
			
		||||
	{
 | 
			
		||||
## http://stackoverflow.com/questions/2500483/is-there-a-way-in-a-message-only-language-to-define-a-whiletrue-message-without
 | 
			
		||||
 | 
			
		||||
## ----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
##		^(self value) ifTrue: [aBlock value. self whileTrue: aBlock].
 | 
			
		||||
 | 
			
		||||
## ----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
		## less block context before whileTrue: is recursively sent.
 | 
			
		||||
		## whileTrue: is sent in a method context.
 | 
			
		||||
##		(self value) ifFalse: [^nil].
 | 
			
		||||
##		aBlock value. 
 | 
			
		||||
##		self whileTrue: aBlock.
 | 
			
		||||
 | 
			
		||||
## ----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
## ----------------------------------------------------------------------------
 | 
			
		||||
		| pc sp xsp |
 | 
			
		||||
 | 
			
		||||
		sp := thisContext sp.
 | 
			
		||||
		sp := sp - 1. "decrement sp by 1 becuase thisContext pushed above affects the sp method"
 | 
			
		||||
		pc := thisContext pc.
 | 
			
		||||
		self value ifFalse: [ ^nil "^self" ].
 | 
			
		||||
		aBlock value.
 | 
			
		||||
		##thisContext pc: pc - 3 sp: sp.
 | 
			
		||||
		##thisContext pc: pc + 2 sp: sp.   
 | 
			
		||||
		thisContext pc: pc + 1 sp: sp.   
 | 
			
		||||
		## this +2 or - 3 above is dependent on the byte code instruction size used for 'store'  
 | 
			
		||||
		## +2 to skip STORE_INTO_TEMP(pc) and POP_STACKTOP.
 | 
			
		||||
		## TODO: make it independent of the byte code size 
 | 
			
		||||
 | 
			
		||||
## ----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
##        #<label>:
 | 
			
		||||
##		thisContext pc: #<label> sp: sp.
 | 
			
		||||
##
 | 
			
		||||
##		| pc |
 | 
			
		||||
##		pc := thisContext pc.
 | 
			
		||||
##		^self value ifTrue: [aBlock value. thisContext pc: pc]
 | 
			
		||||
 | 
			
		||||
## ----------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
##		self value ifTrue: [ aBlock value. thisContext restart. ].
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method pc
 | 
			
		||||
	{
 | 
			
		||||
		^ip
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method pc: anInteger
 | 
			
		||||
	{
 | 
			
		||||
		ip := anInteger.
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	#method sp
 | 
			
		||||
	{
 | 
			
		||||
		^sp
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method sp: anInteger
 | 
			
		||||
	{
 | 
			
		||||
		sp := anInteger.
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	#method restart
 | 
			
		||||
	{
 | 
			
		||||
		ip := source pc.
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#class(#pointer) CompiledMethod(Object)
 | 
			
		||||
{
 | 
			
		||||
	#dcl owner preamble ntmprs nargs code source.
 | 
			
		||||
}
 | 
			
		||||
#include 'Stix.st'
 | 
			
		||||
 | 
			
		||||
#################################################################
 | 
			
		||||
## MAIN
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user