enhanced the compiler to compile byte array expression.

added MAKE_BYTEARRAY and POP_INTO_BYTEARRAY byte codes
This commit is contained in:
hyunghwan.chung 2018-04-19 09:48:45 +00:00
parent a5328db569
commit df5b9301dc
6 changed files with 140 additions and 22 deletions

View File

@ -331,10 +331,9 @@ class AsyncHandle(Object)
}.
}
method writeBytes: bytes offset: offset length: length
method writeBytes: bytes offset: offset length: length semaphore: sem
{
| oldact |
| oldact n |
#######################################
## TODO: if data still in progress, failure... or success while concatening the message?
## for a stream, concatening is not bad. but it's not good if the socket requires message boundary preservation.
@ -342,12 +341,25 @@ class AsyncHandle(Object)
if (self.outputReady)
{
if ((self _writeBytes: bytes offset: offset length: length) >= 0) { ^self }.
## n >= 0: written
## n <= -1: tolerable error (e.g. EAGAIN)
## exception: fatal error
##while (true) ## TODO: loop to write as much as possible
##{
n := self _writeBytes: bytes offset: offset length: length.
if (n >= 0)
{
if (sem notNil) { sem signal }.
^n
}.
##}.
self.outputReady := false.
}.
oldact := self.outputAction.
self.outputAction := [ :sck :state |
##### schedule write.
if (state)
{
if ((self _writeBytes: bytes offset: offset length: length) <= -1)
@ -367,9 +379,19 @@ class AsyncHandle(Object)
self watchOutput.
}
method writeBytes: bytes semaphore: sem
{
^self writeBytes: bytes offset: 0 length: (bytes size) semaphore: sem.
}
method writeBytes: bytes offset: offset length: length
{
^self writeBytes: bytes offset: offset length: length semaphore: nil.
}
method writeBytes: bytes
{
^self writeBytes: bytes offset: 0 length: (bytes size)
^self writeBytes: bytes offset: 0 length: (bytes size) semaphore: nil.
}
}
@ -576,15 +598,29 @@ error -> exception
}
].
conact := [:sck :state |
| x write_more count |
count := 0.
if (state)
{
'CONNECTED NOW.............' dump.
###sck inputTimeout: 10; outputTimeout: 10; connectTimeout: 10.
write_more := [:sem |
sck writeBytes: %[ $h, $e, $l, $l, $o, $-, $m, $o, count + 65, $o, $o, C'\n' ] semaphore: x.
if (count > 26) { count := 0 }
else { count := count + 1 }.
].
x := Semaphore new.
x signalAction: write_more.
System addAsyncSemaphore: x.
sck outputAction: outact.
sck writeBytes: #[ $h, $e, $l, $l, $o, $-, $m, $o, $o, C'\n' ].
sck writeBytes: #[ $h, $e, $l, $l, $o, $-, $m, $o, $o, C'\n' ] semaphore: x.
sck inputAction: inact.
sck watchInput.
@ -608,6 +644,7 @@ error -> exception
##newsck watchInput; watchOutput.
newsck watchInput.
newsck writeBytes: #[ $W, $e, $l, $c, $o, $m, $e, $., C'\n' ].
].
@ -615,7 +652,6 @@ error -> exception
| s s2 st sg ss |
[
s := Socket domain: Socket.Domain.INET type: Socket.Type.STREAM.
##s connect: (SocketAddress fromString: '127.0.0.1:9999') do: conact.
s connect: (SocketAddress fromString: '127.0.0.1:9999') do: conact.
## s2 := Socket domain: Socket.Domain.INET type: Socket.Type.STREAM.
@ -642,6 +678,8 @@ st := Semaphore new.
System addAsyncSemaphore: st.
System signal: st afterSecs: 20.
*)
while (true)
{
ss := System handleAsyncEvent.

View File

@ -1681,13 +1681,18 @@ retry:
ADD_TOKEN_CHAR(moo, c);
GET_CHAR_TO (moo, c);
/* TODO: byte array expression token -> %[ */
if (c == '(')
{
/* %( - array expression */
ADD_TOKEN_CHAR(moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_PERCPAREN);
}
else if (c == '[')
{
/* %[ - byte-array expression */
ADD_TOKEN_CHAR(moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_PERCBRACK);
}
else if (c == '{')
{
/* %{ - dictionary expression */
@ -1725,6 +1730,12 @@ retry:
SET_TOKEN_TYPE (moo, MOO_IOTOK_HASHBRACK);
break;
case '{':
/* #[ - dictionary literal */
ADD_TOKEN_CHAR(moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_HASHBRACE);
break;
case '\'':
/* quoted symbol literal */
if (get_strlit(moo) <= -1) return -1; /* reuse the string literal tokenizer */
@ -2192,6 +2203,8 @@ static int emit_single_param_instruction (moo_t* moo, int cmd, moo_oow_t param_1
case BCODE_MAKE_DICTIONARY:
case BCODE_MAKE_ARRAY:
case BCODE_POP_INTO_ARRAY:
case BCODE_MAKE_BYTEARRAY:
case BCODE_POP_INTO_BYTEARRAY:
bc = cmd;
goto write_long;
}
@ -4713,15 +4726,15 @@ static int compile_array_literal (moo_t* moo)
return 0;
}
static int compile_array_expression (moo_t* moo)
static int _compile_array_expression (moo_t* moo, int closer_token, int bcode_make, int bcode_pop_into)
{
moo_oow_t maip;
moo_ioloc_t aeloc;
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_PERCPAREN);
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_PERCPAREN || TOKEN_TYPE(moo) == MOO_IOTOK_PERCBRACK);
maip = moo->c->mth.code.len;
if (emit_single_param_instruction(moo, BCODE_MAKE_ARRAY, 0) <= -1) return -1;
if (emit_single_param_instruction(moo, bcode_make, 0) <= -1) return -1;
aeloc = *TOKEN_LOC(moo);
GET_TOKEN (moo); /* read a token after #{ */
@ -4732,8 +4745,8 @@ static int compile_array_expression (moo_t* moo)
index = 0;
do
{
if (compile_method_expression (moo, 0) <= -1) return -1;
if (emit_single_param_instruction (moo, BCODE_POP_INTO_ARRAY, index) <= -1) return -1;
if (compile_method_expression(moo, 0) <= -1) return -1;
if (emit_single_param_instruction(moo, bcode_pop_into, index) <= -1) return -1;
index++;
if (index > MAX_CODE_PARAM)
@ -4742,7 +4755,7 @@ static int compile_array_expression (moo_t* moo)
return -1;
}
if (TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) break;
if (TOKEN_TYPE(moo) == closer_token) break;
if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA)
{
@ -4768,6 +4781,16 @@ static int compile_array_expression (moo_t* moo)
return 0;
}
static int compile_array_expression (moo_t* moo)
{
return _compile_array_expression (moo, MOO_IOTOK_RPAREN, BCODE_MAKE_ARRAY, BCODE_POP_INTO_ARRAY);
}
static int compile_bytearray_expression (moo_t* moo)
{
return _compile_array_expression (moo, MOO_IOTOK_RBRACK, BCODE_MAKE_BYTEARRAY, BCODE_POP_INTO_BYTEARRAY);
}
static int compile_dictionary_expression (moo_t* moo)
{
moo_oow_t mdip;
@ -5008,20 +5031,32 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons
GET_TOKEN (moo);
break;
case MOO_IOTOK_HASHBRACK: /* #[ */
/*GET_TOKEN (moo);*/
if (compile_byte_array_literal(moo) <= -1) return -1;
break;
case MOO_IOTOK_HASHPAREN: /* #( */
/*GET_TOKEN (moo);*/
if (compile_array_literal(moo) <= -1) return -1;
break;
case MOO_IOTOK_HASHBRACK: /* #[ */
/*GET_TOKEN (moo);*/
if (compile_byte_array_literal(moo) <= -1) return -1;
break;
#if 0
/* TODO: */
case MOO_IOTOK_HASHBRACE: /* #{ */
if (compile_dictionary_literal(moo) <= -1) return -1;
break;
#endif
case MOO_IOTOK_PERCPAREN: /* %( */
if (compile_array_expression(moo) <= -1) return -1;
break;
case MOO_IOTOK_PERCBRACK: /* %[ */
if (compile_bytearray_expression(moo) <= -1) return -1;
break;
case MOO_IOTOK_PERCBRACE: /* %{ */
if (compile_dictionary_expression(moo) <= -1) return -1;
break;

View File

@ -500,6 +500,16 @@ int moo_decode (moo_t* moo, moo_oop_method_t mth, const moo_oocs_t* classfqn)
break;
/* -------------------------------------------------------- */
case BCODE_MAKE_BYTEARRAY:
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "make_bytearray %zu", b1);
break;
case BCODE_POP_INTO_BYTEARRAY:
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "pop_into_bytearray %zu", b1);
break;
case BCODE_MAKE_DICTIONARY:
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST_1 (moo, "make_dictionary %zu", b1);

View File

@ -5283,6 +5283,39 @@ static int __execute (moo_t* moo)
NEXT_INST();
}
ON_INST(BCODE_MAKE_BYTEARRAY)
{
moo_oop_t t;
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST1 (moo, "make_bytearray %zu", b1);
/* create an empty array */
t = moo_instantiate (moo, moo->_byte_array, MOO_NULL, b1);
if (!t) return -1;
MOO_STACK_PUSH (moo, t); /* push the array created */
NEXT_INST();
}
ON_INST(BCODE_POP_INTO_BYTEARRAY)
{
moo_oop_t t1, t2;
moo_uint8_t bv;
FETCH_PARAM_CODE_TO (moo, b1);
LOG_INST1 (moo, "pop_into_bytearray %zu", b1);
t1 = MOO_STACK_GETTOP(moo);
MOO_STACK_POP (moo);
t2 = MOO_STACK_GETTOP(moo);
if (MOO_OOP_IS_SMOOI(t1)) bv = MOO_OOP_TO_SMOOI(t1);
else if (MOO_OOP_IS_CHAR(t1)) bv = MOO_OOP_TO_CHAR(t1);
else if (MOO_OOP_IS_ERROR(t1)) bv = MOO_OOP_TO_ERROR(t1);
else if (MOO_OOP_IS_SMPTR(t1)) bv = ((moo_oow_t)MOO_OOP_TO_SMPTR(t1) & 0xFF);
else bv = 0;
((moo_oop_byte_t)t2)->slot[b1] = bv;
NEXT_INST();
}
ON_INST(BCODE_DUP_STACKTOP)
{
moo_oop_t t;

View File

@ -238,8 +238,8 @@
/* 235 */ &&case_DEFAULT,
/* 236 */ &&case_BCODE_POP_INTO_OBJVAR_X,
/* 237 */ &&case_DEFAULT,
/* 238 */ &&case_DEFAULT,
/* 239 */ &&case_DEFAULT,
/* 238 */ &&case_BCODE_MAKE_BYTEARRAY,
/* 239 */ &&case_BCODE_POP_INTO_BYTEARRAY,
/* 240 */ &&case_BCODE_SEND_MESSAGE_X,
/* 241 */ &&case_DEFAULT,
/* 242 */ &&case_BCODE_MAKE_DICTIONARY,

View File

@ -369,7 +369,9 @@ enum moo_iotok_type_t
MOO_IOTOK_RPAREN,
MOO_IOTOK_HASHPAREN, /* #( - array literal */
MOO_IOTOK_HASHBRACK, /* #[ - byte array literal */
MOO_IOTOK_HASHBRACE, /* #{ - dictionary literal */
MOO_IOTOK_PERCPAREN, /* %( - array expression */
MOO_IOTOK_PERCBRACK, /* %[ - byte array expression */
MOO_IOTOK_PERCBRACE, /* %{ - dictionary expression */
MOO_IOTOK_PERIOD,
MOO_IOTOK_COMMA,
@ -954,8 +956,8 @@ enum moo_bcode_t
BCODE_POP_INTO_OBJVAR_X = 0xEC, /* 236 ## */
/* UNUSED 237 */
/* UNUSED 238 */
/* UNUSED 239 */
BCODE_MAKE_BYTEARRAY = 0xEE, /* 238 */
BCODE_POP_INTO_BYTEARRAY = 0xEF, /* 239 */
BCODE_SEND_MESSAGE_X = 0xF0, /* 240 ## */
/* UNUSED 241 */