added PUSH_NEGONE, PUSH_ZERO, PUSH_ONE

This commit is contained in:
hyunghwan.chung 2015-06-16 04:31:28 +00:00
parent 8e143685c9
commit 13fecb4c70
3 changed files with 243 additions and 112 deletions

View File

@ -342,6 +342,74 @@ static stix_ssize_t find_word_in_string (const stix_ucs_t* haystack, const stix_
return -1;
}
#define CHAR_TO_NUM(c,base) \
((c >= '0' && c <= '9')? ((c - '0' < base)? (c - '0'): base): \
(c >= 'A' && c <= 'Z')? ((c - 'A' + 10 < base)? (c - 'A' + 10): base): \
(c >= 'a' && c <= 'z')? ((c - 'a' + 10 < base)? (c - 'a' + 10): base): base)
static int string_to_smint (stix_t* stix, stix_ucs_t* str, int base, stix_ooi_t* num)
{
/* TODO: handle floating point numbers, etc, handle radix */
int v, negsign, overflow;
const stix_uch_t* ptr, * end;
stix_oow_t value, old_value;
negsign = 0;
overflow = 0;
ptr = str->ptr,
end = str->ptr + str->len;
if (ptr < end)
{
if (*ptr == '+' || *ptr == '-')
{
negsign = *ptr - '+';
ptr++;
}
}
if (ptr >= end)
{
stix->errnum = STIX_EINVAL;
return -1;
}
value = old_value = 0;
while (ptr < end && (v = CHAR_TO_NUM(*ptr, base)) != base)
{
value = value * base + v;
if (value < old_value)
{
/* overflow must have occurred */
overflow = 1;
}
old_value = value;
ptr++;
}
if (ptr < end || overflow)
{
/* trailing garbage or overflow */
stix->errnum = STIX_EINVAL;
return -1;
}
if (negsign)
{
if (value > STIX_SMINT_MIN) return -1;
*num = value;
*num *= -1;
}
else
{
if (value > STIX_SMINT_MAX) return -1;
*num = value;
}
return 0;
}
/* ---------------------------------------------------------------------
* Tokenizer
* --------------------------------------------------------------------- */
@ -1882,13 +1950,29 @@ static int compile_block_temporaries (stix_t* stix)
static int compile_block_expression (stix_t* stix)
{
stix_size_t code_start_pos;
/*
* block-expression := "[" block-body "]"
* block-body := (block-argument* "|")? block-temporaries? method-statement*
* block-argument := ":" identifier
*/
/* TODO: GENERATE JUMP INSTRUCTION */
code_start_pos = stix->c->mth.code.len;
#if 0
if (emit_byte_instruction(stix, CODE_PUSH_CONTEXT) <= -1 ||
emit_byte_instruction(stix,
if (emit_byte_instruction(stix, CODE_NOOP) <= -1 ||
emit_byte_instruction(stix, CODE_NOOP) <= -
/* reserve space for JUMP instruction */
if (emit_byte_instruction(stix, CODE_NOOP) <= -1 ||
emit_byte_instruction(stix, CODE_NOOP) <= -1 ||
emit_byte_instruction(stix, CODE_NOOP) <= -1) return -1;
#endif
if (stix->c->tok.type == STIX_IOTOK_COLON)
{
/* block temporary variables */
@ -2047,7 +2131,6 @@ printf ("push character literal %d\n", (int)index);
emit_positional_instruction(stix, CMD_PUSH_LITERAL, index) <= -1) return -1;
printf ("push string literal %d\n", (int)index);
GET_TOKEN (stix);
break;
case STIX_IOTOK_SYMLIT:
@ -2060,16 +2143,37 @@ printf ("push symbol literal %d\n", (int)index);
case STIX_IOTOK_NUMLIT:
{
/* TODO: other types of numbers, negative numbers, etc */
/*
stix_word_t tmp;
STIX_STRTOI (tmp, stix->tok.name.buffer, STIX_NULL, 10);
literal = STIX_TO_SMALLINT(tmp);
/* TODO: proper numbeic literal handling */
stix_ooi_t tmp;
if (add_literal(stix, literal, &index) <= -1)r eturn -1;
if (string_to_smint(stix, &stix->c->tok.name, 10, &tmp) <= -1)
{
printf ("NOT IMPLEMENTED LARGE_INTEGER or ERROR?\n");
stix->errnum = STIX_ENOIMPL;
return -1;
}
else
{
switch (tmp)
{
case -1:
if (emit_byte_instruction(stix, CODE_PUSH_NEGONE) <= -1) return -1;
break;
case 0:
if (emit_byte_instruction(stix, CODE_PUSH_ZERO) <= -1) return -1;
break;
case 1:
if (emit_byte_instruction(stix, CODE_PUSH_ONE) <= -1) return -1;
break;
default:
if (add_literal(stix, STIX_OOP_FROM_SMINT(tmp), &index) <= -1) return -1;
}
}
EMIT_PUSH_LITERAL_CONSTANT (stix, index);
GET_TOKEN (stix);
*/
break;
}

View File

@ -26,32 +26,27 @@
#include "stix-prv.h"
#define LOAD_IP_AND_SP(v_ctx, v_ip, v_sp) \
do \
{ \
v_ip = STIX_OOP_TO_SMINT((v_ctx)->ip); \
v_sp = STIX_OOP_TO_SMINT((v_ctx)->sp); \
} while(0)
#define STORE_IP_AND_SP(v_ctx, v_ip, v_sp) \
do \
{ \
(v_ctx)->ip = STIX_OOP_FROM_SMINT(v_ip); \
(v_ctx)->sp = STIX_OOP_FROM_SMINT(v_sp); \
} while(0)
#define LOAD_SP(v_ctx, v_sp) \
do \
{ \
v_sp = STIX_OOP_TO_SMINT((v_ctx)->sp); \
} while(0)
#define STORE_SP(v_ctx, v_sp) \
do \
{ \
(v_ctx)->sp = STIX_OOP_FROM_SMINT(v_sp); \
#define LOAD_IP(v_ctx, v_ip) (v_ip = STIX_OOP_TO_SMINT((v_ctx)->ip))
#define STORE_IP(v_ctx, v_ip) ((v_ctx)->ip = STIX_OOP_FROM_SMINT(v_ip))
#define LOAD_SP(v_ctx, v_sp) (v_sp = STIX_OOP_TO_SMINT((v_ctx)->sp))
#define STORE_SP(v_ctx, v_sp) ((v_ctx)->sp = STIX_OOP_FROM_SMINT(v_sp))
#define LOAD_ACTIVE_IP(stix, v_ip) LOAD_IP((stix)->active_context, v_ip)
#define STORE_ACTIVE_IP(stix, v_ip) STORE_IP((stix)->active_context, v_ip)
#define LOAD_ACTIVE_SP(stix, v_sp) LOAD_SP((stix)->active_context, v_sp)
#define STORE_ACTIVE_SP(stix, v_sp) STORE_SP((stix)->active_context, v_sp)
#define STACK_PUSH(stix,v) \
do { \
++sp; \
(stix)->active_context->slot[sp] = v; \
} while (0)
#define STACK_GET(stix,v_sp) ((stix)->active_context->slot[v_sp])
#define STACK_PUT(stix,v_sp,v_obj) ((stix)->active_context->slot[v_sp] = v_obj)
static int activate_new_method (stix_t* stix, stix_oop_method_t mth, stix_ooi_t* xip, stix_ooi_t* xsp)
{
@ -159,14 +154,16 @@ static int activate_new_method (stix_t* stix, stix_oop_method_t mth, stix_ooi_t*
/* store an instruction pointer and a stack pointer to the active context
* before switching it to a new context */
STORE_IP_AND_SP (stix->active_context, *xip, sp);
STORE_ACTIVE_IP (stix, *xip);
STORE_ACTIVE_SP (stix, sp); /* note it is not *xsp */
/* swtich the active context */
stix->active_context = ctx;
/* load an instruction pointer and a stack pointer from the new active
* context */
LOAD_IP_AND_SP (stix->active_context, *xip, *xsp);
LOAD_ACTIVE_IP (stix, *xip);
LOAD_ACTIVE_SP (stix, *xsp);
printf ("<<ENTERING>>\n");
return 0;
@ -187,7 +184,7 @@ printf ("] in ");
cls = (stix_oop_class_t)STIX_CLASSOF(stix, receiver);
if ((stix_oop_t)cls == stix->_class)
{
/* receiver is a class receiverect */
/* receiver is a class object */
c = receiver;
dic_no = STIX_CLASS_MTHDIC_CLASS;
printf ("class method dictioanry ====\n");
@ -211,6 +208,7 @@ printf ("instance method dictioanry ====\n");
do
{
mthdic = ((stix_oop_class_t)c)->mthdic[dic_no];
STIX_ASSERT (mthdic != stix->_nil);
STIX_ASSERT (STIX_CLASSOF(stix, mthdic) == stix->_method_dictionary);
dump_dictionary (stix, mthdic, "Method dictionary");
@ -275,21 +273,15 @@ TODO: overcome this problem
sp = -1;
ctx->slot[++sp] = ass->value; /* push receiver */
STORE_IP_AND_SP (ctx, ip, sp);
/* receiver, sender, method are nils */
stix->active_context = ctx;
STORE_ACTIVE_IP (stix, ip);
STORE_ACTIVE_SP (stix, sp);
return activate_new_method (stix, mth, &ip, &sp);
}
#define PUSH(stix,v) \
do { \
++sp; \
(stix)->active_context->slot[sp] = v; \
} while (0)
#define STACK_GET(stix,v_sp) ((stix)->active_context->slot[v_sp])
#define STACK_PUT(stix,v_sp,v_obj) ((stix)->active_context->slot[v_sp] = v_obj)
int primitive_dump (stix_t* stix, stix_ooi_t nargs)
{
@ -298,7 +290,7 @@ int primitive_dump (stix_t* stix, stix_ooi_t nargs)
STIX_ASSERT (nargs >= 0);
LOAD_SP (stix->active_context, sp);
LOAD_ACTIVE_SP (stix, sp);
dump_object (stix, stix->active_context->slot[sp - nargs], "receiver");
for (i = nargs; i > 0; )
{
@ -307,7 +299,7 @@ int primitive_dump (stix_t* stix, stix_ooi_t nargs)
}
sp -= nargs; /* pop off arguments */
STORE_SP (stix->active_context, sp);
STORE_ACTIVE_SP (stix, sp);
return 1; /* success */
}
@ -318,7 +310,7 @@ int primitive_new (stix_t* stix, stix_ooi_t nargs)
STIX_ASSERT (nargs == 0);
LOAD_SP (stix->active_context, sp);
LOAD_ACTIVE_SP (stix, sp);
rcv = STACK_GET(stix, sp);
if (STIX_CLASSOF(stix, rcv) != stix->_class)
@ -343,7 +335,7 @@ int primitive_new_with_size (stix_t* stix, stix_ooi_t nargs)
STIX_ASSERT (nargs == 1);
LOAD_SP (stix->active_context, sp);
LOAD_ACTIVE_SP (stix, sp);
rcv = STACK_GET(stix, sp - 1);
if (STIX_CLASSOF(stix, rcv) != stix->_class)
@ -364,12 +356,18 @@ int primitive_new_with_size (stix_t* stix, stix_ooi_t nargs)
return 0;
}
/* stix_instantiate() ignores size if the instance specification
* disallows indexed(variable) parts. */
/* TODO: should i check the specification before calling
* stix_instantiate()? */
obj = stix_instantiate (stix, rcv, STIX_NULL, size);
if (!obj) return -1; /* hard failure */
/* remove the argument and replace the receiver with a new object
* instantiated */
sp--;
STACK_PUT (stix, sp, obj);
STORE_SP (stix->active_context, sp);
STORE_ACTIVE_SP (stix, sp);
return 1; /* success */
}
@ -418,6 +416,8 @@ int stix_execute (stix_t* stix)
printf ("IP => %d ", (int)ip);
bc = code->slot[ip++];
/*if (bc == CODE_NOOP) continue; TODO: DO I NEED THIS???*/
cmd = bc >> 4;
if (cmd == CMD_EXTEND)
{
@ -437,17 +437,17 @@ printf ("CMD => %d, B1 = %d, SP = %d, IP AFTER INC %d\n", (int)cmd, (int)b1, (in
case CMD_PUSH_INSTVAR:
printf ("PUSH_INSTVAR %d\n", (int)b1);
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(stix->active_context->receiver) == STIX_OBJ_TYPE_OOP);
PUSH (stix, ((stix_oop_oop_t)stix->active_context->receiver)->slot[b1]);
STACK_PUSH (stix, ((stix_oop_oop_t)stix->active_context->receiver)->slot[b1]);
break;
case CMD_PUSH_TEMPVAR:
printf ("PUSH_TEMPVAR %d\n", (int)b1);
PUSH (stix, stix->active_context->slot[b1]);
STACK_PUSH (stix, stix->active_context->slot[b1]);
break;
case CMD_PUSH_LITERAL:
printf ("PUSH_LITERAL %d\n", (int)b1);
PUSH (stix, mth->slot[b1]);
STACK_PUSH (stix, mth->slot[b1]);
break;
case CMD_STORE_INTO_INSTVAR:
@ -461,9 +461,11 @@ printf ("STORE_TEMPVAR %d\n", (int)b1);
stix->active_context->slot[b1] = stix->active_context->slot[sp];
break;
/*
case CMD_POP_AND_STORE_INTO_OBJECT_POINTED_TO_BY_LITERAL???
*/
/* -------------------------------------------------------- */
case CMD_JUMP:
/* TODO: */
break;
/* -------------------------------------------------------- */
@ -479,7 +481,7 @@ printf ("STORE_TEMPVAR %d\n", (int)b1);
printf ("PUSH OBJVAR %d %d\n", (int)b1, (int)obj_index);
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(obj) == STIX_OBJ_TYPE_OOP);
STIX_ASSERT (obj_index < STIX_OBJ_GET_SIZE(obj));
PUSH (stix, obj->slot[b1]);
STACK_PUSH (stix, obj->slot[b1]);
break;
}
@ -572,9 +574,9 @@ printf ("RETURN INSTVAR AT PREAMBLE\n");
(primitives[prim_no].nargs < 0 || primitives[prim_no].nargs == b1))
{
stix_pushtmp (stix, (stix_oop_t*)&newmth);
STORE_SP (stix->active_context, sp);
STORE_ACTIVE_SP (stix, sp);
n = primitives[prim_no].handler (stix, b1);
LOAD_SP (stix->active_context, sp);
LOAD_ACTIVE_SP (stix, sp);
stix_poptmp (stix);
if (n <= -1) goto oops;
if (n >= 1) break;
@ -598,27 +600,39 @@ printf ("RETURN INSTVAR AT PREAMBLE\n");
{
case SUBCMD_PUSH_RECEIVER:
printf ("PUSH_RECEIVER %p TO STACK INDEX %d\n", stix->active_context->receiver, (int)sp);
PUSH (stix, stix->active_context->receiver);
STACK_PUSH (stix, stix->active_context->receiver);
break;
case SUBCMD_PUSH_NIL:
printf ("PUSH_NIL\n");
PUSH (stix, stix->_nil);
STACK_PUSH (stix, stix->_nil);
break;
case SUBCMD_PUSH_TRUE:
printf ("PUSH_TRUE\n");
PUSH (stix, stix->_true);
STACK_PUSH (stix, stix->_true);
break;
case SUBCMD_PUSH_FALSE:
printf ("PUSH_FALSE\n");
PUSH (stix, stix->_false);
STACK_PUSH (stix, stix->_false);
break;
case SUBCMD_PUSH_CONTEXT:
printf ("PUSH_CONTEXT\n");
PUSH (stix, (stix_oop_t)stix->active_context);
STACK_PUSH (stix, (stix_oop_t)stix->active_context);
break;
case SUBCMD_PUSH_NEGONE:
STACK_PUSH (stix, STIX_OOP_FROM_SMINT(-1));
break;
case SUBCMD_PUSH_ZERO:
STACK_PUSH (stix, STIX_OOP_FROM_SMINT(0));
break;
case SUBCMD_PUSH_ONE:
STACK_PUSH (stix, STIX_OOP_FROM_SMINT(1));
break;
}
break; /* CMD_PUSH_SPECIAL */
@ -657,16 +671,18 @@ printf ("RETURN_RECEIVER\n");
handle_return:
/* store the instruction pointer and the stack pointer to the active context */
STORE_IP_AND_SP (stix->active_context, ip, sp);
STORE_ACTIVE_IP (stix, ip);
STORE_ACTIVE_SP (stix, sp);
/* switch the active context to the sending context */
stix->active_context = (stix_oop_context_t)stix->active_context->sender;
/* load the instruction pointer and the stack pointer from the new active context */
LOAD_IP_AND_SP (stix->active_context, ip, sp);
LOAD_ACTIVE_IP (stix, ip);
LOAD_ACTIVE_SP (stix, sp);
/* push the return value to the stack of the new active context */
PUSH (stix, return_value);
STACK_PUSH (stix, return_value);
printf ("<<LEAVING>>\n");
if (stix->active_context->sender == stix->_nil)

View File

@ -439,8 +439,10 @@ struct stix_compiler_t
#define MAX_CODE_INDEX 0xFFFFu
#define MAX_CODE_NARGS 0xFFFFu
#define CMD_EXTEND 0x0
#define CMD_EXTEND_DOUBLE 0x1
enum stix_cmdcode_t
{
CMD_EXTEND = 0x0,
CMD_EXTEND_DOUBLE = 0x1,
/* Single positional instructions
*
@ -451,11 +453,14 @@ struct stix_compiler_t
* XXXX is one of the following positional instructions.
* JJJJ or JJJJJJJJ is the position.
*/
#define CMD_PUSH_INSTVAR 0x2
#define CMD_PUSH_TEMPVAR 0x3
#define CMD_PUSH_LITERAL 0x4
#define CMD_STORE_INTO_INSTVAR 0x5
#define CMD_STORE_INTO_TEMPVAR 0x6
CMD_PUSH_INSTVAR = 0x2,
CMD_PUSH_TEMPVAR = 0x3,
CMD_PUSH_LITERAL = 0x4,
CMD_STORE_INTO_INSTVAR = 0x5,
CMD_STORE_INTO_TEMPVAR = 0x6,
CMD_JUMP = 0x7,
CMD_JUMP_IF_FALSE = 0x8,
/*
* Double positional instructions
@ -467,33 +472,35 @@ struct stix_compiler_t
* Access instance variable #JJJJ of an object at literal frame #KKKKKKKK
* Send message at literal frame #KKKKKKKK with #JJJJ arguments.
*/
#define CMD_PUSH_OBJVAR 0x8
#define CMD_STORE_INTO_OBJVAR 0x9
CMD_PUSH_OBJVAR = 0x9,
CMD_STORE_INTO_OBJVAR = 0xA,
#define CMD_SEND_MESSAGE 0xA
#define CMD_SEND_MESSAGE_TO_SUPER 0xB
CMD_SEND_MESSAGE = 0xB,
CMD_SEND_MESSAGE_TO_SUPER = 0xC,
/*
* Single byte instructions
*/
#define CMD_PUSH_SPECIAL 0xE
#define CMD_DO_SPECIAL 0xF
CMD_PUSH_SPECIAL = 0xE,
CMD_DO_SPECIAL = 0xF,
enum stix_subcmd_t
{
/* sub-commands for CMD_PUSH_SPECIAL */
SUBCMD_PUSH_RECEIVER = 0x0,
SUBCMD_PUSH_NIL = 0x1,
SUBCMD_PUSH_TRUE = 0x2,
SUBCMD_PUSH_FALSE = 0x3,
SUBCMD_PUSH_CONTEXT = 0x4,
SUBCMD_PUSH_NEGONE = 0x5,
SUBCMD_PUSH_ZERO = 0x6,
SUBCMD_PUSH_ONE = 0x7,
/* sub-commands for CMD_DO_SPECIAL */
SUBCMD_DUP_STACKTOP = 0x0,
SUBCMD_POP_STACKTOP = 0x1,
SUBCMD_RETURN_STACKTOP = 0x2,
SUBCMD_RETURN_BLOCK_STACKTOP = 0x3,
SUBCMD_RETURN_RECEIVER = 0x4
SUBCMD_RETURN_RECEIVER = 0x4,
SUBCMD_NOOP = 0xF
};
/* ---------------------------------- */
@ -502,6 +509,9 @@ enum stix_subcmd_t
#define CODE_PUSH_TRUE MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_TRUE)
#define CODE_PUSH_FALSE MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_FALSE)
#define CODE_PUSH_CONTEXT MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_CONTEXT)
#define CODE_PUSH_NEGONE MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_NEGONE)
#define CODE_PUSH_ZERO MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_ZERO)
#define CODE_PUSH_ONE MAKE_CODE(CMD_PUSH_SPECIAL, SUBCMD_PUSH_ONE)
/* special code */
#define CODE_DUP_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_DUP_STACKTOP)
@ -509,6 +519,7 @@ enum stix_subcmd_t
#define CODE_RETURN_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_STACKTOP)
#define CODE_RETURN_BLOCK_STACKTOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_BLOCK_STACKTOP)
#define CODE_RETURN_RECEIVER MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_RETURN_RECEIVER)
#define CODE_NOOP MAKE_CODE(CMD_DO_SPECIAL, SUBCMD_NOOP)
#if defined(__cplusplus)
extern "C" {