started migrating some primitive functions to a separate file
This commit is contained in:
@ -61,6 +61,7 @@ libmoo_la_SOURCES = \
|
||||
obj.c \
|
||||
opt-impl.h \
|
||||
opt.c \
|
||||
pf-basic.c \
|
||||
rbt.c \
|
||||
sym.c \
|
||||
utf8.c \
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Makefile.in generated by automake 1.15 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.14.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@ -17,17 +17,7 @@
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
am__is_gnu_make = { \
|
||||
if test -z '$(MAKELEVEL)'; then \
|
||||
false; \
|
||||
elif test -n '$(MAKE_HOST)'; then \
|
||||
true; \
|
||||
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
|
||||
true; \
|
||||
else \
|
||||
false; \
|
||||
fi; \
|
||||
}
|
||||
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
|
||||
am__make_running_with_option = \
|
||||
case $${target_option-} in \
|
||||
?) ;; \
|
||||
@ -111,17 +101,18 @@ host_triplet = @host@
|
||||
bin_PROGRAMS = moo$(EXEEXT)
|
||||
@ENABLE_STATIC_MODULE_FALSE@moo_DEPENDENCIES = $(am__DEPENDENCIES_3)
|
||||
subdir = lib
|
||||
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
|
||||
$(srcdir)/moo-cfg.h.in $(top_srcdir)/ac/depcomp \
|
||||
$(noinst_HEADERS) $(pkginclude_HEADERS)
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_namespace.m4 \
|
||||
am__aclocal_m4_deps = $(top_srcdir)/m4/argz.m4 \
|
||||
$(top_srcdir)/m4/ax_cxx_namespace.m4 \
|
||||
$(top_srcdir)/m4/ax_numval.m4 $(top_srcdir)/m4/libtool.m4 \
|
||||
$(top_srcdir)/m4/ltargz.m4 $(top_srcdir)/m4/ltdl.m4 \
|
||||
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
|
||||
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
$(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \
|
||||
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
|
||||
$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
DIST_COMMON = $(srcdir)/Makefile.am $(noinst_HEADERS) \
|
||||
$(pkginclude_HEADERS) $(am__DIST_COMMON)
|
||||
mkinstalldirs = $(install_sh) -d
|
||||
CONFIG_HEADER = moo-cfg.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
@ -163,8 +154,9 @@ am_libmoo_la_OBJECTS = libmoo_la-bigint.lo libmoo_la-comp.lo \
|
||||
libmoo_la-debug.lo libmoo_la-decode.lo libmoo_la-dic.lo \
|
||||
libmoo_la-err.lo libmoo_la-exec.lo libmoo_la-logfmt.lo \
|
||||
libmoo_la-gc.lo libmoo_la-heap.lo libmoo_la-moo.lo \
|
||||
libmoo_la-obj.lo libmoo_la-opt.lo libmoo_la-rbt.lo \
|
||||
libmoo_la-sym.lo libmoo_la-utf8.lo libmoo_la-utl.lo
|
||||
libmoo_la-obj.lo libmoo_la-opt.lo libmoo_la-pf-basic.lo \
|
||||
libmoo_la-rbt.lo libmoo_la-sym.lo libmoo_la-utf8.lo \
|
||||
libmoo_la-utl.lo
|
||||
libmoo_la_OBJECTS = $(am_libmoo_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
@ -241,8 +233,6 @@ am__define_uniq_tagged_files = \
|
||||
done | $(am__uniquify_input)`
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/moo-cfg.h.in \
|
||||
$(top_srcdir)/ac/depcomp
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
pkgincludedir = $(includedir)
|
||||
pkglibdir = $(libdir)
|
||||
@ -250,6 +240,7 @@ ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AR = @AR@
|
||||
ARGZ_H = @ARGZ_H@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
@ -303,11 +294,9 @@ LTDLDEPS = @LTDLDEPS@
|
||||
LTDLINCL = @LTDLINCL@
|
||||
LTDLOPEN = @LTDLOPEN@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
LT_ARGZ_H = @LT_ARGZ_H@
|
||||
LT_CONFIG_H = @LT_CONFIG_H@
|
||||
LT_DLLOADERS = @LT_DLLOADERS@
|
||||
LT_DLPREOPEN = @LT_DLPREOPEN@
|
||||
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MANIFEST_TOOL = @MANIFEST_TOOL@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
@ -449,6 +438,7 @@ libmoo_la_SOURCES = \
|
||||
obj.c \
|
||||
opt-impl.h \
|
||||
opt.c \
|
||||
pf-basic.c \
|
||||
rbt.c \
|
||||
sym.c \
|
||||
utf8.c \
|
||||
@ -484,6 +474,7 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign lib/Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
@ -627,6 +618,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-moo.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-obj.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-opt.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-pf-basic.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-rbt.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-sym.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libmoo_la-utf8.Plo@am__quote@
|
||||
@ -748,6 +740,13 @@ libmoo_la-opt.lo: opt.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_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_la-opt.lo `test -f 'opt.c' || echo '$(srcdir)/'`opt.c
|
||||
|
||||
libmoo_la-pf-basic.lo: pf-basic.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmoo_la-pf-basic.lo -MD -MP -MF $(DEPDIR)/libmoo_la-pf-basic.Tpo -c -o libmoo_la-pf-basic.lo `test -f 'pf-basic.c' || echo '$(srcdir)/'`pf-basic.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmoo_la-pf-basic.Tpo $(DEPDIR)/libmoo_la-pf-basic.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pf-basic.c' object='libmoo_la-pf-basic.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_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libmoo_la-pf-basic.lo `test -f 'pf-basic.c' || echo '$(srcdir)/'`pf-basic.c
|
||||
|
||||
libmoo_la-rbt.lo: rbt.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmoo_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libmoo_la-rbt.lo -MD -MP -MF $(DEPDIR)/libmoo_la-rbt.Tpo -c -o libmoo_la-rbt.lo `test -f 'rbt.c' || echo '$(srcdir)/'`rbt.c
|
||||
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libmoo_la-rbt.Tpo $(DEPDIR)/libmoo_la-rbt.Plo
|
||||
@ -1030,8 +1029,6 @@ uninstall-am: uninstall-binPROGRAMS uninstall-pkgincludeHEADERS \
|
||||
uninstall-binPROGRAMS uninstall-hook \
|
||||
uninstall-pkgincludeHEADERS uninstall-pkglibLTLIBRARIES
|
||||
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
install-data-hook:
|
||||
@echo "#ifndef _MOO_CFG_H_" > "$(DESTDIR)$(pkgincludedir)/moo-cfg.h"
|
||||
|
441
moo/lib/exec.c
441
moo/lib/exec.c
@ -1665,403 +1665,6 @@ start_over:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static moo_pfrc_t pf_identical (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, arg, b;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
b = (rcv == arg)? moo->_true: moo->_false;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, b);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_not_identical (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, arg, b;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
b = (rcv != arg)? moo->_true: moo->_false;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, b);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static int _equal_objects (moo_t* moo, moo_oop_t rcv, moo_oop_t arg)
|
||||
{
|
||||
int rtag;
|
||||
|
||||
if (rcv == arg) return 1; /* identical. so equal */
|
||||
|
||||
rtag = MOO_OOP_GET_TAG(rcv);
|
||||
if (rtag != MOO_OOP_GET_TAG(arg)) return 0;
|
||||
|
||||
switch (rtag)
|
||||
{
|
||||
case MOO_OOP_TAG_SMOOI:
|
||||
return MOO_OOP_TO_SMOOI(rcv) == MOO_OOP_TO_SMOOI(arg)? 1: 0;
|
||||
|
||||
case MOO_OOP_TAG_SMPTR:
|
||||
return MOO_OOP_TO_SMPTR(rcv) == MOO_OOP_TO_SMPTR(arg)? 1: 0;
|
||||
|
||||
case MOO_OOP_TAG_CHAR:
|
||||
return MOO_OOP_TO_CHAR(rcv) == MOO_OOP_TO_CHAR(arg)? 1: 0;
|
||||
|
||||
case MOO_OOP_TAG_ERROR:
|
||||
return MOO_OOP_TO_ERROR(rcv) == MOO_OOP_TO_ERROR(arg)? 1: 0;
|
||||
|
||||
default:
|
||||
{
|
||||
MOO_ASSERT (moo, MOO_OOP_IS_POINTER(rcv));
|
||||
|
||||
if (MOO_OBJ_GET_CLASS(rcv) != MOO_OBJ_GET_CLASS(arg)) return 0; /* different class, not equal */
|
||||
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_TYPE(rcv) == MOO_OBJ_GET_FLAGS_TYPE(arg));
|
||||
|
||||
if (MOO_OBJ_GET_CLASS(rcv) == moo->_class && rcv != arg)
|
||||
{
|
||||
/* a class object are supposed to be unique */
|
||||
return 0;
|
||||
}
|
||||
if (MOO_OBJ_GET_SIZE(rcv) != MOO_OBJ_GET_SIZE(arg)) return 0; /* different size, not equal */
|
||||
|
||||
switch (MOO_OBJ_GET_FLAGS_TYPE(rcv))
|
||||
{
|
||||
case MOO_OBJ_TYPE_BYTE:
|
||||
case MOO_OBJ_TYPE_CHAR:
|
||||
case MOO_OBJ_TYPE_HALFWORD:
|
||||
case MOO_OBJ_TYPE_WORD:
|
||||
return (MOO_MEMCMP (MOO_OBJ_GET_BYTE_SLOT(rcv), MOO_OBJ_GET_BYTE_SLOT(arg), MOO_BYTESOF(moo,rcv)) == 0)? 1: 0;
|
||||
|
||||
default:
|
||||
{
|
||||
if (rcv == moo->_nil) return arg == moo->_nil? 1: 0;
|
||||
if (rcv == moo->_true) return arg == moo->_true? 1: 0;
|
||||
if (rcv == moo->_false) return arg == moo->_false? 1: 0;
|
||||
|
||||
/* MOO_OBJ_TYPE_OOP, ... */
|
||||
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_TYPE(rcv) == MOO_OBJ_TYPE_OOP);
|
||||
|
||||
#if 1
|
||||
moo_seterrbfmt (moo, MOO_ENOIMPL, "no builtin comparison implemented for %O and %O", rcv, arg); /* TODO: better error code */
|
||||
return -1;
|
||||
#else
|
||||
for (i = 0; i < MOO_OBJ_GET_SIZE(rcv); i++)
|
||||
{
|
||||
/* TODO: remove recursion */
|
||||
|
||||
/* NOTE: even if the object implements the equality method,
|
||||
* this primitive method doesn't honor it. */
|
||||
if (!_equal_objects(moo, ((moo_oop_oop_t)rcv)->slot[i], ((moo_oop_oop_t)arg)->slot[i])) return 0;
|
||||
}
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_equal (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, arg;
|
||||
int n;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
n = _equal_objects (moo, rcv, arg);
|
||||
if (n <= -1) return MOO_PF_FAILURE;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, (n? moo->_true: moo->_false));
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_not_equal (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, arg;
|
||||
int n;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
n = _equal_objects (moo, rcv, arg);
|
||||
if (n <= -1) return MOO_PF_FAILURE;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, (n? moo->_false: moo->_true));
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_class (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv;
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
MOO_STACK_SETRET (moo, nargs, (moo_oop_t)MOO_CLASSOF(moo, rcv));
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_class_t _class;
|
||||
moo_oop_t szoop, obj;
|
||||
moo_oow_t size = 0; /* size of the variable/indexed part */
|
||||
|
||||
_class = (moo_oop_class_t)MOO_STACK_GETRCV(moo, nargs);
|
||||
if (MOO_CLASSOF(moo, _class) != moo->_class)
|
||||
{
|
||||
/* the receiver is not a class object */
|
||||
MOO_DEBUG1 (moo, "<pf_basic_new> Receiver is not a class - %O\n", _class);
|
||||
moo_seterrbfmt (moo, MOO_EMSGRCV, "non-class receiver - %O", _class);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
/* check if #limited is set on the class */
|
||||
if (MOO_CLASS_SELFSPEC_FLAGS(MOO_OOP_TO_SMOOI(_class->selfspec)) & MOO_CLASS_SELFSPEC_FLAG_LIMITED)
|
||||
{
|
||||
MOO_DEBUG1 (moo, "<pf_basic_new> Receiver is #limited - %O\n", _class);
|
||||
moo_seterrbfmt (moo, MOO_EPERM, "limited receiver - %O", _class);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
if (nargs >= 1)
|
||||
{
|
||||
szoop = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
if (moo_inttooow (moo, szoop, &size) <= 0)
|
||||
{
|
||||
/* integer out of range or not integer */
|
||||
MOO_DEBUG1 (moo, "<pf_basic_new> Size out of range or not integer - %O\n", szoop);
|
||||
moo_seterrbfmt (moo, MOO_EINVAL, "size out of range or not integer - %O", szoop);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (MOO_OOP_IS_SMOOI(((moo_oop_class_t)_class)->trsize))
|
||||
{
|
||||
obj = moo_instantiatewithtrailer (moo, _class, size, MOO_NULL, MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->trsize));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* moo_instantiate() will ignore size if the instance specification
|
||||
* disallows indexed(variable) parts. */
|
||||
/* TODO: should i check the specification before calling
|
||||
* moo_instantiate()? */
|
||||
obj = moo_instantiate (moo, _class, MOO_NULL, size);
|
||||
}
|
||||
if (!obj) return MOO_PF_FAILURE;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, obj);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_shallow_copy (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, obj;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
rcv = MOO_STACK_GETRCV (moo, nargs);
|
||||
|
||||
obj = moo_shallowcopy (moo, rcv);
|
||||
if (!obj) return MOO_PF_FAILURE;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, obj);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_basic_size (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
/* return the number of indexable fields */
|
||||
|
||||
moo_oop_t rcv, sz;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV (moo, nargs);
|
||||
|
||||
if (!MOO_OOP_IS_POINTER(rcv))
|
||||
{
|
||||
sz = MOO_SMOOI_TO_OOP(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
sz = moo_oowtoint (moo, MOO_OBJ_GET_SIZE(rcv));
|
||||
if (!sz) return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
MOO_STACK_SETRET(moo, nargs, sz);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_basic_at (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, pos, v;
|
||||
moo_oow_t idx;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_POINTER(rcv))
|
||||
{
|
||||
/* the receiver is a special numeric object, not a normal pointer */
|
||||
moo_seterrbfmt (moo, MOO_EMSGRCV, "receiver not indexable - %O", rcv);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
pos = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
if (moo_inttooow (moo, pos, &idx) <= 0)
|
||||
{
|
||||
/* negative integer or not integer */
|
||||
moo_seterrbfmt (moo, MOO_EINVAL, "invalid position - %O", pos);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
if (idx >= MOO_OBJ_GET_SIZE(rcv))
|
||||
{
|
||||
/* index out of range */
|
||||
moo_seterrbfmt (moo, MOO_ERANGE, "position out of bound - %O", pos);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
switch (MOO_OBJ_GET_FLAGS_TYPE(rcv))
|
||||
{
|
||||
case MOO_OBJ_TYPE_BYTE:
|
||||
v = MOO_SMOOI_TO_OOP(((moo_oop_byte_t)rcv)->slot[idx]);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_CHAR:
|
||||
v = MOO_CHAR_TO_OOP(((moo_oop_char_t)rcv)->slot[idx]);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_HALFWORD:
|
||||
/* TODO: LargeInteger if the halfword is too large */
|
||||
v = MOO_SMOOI_TO_OOP(((moo_oop_halfword_t)rcv)->slot[idx]);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_WORD:
|
||||
v = moo_oowtoint (moo, ((moo_oop_word_t)rcv)->slot[idx]);
|
||||
if (!v) return MOO_PF_FAILURE;
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_OOP:
|
||||
v = ((moo_oop_oop_t)rcv)->slot[idx];
|
||||
break;
|
||||
|
||||
default:
|
||||
moo_seterrnum (moo, MOO_EINTERN);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, v);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_basic_at_put (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, pos, val;
|
||||
moo_oow_t idx;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 2);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_POINTER(rcv))
|
||||
{
|
||||
/* the receiver is a special numeric object, not a normal pointer */
|
||||
moo_seterrbfmt (moo, MOO_EMSGRCV, "receiver not indexable - %O", rcv);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
if (MOO_OBJ_GET_FLAGS_RDONLY(rcv))
|
||||
{
|
||||
/* TODO: better error handling */
|
||||
moo_seterrbfmt (moo, MOO_EPERM, "now allowed to change a read-only object - %O", rcv);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
pos = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
val = MOO_STACK_GETARG(moo, nargs, 1);
|
||||
|
||||
if (moo_inttooow (moo, pos, &idx) <= 0)
|
||||
{
|
||||
/* negative integer or not integer */
|
||||
moo_seterrbfmt (moo, MOO_EINVAL, "invalid position - %O", pos);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
if (idx >= MOO_OBJ_GET_SIZE(rcv))
|
||||
{
|
||||
/* index out of range */
|
||||
moo_seterrbfmt (moo, MOO_ERANGE, "position out of bound - %O", pos);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
switch (MOO_OBJ_GET_FLAGS_TYPE(rcv))
|
||||
{
|
||||
case MOO_OBJ_TYPE_BYTE:
|
||||
if (!MOO_OOP_IS_SMOOI(val))
|
||||
{
|
||||
/* the value is not a character */
|
||||
moo_seterrnum (moo, MOO_EINVAL);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
/* TOOD: must I check the range of the value? */
|
||||
((moo_oop_char_t)rcv)->slot[idx] = MOO_OOP_TO_SMOOI(val);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_CHAR:
|
||||
if (!MOO_OOP_IS_CHAR(val))
|
||||
{
|
||||
/* the value is not a character */
|
||||
moo_seterrnum (moo, MOO_EINVAL);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
((moo_oop_char_t)rcv)->slot[idx] = MOO_OOP_TO_CHAR(val);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_HALFWORD:
|
||||
if (!MOO_OOP_IS_SMOOI(val))
|
||||
{
|
||||
/* the value is not a number */
|
||||
moo_seterrnum (moo, MOO_EINVAL);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
/* if the small integer is too large, it will get truncated */
|
||||
((moo_oop_halfword_t)rcv)->slot[idx] = MOO_OOP_TO_SMOOI(val);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_WORD:
|
||||
{
|
||||
moo_oow_t w;
|
||||
|
||||
if (moo_inttooow (moo, val, &w) <= 0)
|
||||
{
|
||||
/* the value is not a number, out of range, or negative */
|
||||
moo_seterrnum (moo, MOO_EINVAL);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
((moo_oop_word_t)rcv)->slot[idx] = w;
|
||||
break;
|
||||
}
|
||||
|
||||
case MOO_OBJ_TYPE_OOP:
|
||||
((moo_oop_oop_t)rcv)->slot[idx] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
moo_seterrnum (moo, MOO_EINTERN);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
|
||||
/* TODO: return receiver or value? */
|
||||
MOO_STACK_SETRET (moo, nargs, val);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_add_to_be_finalized (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
/* TODO: check if it has already been added */
|
||||
@ -2145,25 +1748,6 @@ static moo_pfrc_t pf_hash (moo_t* moo, moo_ooi_t nargs)
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_is_kind_of (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, _class;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
_class = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
if (MOO_CLASSOF(moo, _class) == moo->_class &&
|
||||
moo_iskindof(moo, rcv, (moo_oop_class_t)_class))
|
||||
{
|
||||
MOO_STACK_SETRET (moo, nargs, moo->_true);
|
||||
}
|
||||
else
|
||||
{
|
||||
MOO_STACK_SETRET (moo, nargs, moo->_false);
|
||||
}
|
||||
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_responds_to (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
@ -4322,26 +3906,23 @@ static pf_t pftab[] =
|
||||
{ "_integer_inttostr", { pf_integer_inttostr, 1, 1 } },
|
||||
|
||||
{ "Apex_addToBeFinalized", { pf_add_to_be_finalized, 0, 0 } },
|
||||
{ "Apex_basicAt:", { pf_basic_at, 1, 1 } },
|
||||
{ "Apex_basicAt:put:", { pf_basic_at_put, 2, 2 } },
|
||||
{ "Apex_basicNew", { pf_basic_new, 0, 0 } },
|
||||
{ "Apex_basicNew:", { pf_basic_new, 1, 1 } },
|
||||
{ "Apex_basicSize", { pf_basic_size, 0, 0 } },
|
||||
{ "Apex_basicNew", { pf_basic_new, 0, 0 } },
|
||||
{ "Apex_basicNew:", { pf_basic_new, 1, 1 } },
|
||||
{ "Apex_basicSize", { pf_basic_size, 0, 0 } },
|
||||
{ "Apex_class", { pf_class, 0, 0 } },
|
||||
{ "Apex_basicAt:", { moo_pf_basic_at, 1, 1 } },
|
||||
{ "Apex_basicAt:put:", { moo_pf_basic_at_put, 2, 2 } },
|
||||
{ "Apex_basicNew", { moo_pf_basic_new, 0, 0 } },
|
||||
{ "Apex_basicNew:", { moo_pf_basic_new, 1, 1 } },
|
||||
{ "Apex_basicSize", { moo_pf_basic_size, 0, 0 } },
|
||||
{ "Apex_class", { moo_pf_class, 0, 0 } },
|
||||
{ "Apex_hash", { pf_hash, 0, 0 } },
|
||||
{ "Apex_isKindOf:", { pf_is_kind_of, 1, 1, } },
|
||||
{ "Apex_perform", { pf_perform, 1, MA } },
|
||||
{ "Apex_removeToBeFinalized", { pf_remove_to_be_finalized, 0, 0 } },
|
||||
{ "Apex_respondsTo:", { pf_responds_to, 1, 1 } },
|
||||
{ "Apex_shallowCopy", { pf_shallow_copy, 0, 0 } },
|
||||
{ "Apex_shallowCopy", { moo_pf_shallow_copy, 0, 0 } },
|
||||
|
||||
{ "Apex_==", { pf_identical, 1, 1 } },
|
||||
{ "Apex_~~", { pf_not_identical, 1, 1 } },
|
||||
{ "Apex_=", { pf_equal, 1, 1 } },
|
||||
{ "Apex_~=", { pf_not_equal, 1, 1 } },
|
||||
{ "Apex_==", { moo_pf_identical, 1, 1 } },
|
||||
{ "Apex_~~", { moo_pf_not_identical, 1, 1 } },
|
||||
{ "Apex_=", { moo_pf_equal, 1, 1 } },
|
||||
{ "Apex_~=", { moo_pf_not_equal, 1, 1 } },
|
||||
|
||||
{ "BlockContext_value", { pf_block_value, 0, MA } },
|
||||
{ "BlockContext_newProcess", { pf_block_new_process, 0, MA } },
|
||||
|
@ -332,15 +332,13 @@
|
||||
module search path. */
|
||||
#undef LT_MODULE_PATH_VAR
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Define to the shared library suffix, say, ".dylib". */
|
||||
#undef LT_SHARED_EXT
|
||||
|
||||
/* Define to the shared archive member specification, say "(shr.o)". */
|
||||
#undef LT_SHARED_LIB_MEMBER
|
||||
|
||||
/* enable dynamic module capability */
|
||||
#undef MOO_ENABLE_DYNAMIC_MODULE
|
||||
|
||||
@ -578,5 +576,5 @@
|
||||
/* Define so that glibc/gnulib argp.h does not typedef error_t. */
|
||||
#undef __error_t_defined
|
||||
|
||||
/* Define to a type to use for 'error_t' if it is not otherwise available. */
|
||||
/* Define to a type to use for `error_t' if it is not otherwise available. */
|
||||
#undef error_t
|
||||
|
@ -1297,6 +1297,24 @@ moo_pfbase_t* moo_querymod (
|
||||
);
|
||||
|
||||
|
||||
/* ========================================================================= */
|
||||
/* pf-basic.c */
|
||||
/* ========================================================================= */
|
||||
moo_pfrc_t moo_pf_identical (moo_t* moo, moo_ooi_t nargs);
|
||||
moo_pfrc_t moo_pf_not_identical (moo_t* moo, moo_ooi_t nargs);
|
||||
moo_pfrc_t moo_pf_equal (moo_t* moo, moo_ooi_t nargs);
|
||||
moo_pfrc_t moo_pf_not_equal (moo_t* moo, moo_ooi_t nargs);
|
||||
|
||||
moo_pfrc_t moo_pf_basic_new (moo_t* moo, moo_ooi_t nargs);
|
||||
moo_pfrc_t moo_pf_shallow_copy (moo_t* moo, moo_ooi_t nargs);
|
||||
|
||||
moo_pfrc_t moo_pf_class (moo_t* moo, moo_ooi_t nargs);
|
||||
moo_pfrc_t moo_pf_basic_size (moo_t* moo, moo_ooi_t nargs);
|
||||
moo_pfrc_t moo_pf_basic_at (moo_t* moo, moo_ooi_t nargs);
|
||||
moo_pfrc_t moo_pf_basic_at_put (moo_t* moo, moo_ooi_t nargs);
|
||||
|
||||
moo_pfrc_t moo_pf_is_kind_of (moo_t* moo, moo_ooi_t nargs);
|
||||
|
||||
/* TODO: remove the following debugging functions */
|
||||
/* ========================================================================= */
|
||||
/* debug.c */
|
||||
|
462
moo/lib/pf-basic.c
Normal file
462
moo/lib/pf-basic.c
Normal file
@ -0,0 +1,462 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
Copyright (c) 2014-2017 Chung, Hyung-Hwan. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WAfRRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "moo-prv.h"
|
||||
|
||||
/* --------------------------------------------------------------------------------
|
||||
* COMPARISON
|
||||
* -------------------------------------------------------------------------------- */
|
||||
|
||||
moo_pfrc_t moo_pf_identical (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, arg, b;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
b = (rcv == arg)? moo->_true: moo->_false;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, b);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
moo_pfrc_t moo_pf_not_identical (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, arg, b;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
b = (rcv != arg)? moo->_true: moo->_false;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, b);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static int _equal_objects (moo_t* moo, moo_oop_t rcv, moo_oop_t arg)
|
||||
{
|
||||
int rtag;
|
||||
|
||||
if (rcv == arg) return 1; /* identical. so equal */
|
||||
|
||||
rtag = MOO_OOP_GET_TAG(rcv);
|
||||
if (rtag != MOO_OOP_GET_TAG(arg)) return 0;
|
||||
|
||||
switch (rtag)
|
||||
{
|
||||
case MOO_OOP_TAG_SMOOI:
|
||||
return MOO_OOP_TO_SMOOI(rcv) == MOO_OOP_TO_SMOOI(arg)? 1: 0;
|
||||
|
||||
case MOO_OOP_TAG_SMPTR:
|
||||
return MOO_OOP_TO_SMPTR(rcv) == MOO_OOP_TO_SMPTR(arg)? 1: 0;
|
||||
|
||||
case MOO_OOP_TAG_CHAR:
|
||||
return MOO_OOP_TO_CHAR(rcv) == MOO_OOP_TO_CHAR(arg)? 1: 0;
|
||||
|
||||
case MOO_OOP_TAG_ERROR:
|
||||
return MOO_OOP_TO_ERROR(rcv) == MOO_OOP_TO_ERROR(arg)? 1: 0;
|
||||
|
||||
default:
|
||||
{
|
||||
MOO_ASSERT (moo, MOO_OOP_IS_POINTER(rcv));
|
||||
|
||||
if (MOO_OBJ_GET_CLASS(rcv) != MOO_OBJ_GET_CLASS(arg)) return 0; /* different class, not equal */
|
||||
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_TYPE(rcv) == MOO_OBJ_GET_FLAGS_TYPE(arg));
|
||||
|
||||
if (MOO_OBJ_GET_CLASS(rcv) == moo->_class && rcv != arg)
|
||||
{
|
||||
/* a class object are supposed to be unique */
|
||||
return 0;
|
||||
}
|
||||
if (MOO_OBJ_GET_SIZE(rcv) != MOO_OBJ_GET_SIZE(arg)) return 0; /* different size, not equal */
|
||||
|
||||
switch (MOO_OBJ_GET_FLAGS_TYPE(rcv))
|
||||
{
|
||||
case MOO_OBJ_TYPE_BYTE:
|
||||
case MOO_OBJ_TYPE_CHAR:
|
||||
case MOO_OBJ_TYPE_HALFWORD:
|
||||
case MOO_OBJ_TYPE_WORD:
|
||||
return (MOO_MEMCMP (MOO_OBJ_GET_BYTE_SLOT(rcv), MOO_OBJ_GET_BYTE_SLOT(arg), MOO_BYTESOF(moo,rcv)) == 0)? 1: 0;
|
||||
|
||||
default:
|
||||
{
|
||||
if (rcv == moo->_nil) return arg == moo->_nil? 1: 0;
|
||||
if (rcv == moo->_true) return arg == moo->_true? 1: 0;
|
||||
if (rcv == moo->_false) return arg == moo->_false? 1: 0;
|
||||
|
||||
/* MOO_OBJ_TYPE_OOP, ... */
|
||||
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_TYPE(rcv) == MOO_OBJ_TYPE_OOP);
|
||||
|
||||
#if 1
|
||||
moo_seterrbfmt (moo, MOO_ENOIMPL, "no builtin comparison implemented for %O and %O", rcv, arg); /* TODO: better error code */
|
||||
return -1;
|
||||
#else
|
||||
for (i = 0; i < MOO_OBJ_GET_SIZE(rcv); i++)
|
||||
{
|
||||
/* TODO: remove recursion */
|
||||
|
||||
/* NOTE: even if the object implements the equality method,
|
||||
* this primitive method doesn't honor it. */
|
||||
if (!_equal_objects(moo, ((moo_oop_oop_t)rcv)->slot[i], ((moo_oop_oop_t)arg)->slot[i])) return 0;
|
||||
}
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
moo_pfrc_t moo_pf_equal (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, arg;
|
||||
int n;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
n = _equal_objects (moo, rcv, arg);
|
||||
if (n <= -1) return MOO_PF_FAILURE;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, (n? moo->_true: moo->_false));
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
moo_pfrc_t moo_pf_not_equal (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, arg;
|
||||
int n;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
n = _equal_objects (moo, rcv, arg);
|
||||
if (n <= -1) return MOO_PF_FAILURE;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, (n? moo->_false: moo->_true));
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------------
|
||||
* INSTANTIATION
|
||||
* -------------------------------------------------------------------------------- */
|
||||
|
||||
moo_pfrc_t moo_pf_basic_new (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_class_t _class;
|
||||
moo_oop_t szoop, obj;
|
||||
moo_oow_t size = 0; /* size of the variable/indexed part */
|
||||
|
||||
_class = (moo_oop_class_t)MOO_STACK_GETRCV(moo, nargs);
|
||||
if (MOO_CLASSOF(moo, _class) != moo->_class)
|
||||
{
|
||||
/* the receiver is not a class object */
|
||||
moo_seterrbfmt (moo, MOO_EMSGRCV, "non-class receiver - %O", _class);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
/* check if #limited is set on the class */
|
||||
if (MOO_CLASS_SELFSPEC_FLAGS(MOO_OOP_TO_SMOOI(_class->selfspec)) & MOO_CLASS_SELFSPEC_FLAG_LIMITED)
|
||||
{
|
||||
moo_seterrbfmt (moo, MOO_EPERM, "limited receiver - %O", _class);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
if (nargs >= 1)
|
||||
{
|
||||
szoop = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
if (moo_inttooow (moo, szoop, &size) <= 0)
|
||||
{
|
||||
/* integer out of range or not integer */
|
||||
moo_seterrbfmt (moo, MOO_EINVAL, "size out of range or not integer - %O", szoop);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (MOO_OOP_IS_SMOOI(((moo_oop_class_t)_class)->trsize))
|
||||
{
|
||||
obj = moo_instantiatewithtrailer (moo, _class, size, MOO_NULL, MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->trsize));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* moo_instantiate() will ignore size if the instance specification
|
||||
* disallows indexed(variable) parts. */
|
||||
/* TODO: should i check the specification before calling
|
||||
* moo_instantiate()? */
|
||||
obj = moo_instantiate (moo, _class, MOO_NULL, size);
|
||||
}
|
||||
if (!obj) return MOO_PF_FAILURE;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, obj);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
moo_pfrc_t moo_pf_shallow_copy (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, obj;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
rcv = MOO_STACK_GETRCV (moo, nargs);
|
||||
|
||||
obj = moo_shallowcopy (moo, rcv);
|
||||
if (!obj) return MOO_PF_FAILURE;
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, obj);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------------
|
||||
* BASIC ACCESS
|
||||
* -------------------------------------------------------------------------------- */
|
||||
|
||||
moo_pfrc_t moo_pf_class (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv;
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
MOO_STACK_SETRET (moo, nargs, (moo_oop_t)MOO_CLASSOF(moo, rcv));
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
moo_pfrc_t moo_pf_basic_size (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
/* return the number of indexable fields */
|
||||
|
||||
moo_oop_t rcv, sz;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV (moo, nargs);
|
||||
|
||||
if (!MOO_OOP_IS_POINTER(rcv))
|
||||
{
|
||||
sz = MOO_SMOOI_TO_OOP(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
sz = moo_oowtoint (moo, MOO_OBJ_GET_SIZE(rcv));
|
||||
if (!sz) return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
MOO_STACK_SETRET(moo, nargs, sz);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
moo_pfrc_t moo_pf_basic_at (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, pos, v;
|
||||
moo_oow_t idx;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_POINTER(rcv))
|
||||
{
|
||||
/* the receiver is a special numeric object, not a normal pointer */
|
||||
moo_seterrbfmt (moo, MOO_EMSGRCV, "receiver not indexable - %O", rcv);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
pos = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
if (moo_inttooow (moo, pos, &idx) <= 0)
|
||||
{
|
||||
/* negative integer or not integer */
|
||||
moo_seterrbfmt (moo, MOO_EINVAL, "invalid position - %O", pos);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
if (idx >= MOO_OBJ_GET_SIZE(rcv))
|
||||
{
|
||||
/* index out of range */
|
||||
moo_seterrbfmt (moo, MOO_ERANGE, "position out of bound - %O", pos);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
switch (MOO_OBJ_GET_FLAGS_TYPE(rcv))
|
||||
{
|
||||
case MOO_OBJ_TYPE_BYTE:
|
||||
v = MOO_SMOOI_TO_OOP(((moo_oop_byte_t)rcv)->slot[idx]);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_CHAR:
|
||||
v = MOO_CHAR_TO_OOP(((moo_oop_char_t)rcv)->slot[idx]);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_HALFWORD:
|
||||
/* TODO: LargeInteger if the halfword is too large */
|
||||
v = MOO_SMOOI_TO_OOP(((moo_oop_halfword_t)rcv)->slot[idx]);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_WORD:
|
||||
v = moo_oowtoint (moo, ((moo_oop_word_t)rcv)->slot[idx]);
|
||||
if (!v) return MOO_PF_FAILURE;
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_OOP:
|
||||
v = ((moo_oop_oop_t)rcv)->slot[idx];
|
||||
break;
|
||||
|
||||
default:
|
||||
moo_seterrnum (moo, MOO_EINTERN);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, v);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
moo_pfrc_t moo_pf_basic_at_put (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, pos, val;
|
||||
moo_oow_t idx;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 2);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_POINTER(rcv))
|
||||
{
|
||||
/* the receiver is a special numeric object, not a normal pointer */
|
||||
moo_seterrbfmt (moo, MOO_EMSGRCV, "receiver not indexable - %O", rcv);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
if (MOO_OBJ_GET_FLAGS_RDONLY(rcv))
|
||||
{
|
||||
/* TODO: better error handling */
|
||||
moo_seterrbfmt (moo, MOO_EPERM, "now allowed to change a read-only object - %O", rcv);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
pos = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
val = MOO_STACK_GETARG(moo, nargs, 1);
|
||||
|
||||
if (moo_inttooow (moo, pos, &idx) <= 0)
|
||||
{
|
||||
/* negative integer or not integer */
|
||||
moo_seterrbfmt (moo, MOO_EINVAL, "invalid position - %O", pos);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
if (idx >= MOO_OBJ_GET_SIZE(rcv))
|
||||
{
|
||||
/* index out of range */
|
||||
moo_seterrbfmt (moo, MOO_ERANGE, "position out of bound - %O", pos);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
switch (MOO_OBJ_GET_FLAGS_TYPE(rcv))
|
||||
{
|
||||
case MOO_OBJ_TYPE_BYTE:
|
||||
if (!MOO_OOP_IS_SMOOI(val))
|
||||
{
|
||||
/* the value is not a character */
|
||||
moo_seterrnum (moo, MOO_EINVAL);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
/* TOOD: must I check the range of the value? */
|
||||
((moo_oop_char_t)rcv)->slot[idx] = MOO_OOP_TO_SMOOI(val);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_CHAR:
|
||||
if (!MOO_OOP_IS_CHAR(val))
|
||||
{
|
||||
/* the value is not a character */
|
||||
moo_seterrnum (moo, MOO_EINVAL);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
((moo_oop_char_t)rcv)->slot[idx] = MOO_OOP_TO_CHAR(val);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_HALFWORD:
|
||||
if (!MOO_OOP_IS_SMOOI(val))
|
||||
{
|
||||
/* the value is not a number */
|
||||
moo_seterrnum (moo, MOO_EINVAL);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
/* if the small integer is too large, it will get truncated */
|
||||
((moo_oop_halfword_t)rcv)->slot[idx] = MOO_OOP_TO_SMOOI(val);
|
||||
break;
|
||||
|
||||
case MOO_OBJ_TYPE_WORD:
|
||||
{
|
||||
moo_oow_t w;
|
||||
|
||||
if (moo_inttooow (moo, val, &w) <= 0)
|
||||
{
|
||||
/* the value is not a number, out of range, or negative */
|
||||
moo_seterrnum (moo, MOO_EINVAL);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
((moo_oop_word_t)rcv)->slot[idx] = w;
|
||||
break;
|
||||
}
|
||||
|
||||
case MOO_OBJ_TYPE_OOP:
|
||||
((moo_oop_oop_t)rcv)->slot[idx] = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
moo_seterrnum (moo, MOO_EINTERN);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
|
||||
/* TODO: return receiver or value? */
|
||||
MOO_STACK_SETRET (moo, nargs, val);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------------
|
||||
* BASIC QUERY
|
||||
* -------------------------------------------------------------------------------- */
|
||||
|
||||
moo_pfrc_t moo_pf_is_kind_of (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, _class;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
_class = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
|
||||
if (MOO_CLASSOF(moo, _class) == moo->_class &&
|
||||
moo_iskindof(moo, rcv, (moo_oop_class_t)_class))
|
||||
{
|
||||
MOO_STACK_SETRET (moo, nargs, moo->_true);
|
||||
}
|
||||
else
|
||||
{
|
||||
MOO_STACK_SETRET (moo, nargs, moo->_false);
|
||||
}
|
||||
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
Reference in New Issue
Block a user