added comparision to the Character class

This commit is contained in:
hyunghwan.chung 2017-12-30 19:07:31 +00:00
parent e39dd6027e
commit d0b20bee08
10 changed files with 398 additions and 18 deletions

View File

@ -51,6 +51,55 @@ class(#limited) Character(Magnitude)
## }
method(#primitive) asInteger.
method = aCharacter
{
<primitive: #Character_eq>
self primitiveFailed.
}
method ~= char
{
<primitive: #Character_ne>
self primitiveFailed.
}
method < char
{
<primitive: #Character_lt>
self primitiveFailed.
}
method > char
{
<primitive: #Character_gt>
self primitiveFailed.
}
method <= char
{
<primitive: #Character_le>
self primitiveFailed.
}
method >= char
{
<primitive: #Character_ge>
self primitiveFailed.
}
method - char
{
<primitive: #Character_sub>
^(self asInteger - char asInteger) asCharacter
}
method + char
{
<primitive: #Character_add>
^(self asInteger + char asInteger) asCharacter
}
}
class(#limited) Number(Magnitude)

View File

@ -1,5 +1,117 @@
#include 'Moo.moo'.
##interface IPAddressInterface
##{
##}
## class XXX(Object,IPAddressInterface) {}
class(#byte) IPAddress(Object)
{
}
###class(#byte(4)) IP4Address(IPAddress) -> new basicNew always create 4 bytes. size to new: or basicNew: is ignored.
###class(#byte(16)) IP6Address(IPAddress)
class(#byte) IP4Address(IPAddress)
{
method(#class) new
{
^self basicNew: 4.
}
method(#class) fromString: str
{
^self new fromString: str.
}
method fromString: str
{
| dots digits pos size c acc |
pos := 0.
size := str size.
acc := 0.
digits := 0.
dots := 0.
do
{
if (pos >= size)
{
if (dots < 3 or: [digits == 0])
{
Exception signal: ('invalid IPv4 address A ' & str).
}.
self basicAt: dots put: acc.
break.
}.
c := str at: pos.
pos := pos + 1.
if (c >= $0 and: [c <= $9])
{
acc := acc * 10 + (c - $0) asInteger.
if (acc > 255) { Exception signal: ('invalid IPv4 address B ' & str). }.
digits := digits + 1.
}
elsif (c == $.)
{
if (dots >= 3 or: [digits == 0]) { Exception signal: ('invalid IPv4 address C ' & str). }.
self basicAt: dots put: acc.
dots := dots + 1.
acc := 0.
digits := 0.
}
else
{
Exception signal: ('invalid IPv4 address ' & str).
}.
}
while (true).
}
}
class(#byte) IP6Address(IPAddress)
{
method(#class) new
{
^self basicNew: 16.
}
method(#class) fromString: str
{
}
}
class(#byte) IP4SocketAddress(IP4Address)
{
method(#class) new
{
^self basicNew: 6.
}
}
class SocketAddress(Object) from 'sck.addr'
{
##method(#primitive) family.
method(#primitive) fromString: str.
method(#class) fromString: str
{
^self new fromString: str
}
}
##class InetSocketAddress(SocketAddress)
##{
##}
class Socket(Object) from 'sck'
{
var handle := -1.
@ -96,6 +208,8 @@ extend Socket
]
}
## TODO: how to specify a timeout for an action? using another semaphore??
method watchInput
{
if (self.insem isNil)
@ -106,10 +220,6 @@ extend Socket
}.
System signal: self.insem onInput: self.handle.
###s2 := Semaphore new.
###s2 signalAction: [:sem | inputActionBlock value: self value: false].
###System signal: s2 afterSecs: 10.
}
method unwatchInput
@ -142,27 +252,46 @@ class MyObject(Object)
{
| s conact inact outact |
s := IP4Address fromString: '192.168.1.1'.
s dump.
s := IP6Address new.
s dump.
s := IP4SocketAddress new.
s dump.
thisProcess terminate.
inact := [:sck :state |
| data n |
(*
end of data -> 0.
no data -> -1.
has data -> 1 or moreailure indicated by primitive function 0x55a6210 - _integer_add
error -> exception
*)
data := ByteArray new: 100.
n := sck readBytes: data.
if (n == 0)
do
{
sck close.
n := sck readBytes: data.
if (n <= 0)
{
if (n == 0) { sck close }.
break.
}
elsif (n > 0)
{
(n asString & ' bytes read') dump.
data dump.
}.
}
else
{
(n asString & ' bytes read') dump.
data dump.
}.
while (true).
].
outact := [:sck :state |
if (state)
{
sck writeBytes: #[ $h, $e, $l, $l, $o, C'\n' ].
}
else
{

View File

@ -129,6 +129,7 @@ static struct voca_t
{ 10, { '#','i','m','m','u','t','a','b','l','e' } },
{ 6, { 'i','m','p','o','r','t' } },
{ 8, { '#','i','n','c','l','u','d','e' } },
{ 9, { 'i','n','t','e','r','f','a','c','e' } },
{ 8, { '#','l','e','n','i','e','n','t' } },
{ 8, { '#','l','i','b','e','r','a','l' } },
{ 8, { '#','l','i','m','i','t','e','d' } },
@ -193,6 +194,7 @@ enum voca_id_t
VOCA_IMMUTABLE_S,
VOCA_IMPORT,
VOCA_INCLUDE_S,
VOCA_INTERFACE,
VOCA_LENIENT_S,
VOCA_LIBERAL_S,
VOCA_LIMITED_S,
@ -8060,6 +8062,14 @@ static int compile_stream (moo_t* moo)
GET_TOKEN (moo);
if (compile_class_definition(moo, 0) <= -1) return -1;
}
#if 0
else if (is_token_word(moo, VOCA_INTERFACE))
{
/* interface InterfaceName { } */
GET_TOKEN (moo);
if (compile_interface_defintion(moo, 0) <= -1) return -1;
}
#endif
else if (is_token_word(moo, VOCA_EXTEND))
{
/* extend Selfclass {} */

View File

@ -3022,6 +3022,149 @@ static moo_pfrc_t pf_integer_inttostr (moo_t* moo, moo_ooi_t nargs)
/* ------------------------------------------------------------------ */
static moo_pfrc_t pf_character_eq (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, arg, res;
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_CHAR(rcv));
/*res = (MOO_OOP_IS_CHAR(arg) && MOO_OOP_TO_CHAR(rcv) == MOO_OOP_TO_CHAR(arg))? moo->_true: moo->_false;*/
res = (rcv == arg)? moo->_true: moo->_false; /* this comparision should be sufficient for characters */
MOO_STACK_SETRET (moo, nargs, res);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_character_ne (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, arg, res;
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_CHAR(rcv));
/*res = (MOO_OOP_IS_CHAR(arg) && MOO_OOP_TO_CHAR(rcv) == MOO_OOP_TO_CHAR(arg))? moo->_false: moo->_true;*/
res = (rcv == arg)? moo->_false: moo->_true; /* this comparision should be sufficient for characters */
MOO_STACK_SETRET (moo, nargs, res);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_character_lt (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, arg, res;
MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_CHAR(rcv));
MOO_PF_CHECK_ARGS (moo, nargs, MOO_OOP_IS_CHAR(arg));
res = (MOO_OOP_TO_CHAR(rcv) < MOO_OOP_TO_CHAR(arg))? moo->_true: moo->_false;
MOO_STACK_SETRET (moo, nargs, res);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_character_gt (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, arg, res;
MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_CHAR(rcv));
MOO_PF_CHECK_ARGS (moo, nargs, MOO_OOP_IS_CHAR(arg));
res = (MOO_OOP_TO_CHAR(rcv) > MOO_OOP_TO_CHAR(arg))? moo->_true: moo->_false;
MOO_STACK_SETRET (moo, nargs, res);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_character_le (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, arg, res;
MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_CHAR(rcv));
MOO_PF_CHECK_ARGS (moo, nargs, MOO_OOP_IS_CHAR(arg));
res = (MOO_OOP_TO_CHAR(rcv) <= MOO_OOP_TO_CHAR(arg))? moo->_true: moo->_false;
MOO_STACK_SETRET (moo, nargs, res);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_character_ge (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, arg, res;
MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_CHAR(rcv));
MOO_PF_CHECK_ARGS (moo, nargs, MOO_OOP_IS_CHAR(arg));
res = (MOO_OOP_TO_CHAR(rcv) >= MOO_OOP_TO_CHAR(arg))? moo->_true: moo->_false;
MOO_STACK_SETRET (moo, nargs, res);
return MOO_PF_SUCCESS;
}
/* ------------------------------------------------------------------ */
static moo_pfrc_t pf_character_add (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, arg, res;
MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_CHAR(rcv));
MOO_PF_CHECK_ARGS (moo, nargs, MOO_OOP_IS_CHAR(arg));
res = MOO_CHAR_TO_OOP(MOO_OOP_TO_CHAR(rcv) + MOO_OOP_TO_CHAR(arg));
MOO_STACK_SETRET (moo, nargs, res);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_character_sub (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv, arg, res;
MOO_ASSERT (moo, nargs == 1);
rcv = MOO_STACK_GETRCV(moo, nargs);
arg = MOO_STACK_GETARG(moo, nargs, 0);
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_CHAR(rcv));
MOO_PF_CHECK_ARGS (moo, nargs, MOO_OOP_IS_CHAR(arg));
res = MOO_CHAR_TO_OOP(MOO_OOP_TO_CHAR(rcv) - MOO_OOP_TO_CHAR(arg));
MOO_STACK_SETRET (moo, nargs, res);
return MOO_PF_SUCCESS;
}
/* ------------------------------------------------------------------ */
static moo_pfrc_t pf_character_as_smooi (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t rcv;
@ -3283,7 +3426,15 @@ static pf_t pftab[] =
{ "BlockContext_value", { pf_block_value, 0, MA } },
{ "BlockContext_newProcess", { pf_block_new_process, 0, MA } },
{ "Character_add", { pf_character_add, 1, 1 } },
{ "Character_asInteger", { pf_character_as_smooi, 0, 0 } },
{ "Character_eq", { pf_character_eq, 1, 1 } },
{ "Character_le", { pf_character_le, 1, 1 } },
{ "Character_lt", { pf_character_lt, 1, 1 } },
{ "Character_ne", { pf_character_ne, 1, 1 } },
{ "Character_ge", { pf_character_ge, 1, 1 } },
{ "Character_gt", { pf_character_gt, 1, 1 } },
{ "Character_sub", { pf_character_sub, 1, 1 } },
{ "Error_asCharacter", { pf_error_as_character, 0, 0 } },
{ "Error_asInteger", { pf_error_as_integer, 0, 0 } },

View File

@ -425,6 +425,7 @@ static_modtab[] =
#endif
#if defined(MOO_ENABLE_MOD_SCK)
{ "sck", moo_mod_sck },
{ "sck.addr", moo_mod_sck_addr },
#endif
{ "stdio", moo_mod_stdio },
#if defined(MOO_ENABLE_MOD_X11)

View File

@ -89,7 +89,7 @@ libmoo_ffi_la_LIBADD = $(LIBADD_COMMON) $(DYNCALL_LIBS)
endif
if ENABLE_MOD_SCK
libmoo_sck_la_SOURCES = sck.c _sck.h
libmoo_sck_la_SOURCES = sck.c sck-addr.c _sck.h
libmoo_sck_la_CPPFLAGS = $(CPPFLAGS_COMMON)
libmoo_sck_la_LDFLAGS = $(LDFLAGS_COMMON)
libmoo_sck_la_LIBADD = $(LIBADD_COMMON)

View File

@ -168,8 +168,9 @@ libmoo_ffi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
@ENABLE_MOD_FFI_TRUE@@ENABLE_STATIC_MODULE_TRUE@am_libmoo_ffi_la_rpath =
@ENABLE_MOD_SCK_TRUE@libmoo_sck_la_DEPENDENCIES = \
@ENABLE_MOD_SCK_TRUE@ $(am__DEPENDENCIES_1)
am__libmoo_sck_la_SOURCES_DIST = sck.c _sck.h
@ENABLE_MOD_SCK_TRUE@am_libmoo_sck_la_OBJECTS = libmoo_sck_la-sck.lo
am__libmoo_sck_la_SOURCES_DIST = sck.c sck-addr.c _sck.h
@ENABLE_MOD_SCK_TRUE@am_libmoo_sck_la_OBJECTS = libmoo_sck_la-sck.lo \
@ENABLE_MOD_SCK_TRUE@ libmoo_sck_la-sck-addr.lo
libmoo_sck_la_OBJECTS = $(am_libmoo_sck_la_OBJECTS)
libmoo_sck_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@ -462,7 +463,7 @@ libmoo_con_la_LIBADD = $(LIBADD_COMMON) $(TERMINAL_LIBS)
@ENABLE_MOD_FFI_TRUE@libmoo_ffi_la_CPPFLAGS = $(CPPFLAGS_COMMON)
@ENABLE_MOD_FFI_TRUE@libmoo_ffi_la_LDFLAGS = $(LDFLAGS_COMMON)
@ENABLE_MOD_FFI_TRUE@libmoo_ffi_la_LIBADD = $(LIBADD_COMMON) $(DYNCALL_LIBS)
@ENABLE_MOD_SCK_TRUE@libmoo_sck_la_SOURCES = sck.c _sck.h
@ENABLE_MOD_SCK_TRUE@libmoo_sck_la_SOURCES = sck.c sck-addr.c _sck.h
@ENABLE_MOD_SCK_TRUE@libmoo_sck_la_CPPFLAGS = $(CPPFLAGS_COMMON)
@ENABLE_MOD_SCK_TRUE@libmoo_sck_la_LDFLAGS = $(LDFLAGS_COMMON)
@ENABLE_MOD_SCK_TRUE@libmoo_sck_la_LIBADD = $(LIBADD_COMMON)
@ -578,6 +579,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_con_la-con.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_ffi_la-ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_sck_la-sck-addr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_sck_la-sck.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_stdio_la-stdio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_x11_la-x11.Plo@am__quote@
@ -627,6 +629,13 @@ libmoo_sck_la-sck.lo: sck.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_sck_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_sck_la-sck.lo `test -f 'sck.c' || echo '$(srcdir)/'`sck.c
libmoo_sck_la-sck-addr.lo: sck-addr.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_sck_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmoo_sck_la-sck-addr.lo -MD -MP -MF $(DEPDIR)/libmoo_sck_la-sck-addr.Tpo -c -o libmoo_sck_la-sck-addr.lo `test -f 'sck-addr.c' || echo '$(srcdir)/'`sck-addr.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmoo_sck_la-sck-addr.Tpo $(DEPDIR)/libmoo_sck_la-sck-addr.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sck-addr.c' object='libmoo_sck_la-sck-addr.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_sck_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_sck_la-sck-addr.lo `test -f 'sck-addr.c' || echo '$(srcdir)/'`sck-addr.c
libmoo_stdio_la-stdio.lo: stdio.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_stdio_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmoo_stdio_la-stdio.lo -MD -MP -MF $(DEPDIR)/libmoo_stdio_la-stdio.Tpo -c -o libmoo_stdio_la-stdio.lo `test -f 'stdio.c' || echo '$(srcdir)/'`stdio.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmoo_stdio_la-stdio.Tpo $(DEPDIR)/libmoo_stdio_la-stdio.Plo

View File

@ -38,11 +38,13 @@ struct sck_t
/* there are more fields in the actual object */
};
#if defined(__cplusplus)
extern "C" {
#endif
MOO_EXPORT int moo_mod_sck (moo_t* moo, moo_mod_t* mod);
MOO_EXPORT int moo_mod_sck_addr (moo_t* moo, moo_mod_t* mod);
#if defined(__cplusplus)
}

View File

@ -99,7 +99,6 @@ extern "C" {
#endif
MOO_EXPORT int moo_mod_x11 (moo_t* moo, moo_mod_t* mod);
MOO_EXPORT int moo_mod_x11_win (moo_t* moo, moo_mod_t* mod);
#if defined(__cplusplus)
}

View File

@ -111,6 +111,33 @@ static moo_pfrc_t pf_close_socket (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_FAILURE;
}
static moo_pfrc_t pf_bind_socket (moo_t* moo, moo_ooi_t nargs)
{
oop_sck_t sck;
int fd, 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 0
n = bind(fd, &sin, MOO_SIZEOF(sin));
if (n == -1)
{
moo_seterrwithsyserr (moo, errno);
return MOO_PF_FAILURE;
}
#endif
MOO_STACK_SETRETTORCV (moo, nargs);
return MOO_PF_SUCCESS;
}
static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs)
{
oop_sck_t sck;
@ -300,6 +327,7 @@ struct fnctab_t
static moo_pfinfo_t pfinfos[] =
{
{ I, { 'b','i','n','d','\0' }, 0, { pf_bind_socket, 1, 1 } },
{ 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, 0, 0 } },
@ -334,3 +362,5 @@ int moo_mod_sck (moo_t* moo, moo_mod_t* mod)
mod->ctx = MOO_NULL;
return 0;
}