diff --git a/moo/kernel/Socket.moo b/moo/kernel/Socket.moo index 68c9c68..fd04b33 100644 --- a/moo/kernel/Socket.moo +++ b/moo/kernel/Socket.moo @@ -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. diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 701e30b..207adbd 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -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; diff --git a/moo/lib/decode.c b/moo/lib/decode.c index 11fd0f1..5569781 100644 --- a/moo/lib/decode.c +++ b/moo/lib/decode.c @@ -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); diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 46a959b..d60cfc9 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -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; diff --git a/moo/lib/moo-bct.h b/moo/lib/moo-bct.h index 035dde9..c21012c 100644 --- a/moo/lib/moo-bct.h +++ b/moo/lib/moo-bct.h @@ -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, diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 723a1be..9316471 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -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 */