From 4fe38f883cf65a8f9944b6680cc475991f7106c9 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Wed, 20 Dec 2017 16:25:20 +0000 Subject: [PATCH] changed the compiler to allow a character literal within a byte array literal --- moo/kernel/Socket.moo | 149 ++++++++++++++++++++++++++++++------------ moo/lib/comp.c | 12 +++- moo/lib/main.c | 1 - moo/mod/sck.c | 89 ++++++++++++++++++++++++- 4 files changed, 203 insertions(+), 48 deletions(-) diff --git a/moo/kernel/Socket.moo b/moo/kernel/Socket.moo index fb32401..217ad3c 100644 --- a/moo/kernel/Socket.moo +++ b/moo/kernel/Socket.moo @@ -3,11 +3,16 @@ class Socket(Object) from 'sck' { var handle := -1. + var insem, outsem. + var(#get,#set) inputAction, outputAction. method(#primitive) open(domain, type, proto). method(#primitive) _close. method(#primitive) connect(a,b,c). - method(#primitive) endConnect: xxx. + method(#primitive) endConnect. + + method(#primitive) readBytes: bytes. + method(#primitive) writeBytes: bytes. } (* TODO: generate these domain and type from the C header *) @@ -39,6 +44,19 @@ extend Socket { ## this primitive method may return failure. ## but ignore it here. + if (self.insem) + { + System unsignal: self.insem. + System removeAsyncSemaphore: self.insem. + self.insem := nil. + }. + if (self.outsem) + { + System unsignal: self.outsem. + System removeAsyncSemaphore: self.outsem. + self.outsem := nil. + }. + self _close. self.handle := -1. } @@ -54,9 +72,13 @@ extend Socket sa := [:sem | System unsignal: s1. System unsignal: s2. +'UNSIGNALLLING ...........' dump. System removeAsyncSemaphore: s1. System removeAsyncSemaphore: s2. - connectBlock value: (sem == s1) + +'FINALIZING CONNECT' dump. + self endConnect. + connectBlock value: self value: (sem == s1) ]. s1 signalAction: sa. @@ -74,34 +96,51 @@ extend Socket ] } - method asyncRead: readBlock + method watchInput { - | s1 s2 | - s1 := Semaphore new. - s2 := Semaphore new. + if (self.insem isNil) + { + self.insem := Semaphore new. + self.insem signalAction: [:sem | self.inputAction value: self value: true]. + System signal: self.insem onInput: self.handle. + System addAsyncSemaphore: self.insem. + } + else + { + self.insem signalAction: [:sem | self.inputAction value: self value: true]. + } - s1 signalAction: [:sem | readBlock value: true]. - s2 signalAction: [:sem | readBlock value: false]. - - System signal: s1 onInput: self.handle. - System signal: s2 afterSecs: 10. + ###s2 := Semaphore new. + ###s2 signalAction: [:sem | inputActionBlock value: self value: false]. + ###System signal: s2 afterSecs: 10. } -(* - method asyncWrite: + method unwatchInput { - | s1 s2 | - s1 := Semaphore new. - s2 := Semaphore new. - - s1 signalAction: [:sem | writeBlock value: true]. - s2 signalAction: [:sem | writeBlock value: false]. - - System signal: s1 onOutput: self.handle. - System signal: s2 afterSecs: 10. + System unsignal: self.insem. + System removeAsyncSemaphore: self.insem. } -*) + method watchOutput + { + if (self.outsem isNil) + { + self.outsem := Semaphore new. + self.outsem signalAction: [:sem | self.outputAction value: self value: true]. + System signal: self.outsem onOutput: self.handle. + System addAsyncSemaphore: self.outsem. + } + else + { + self.outsem signalAction: [:sem | self.outputAction value: self value: true]. + } + } + + method unwatchOutput + { + System unsignal: self.outsem. + System removeAsyncSemaphore: self.outsem. + } } @@ -109,32 +148,60 @@ class MyObject(Object) { method(#class) main { - | s | + | s conact inact outact | + + inact := [:sck :state | + | data n | + + data := ByteArray new: 100. + n := sck readBytes: data. + if (n == 0) + { + sck close. + }. + (n asString & ' bytes read') dump. + data dump. + ]. + + outact := [:sck :state | + if (state) + { + sck writeBytes: #[ $h $e $l $l $o ]. + } + else + { + } + ]. + + conact := [:sck :state | + + + if (state) + { + 'CONNECTED NOW.............' dump. + ##s onOutputDo: outact. + s writeBytes: #[ $h $e $l $l $o ]. + s watchInput. + } + else + { + 'UNABLE TO CONNECT............' dump. + } + ]. + + ## ------------------------------------------------------ + [ s := Socket domain: Socket.Domain.INET type: Socket.Type.STREAM. - - s asyncConnect: [:result | - ##s endConnect: result. - ##s beginRead: xxx. - if (result) - { - s endConnect: result. - 'CONNECTED NOW.............' dump. - s asyncRead: [:data | - data dump. - ] - } - else - { - 'UNABLE TO CONNECT............' dump. - } - ]. + s inputAction: inact; outputAction: outact. + s asyncConnect: conact. while (true) { System handleAsyncEvent. }. s close dump. + ] on: Exception do: [:ex | ('Exception - ' & ex messageText) dump ]. '----- END OF MAIN ------' dump. diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 2e35735..a2bd506 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -4555,11 +4555,16 @@ static int read_byte_array_literal (moo_t* moo, moo_oop_t* xlit) GET_TOKEN_GOTO (moo, oops); /* skip #[ and read the next token */ - while (TOKEN_TYPE(moo) == MOO_IOTOK_NUMLIT || TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT) + while (TOKEN_TYPE(moo) == MOO_IOTOK_NUMLIT || TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT || TOKEN_TYPE(moo) == MOO_IOTOK_CHARLIT) { /* TODO: check if the number is an integer */ - if (string_to_smooi(moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT, &tmp) <= -1) + if (TOKEN_TYPE(moo) == MOO_IOTOK_CHARLIT) + { + /* accept a character literal inside a byte array literal */ + tmp = TOKEN_NAME_PTR(moo)[0]; + } + else if (string_to_smooi(moo, TOKEN_NAME(moo), TOKEN_TYPE(moo) == MOO_IOTOK_RADNUMLIT, &tmp) <= -1) { /* the token reader reads a valid token. no other errors * than the range error must not occur */ @@ -4570,7 +4575,8 @@ static int read_byte_array_literal (moo_t* moo, moo_oop_t* xlit) set_syntax_error (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo)); goto oops; } - else if (tmp < 0 || tmp > 255) + + if (tmp < 0 || tmp > 255) { set_syntax_error (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo)); goto oops; diff --git a/moo/lib/main.c b/moo/lib/main.c index 4181391..b75da65 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -1666,7 +1666,6 @@ static void vm_muxwait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_c if (revents & XPOLLERR) mask |= MOO_SEMAPHORE_IO_MASK_ERROR; if (revents & XPOLLHUP) mask |= MOO_SEMAPHORE_IO_MASK_HANGUP; -printf ("먹스 마스크 %d\n", (int)mask); #if defined(USE_DEVPOLL) MOO_ASSERT (moo, xtn->epd.capa > xtn->ev.buf[n].fd); muxwcb (moo, mask, (void*)xtn->epd.ptr[xtn->ev.buf[n].fd]); diff --git a/moo/mod/sck.c b/moo/mod/sck.c index 67952e6..5add543 100644 --- a/moo/mod/sck.c +++ b/moo/mod/sck.c @@ -133,7 +133,7 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs) struct sockaddr_in sin; memset (&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; -sin.sin_addr.s_addr = inet_addr ("1.234.53.142"); +sin.sin_addr.s_addr = inet_addr ("192.168.1.143"); sin.sin_port = htons(12345); do { @@ -196,11 +196,92 @@ static moo_pfrc_t pf_end_connect (moo_t* moo, moo_ooi_t nargs) } } - MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; } +static moo_pfrc_t pf_read_socket (moo_t* moo, moo_ooi_t nargs) +{ + oop_sck_t sck; + moo_oop_byte_t buf; + int fd; + ssize_t n; + + sck = (oop_sck_t)MOO_STACK_GETRCV(moo, nargs); + MOO_PF_CHECK_RCV (moo, + MOO_OOP_IS_POINTER(sck) && + MOO_OBJ_BYTESOF(sck) >= (MOO_SIZEOF(*sck) - MOO_SIZEOF(moo_obj_t)) && + MOO_OOP_IS_SMOOI(sck->handle) + ); + + fd = MOO_OOP_TO_SMOOI(sck->handle); + if (fd <= -1) + { + moo_seterrbfmt (moo, MOO_EINVAL, "bad socket handle - %d\n", fd); + return MOO_PF_FAILURE; + } + + buf = (moo_oop_byte_t)MOO_STACK_GETARG (moo, nargs, 0); + if (!MOO_OBJ_IS_BYTE_POINTER(buf)) + { + moo_seterrbfmt (moo, MOO_EINVAL, "buffer not a byte array - %O\n", buf); + return MOO_PF_FAILURE; + } + + n = recv (fd, MOO_OBJ_GET_BYTE_SLOT(buf), MOO_OBJ_GET_SIZE(buf), 0); + if (n <= -1 && errno != EWOULDBLOCK) + { + moo_seterrwithsyserr (moo, errno); + return MOO_PF_FAILURE; + } + + MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(n)); + + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(n)); + return MOO_PF_SUCCESS; +} + +static moo_pfrc_t pf_write_socket (moo_t* moo, moo_ooi_t nargs) +{ + oop_sck_t sck; + moo_oop_byte_t buf; + int fd; + ssize_t n; + + sck = (oop_sck_t)MOO_STACK_GETRCV(moo, nargs); + MOO_PF_CHECK_RCV (moo, + MOO_OOP_IS_POINTER(sck) && + MOO_OBJ_BYTESOF(sck) >= (MOO_SIZEOF(*sck) - MOO_SIZEOF(moo_obj_t)) && + MOO_OOP_IS_SMOOI(sck->handle) + ); + + fd = MOO_OOP_TO_SMOOI(sck->handle); + if (fd <= -1) + { + moo_seterrbfmt (moo, MOO_EINVAL, "bad socket handle - %d\n", fd); + return MOO_PF_FAILURE; + } + + buf = (moo_oop_byte_t)MOO_STACK_GETARG (moo, nargs, 0); + if (!MOO_OBJ_IS_BYTE_POINTER(buf)) + { + moo_seterrbfmt (moo, MOO_EINVAL, "buffer not a byte array - %O\n", buf); + return MOO_PF_FAILURE; + } + + n = send (fd, MOO_OBJ_GET_BYTE_SLOT(buf), MOO_OBJ_GET_SIZE(buf), 0); + if (n <= -1 && errno != EWOULDBLOCK) + { + moo_seterrwithsyserr (moo, errno); + return MOO_PF_FAILURE; + } + + MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(n)); + + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(n)); + return MOO_PF_SUCCESS; +} + /* ------------------------------------------------------------------------ */ typedef struct fnctab_t fnctab_t; @@ -221,8 +302,10 @@ static moo_pfinfo_t pfinfos[] = { { I, { 'c','l','o','s','e','\0' }, 0, { pf_close_socket, 0, 0 } }, { I, { 'c','o','n','n','e','c','t','\0' }, 0, { pf_connect, 3, 3 } }, - { I, { 'e','n','d','C','o','n','n','e','c','t',':','\0' }, 0, { pf_end_connect, 1, 1 } }, + { I, { 'e','n','d','C','o','n','n','e','c','t','\0' }, 0, { pf_end_connect, 0, 0 } }, { I, { 'o','p','e','n','\0' }, 0, { pf_open_socket, 3, 3 } }, + { I, { 'r','e','a','d','B','y','t','e','s',':','\0' }, 0, { pf_read_socket, 1, 1 } }, + { I, { 'w','r','i','t','e','B','y','t','e','s',':','\0' }, 0, { pf_write_socket, 1, 1 } }, }; /* ------------------------------------------------------------------------ */