changed the compiler to allow a character literal within a byte array literal

This commit is contained in:
hyunghwan.chung 2017-12-20 16:25:20 +00:00
parent d8b36bdf66
commit 4fe38f883c
4 changed files with 203 additions and 48 deletions

View File

@ -3,11 +3,16 @@
class Socket(Object) from 'sck' class Socket(Object) from 'sck'
{ {
var handle := -1. var handle := -1.
var insem, outsem.
var(#get,#set) inputAction, outputAction.
method(#primitive) open(domain, type, proto). method(#primitive) open(domain, type, proto).
method(#primitive) _close. method(#primitive) _close.
method(#primitive) connect(a,b,c). 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 *) (* TODO: generate these domain and type from the C header *)
@ -39,6 +44,19 @@ extend Socket
{ {
## this primitive method may return failure. ## this primitive method may return failure.
## but ignore it here. ## 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 _close.
self.handle := -1. self.handle := -1.
} }
@ -54,9 +72,13 @@ extend Socket
sa := [:sem | sa := [:sem |
System unsignal: s1. System unsignal: s1.
System unsignal: s2. System unsignal: s2.
'UNSIGNALLLING ...........' dump.
System removeAsyncSemaphore: s1. System removeAsyncSemaphore: s1.
System removeAsyncSemaphore: s2. System removeAsyncSemaphore: s2.
connectBlock value: (sem == s1)
'FINALIZING CONNECT' dump.
self endConnect.
connectBlock value: self value: (sem == s1)
]. ].
s1 signalAction: sa. s1 signalAction: sa.
@ -74,34 +96,51 @@ extend Socket
] ]
} }
method asyncRead: readBlock method watchInput
{ {
| s1 s2 | if (self.insem isNil)
s1 := Semaphore new. {
s2 := Semaphore new. self.insem := Semaphore new.
self.insem signalAction: [:sem | self.inputAction value: self value: true].
s1 signalAction: [:sem | readBlock value: true]. System signal: self.insem onInput: self.handle.
s2 signalAction: [:sem | readBlock value: false]. System addAsyncSemaphore: self.insem.
}
System signal: s1 onInput: self.handle. else
System signal: s2 afterSecs: 10. {
self.insem signalAction: [:sem | self.inputAction value: self value: true].
} }
(* ###s2 := Semaphore new.
method asyncWrite: ###s2 signalAction: [:sem | inputActionBlock value: self value: false].
{ ###System signal: s2 afterSecs: 10.
| 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.
} }
*)
method unwatchInput
{
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,20 +148,40 @@ class MyObject(Object)
{ {
method(#class) main method(#class) main
{ {
| s | | s conact inact outact |
[
s := Socket domain: Socket.Domain.INET type: Socket.Type.STREAM.
s asyncConnect: [:result | inact := [:sck :state |
##s endConnect: result. | data n |
##s beginRead: xxx.
if (result) data := ByteArray new: 100.
n := sck readBytes: data.
if (n == 0)
{ {
s endConnect: result. sck close.
'CONNECTED NOW.............' dump. }.
s asyncRead: [:data | (n asString & ' bytes read') dump.
data 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 else
{ {
@ -130,11 +189,19 @@ class MyObject(Object)
} }
]. ].
## ------------------------------------------------------
[
s := Socket domain: Socket.Domain.INET type: Socket.Type.STREAM.
s inputAction: inact; outputAction: outact.
s asyncConnect: conact.
while (true) while (true)
{ {
System handleAsyncEvent. System handleAsyncEvent.
}. }.
s close dump. s close dump.
] on: Exception do: [:ex | ('Exception - ' & ex messageText) dump ]. ] on: Exception do: [:ex | ('Exception - ' & ex messageText) dump ].
'----- END OF MAIN ------' dump. '----- END OF MAIN ------' dump.

View File

@ -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 */ 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 */ /* 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 /* the token reader reads a valid token. no other errors
* than the range error must not occur */ * 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)); set_syntax_error (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo));
goto oops; 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)); set_syntax_error (moo, MOO_SYNERR_BYTERANGE, TOKEN_LOC(moo), TOKEN_NAME(moo));
goto oops; goto oops;

View File

@ -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 & XPOLLERR) mask |= MOO_SEMAPHORE_IO_MASK_ERROR;
if (revents & XPOLLHUP) mask |= MOO_SEMAPHORE_IO_MASK_HANGUP; if (revents & XPOLLHUP) mask |= MOO_SEMAPHORE_IO_MASK_HANGUP;
printf ("먹스 마스크 %d\n", (int)mask);
#if defined(USE_DEVPOLL) #if defined(USE_DEVPOLL)
MOO_ASSERT (moo, xtn->epd.capa > xtn->ev.buf[n].fd); MOO_ASSERT (moo, xtn->epd.capa > xtn->ev.buf[n].fd);
muxwcb (moo, mask, (void*)xtn->epd.ptr[xtn->ev.buf[n].fd]); muxwcb (moo, mask, (void*)xtn->epd.ptr[xtn->ev.buf[n].fd]);

View File

@ -133,7 +133,7 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
struct sockaddr_in sin; struct sockaddr_in sin;
memset (&sin, 0, sizeof(sin)); memset (&sin, 0, sizeof(sin));
sin.sin_family = AF_INET; 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); sin.sin_port = htons(12345);
do do
{ {
@ -196,11 +196,92 @@ static moo_pfrc_t pf_end_connect (moo_t* moo, moo_ooi_t nargs)
} }
} }
MOO_STACK_SETRETTORCV (moo, nargs); MOO_STACK_SETRETTORCV (moo, nargs);
return MOO_PF_SUCCESS; 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; 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','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, { '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, { '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 } },
}; };
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */