diff --git a/moo/configure b/moo/configure index e947686..43d3822 100755 --- a/moo/configure +++ b/moo/configure @@ -18591,7 +18591,7 @@ __builtin_memset ((void*)1, ' ', 10); return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -18602,7 +18602,8 @@ else $as_echo "no" >&6; } fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_memcpy" >&5 $as_echo_n "checking for __builtin_memcpy... " >&6; } @@ -18617,7 +18618,7 @@ __builtin_memcpy ((void*)1, (void*)2, 10); return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -18628,7 +18629,8 @@ else $as_echo "no" >&6; } fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_memmove" >&5 $as_echo_n "checking for __builtin_memmove... " >&6; } @@ -18643,7 +18645,7 @@ __builtin_memmove ((void*)1, (void*)2, 10); return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -18654,7 +18656,8 @@ else $as_echo "no" >&6; } fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_memcmp" >&5 $as_echo_n "checking for __builtin_memcmp... " >&6; } @@ -18669,7 +18672,7 @@ int a = __builtin_memcmp ((void*)1, (void*)2, 10); return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : +if ac_fn_c_try_link "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } @@ -18680,7 +18683,8 @@ else $as_echo "no" >&6; } fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking computed goto usability" >&5 $as_echo_n "checking computed goto usability... " >&6; } diff --git a/moo/configure.ac b/moo/configure.ac index 1c6048f..2850baf 100644 --- a/moo/configure.ac +++ b/moo/configure.ac @@ -109,7 +109,7 @@ AC_SUBST(LIBM, $LIBM) dnl check some compiler builtins AC_MSG_CHECKING([for __builtin_memset]) -AC_COMPILE_IFELSE( +AC_LINK_IFELSE( [AC_LANG_PROGRAM([], [__builtin_memset ((void*)1, ' ', 10);])], [AC_MSG_RESULT(yes) AC_DEFINE([HAVE___BUILTIN_MEMSET], [1], [__builtin_memset])], @@ -117,7 +117,7 @@ AC_COMPILE_IFELSE( ) AC_MSG_CHECKING([for __builtin_memcpy]) -AC_COMPILE_IFELSE( +AC_LINK_IFELSE( [AC_LANG_PROGRAM([], [__builtin_memcpy ((void*)1, (void*)2, 10);])], [AC_MSG_RESULT(yes) AC_DEFINE([HAVE___BUILTIN_MEMCPY], [1], [__builtin_memcpy])], @@ -125,7 +125,7 @@ AC_COMPILE_IFELSE( ) AC_MSG_CHECKING([for __builtin_memmove]) -AC_COMPILE_IFELSE( +AC_LINK_IFELSE( [AC_LANG_PROGRAM([], [__builtin_memmove ((void*)1, (void*)2, 10);])], [AC_MSG_RESULT(yes) AC_DEFINE([HAVE___BUILTIN_MEMMOVE], [1], [__builtin_memmove])], @@ -133,7 +133,7 @@ AC_COMPILE_IFELSE( ) AC_MSG_CHECKING([for __builtin_memcmp]) -AC_COMPILE_IFELSE( +AC_LINK_IFELSE( [AC_LANG_PROGRAM([], [int a = __builtin_memcmp ((void*)1, (void*)2, 10);])], [AC_MSG_RESULT(yes) AC_DEFINE([HAVE___BUILTIN_MEMCMP], [1], [__builtin_memcmp])], diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 6d50d61..835e59d 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -1,5 +1,5 @@ -class(#pointer) Process(Object) +class(#pointer,#limited) Process(Object) { var initial_context, current_context, state, sp, prev, next, sem, perr. @@ -345,7 +345,7 @@ class SemaphoreHeap(Object) } } -class ProcessScheduler(Object) +class(#limited) ProcessScheduler(Object) { var tally, active, runnable_head, runnable_tail, sem_heap. diff --git a/moo/lib/comp.c b/moo/lib/comp.c index b2b3cdf..5348493 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -50,7 +50,8 @@ enum class_mod_t { - CLASS_INDEXED = (1 << 0) + CLASS_INDEXED = (1 << 0), + CLASS_LIMITED = (1 << 1) }; enum var_type_t @@ -107,6 +108,7 @@ static struct voca_t { 6, { 'i','m','p','o','r','t' } }, { 8, { '#','i','n','c','l','u','d','e' } }, { 8, { '#','l','i','b','e','r','a','l' } }, + { 8, { '#','l','i','m','i','t','e','d' } }, { 7, { '#','l','i','w','o','r','d' } }, { 6, { 'm','e','t','h','o','d' } }, { 3, { 'n','i','l' } }, @@ -163,6 +165,7 @@ enum voca_id_t VOCA_IMPORT, VOCA_INCLUDE_S, VOCA_LIBERAL_S, + VOCA_LIMITED_S, VOCA_LIWORD_S, VOCA_METHOD, VOCA_NIL, @@ -6545,6 +6548,19 @@ static int make_defined_class (moo_t* moo) return 0; } +static MOO_INLINE int _set_class_indexed_type (moo_t* moo, moo_obj_type_t type) +{ + if (moo->c->cls.flags & CLASS_INDEXED) + { + set_syntax_error (moo, MOO_SYNERR_MODIFIERDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + moo->c->cls.flags |= CLASS_INDEXED; + moo->c->cls.indexed_type = type; + return 0; +} + static int __compile_class_definition (moo_t* moo, int extend) { /* @@ -6570,9 +6586,80 @@ static int __compile_class_definition (moo_t* moo, int extend) if (!extend && TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN) { /* process class modifiers */ + MOO_ASSERT (moo, (moo->c->cls.flags & CLASS_INDEXED) == 0); GET_TOKEN (moo); + if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) + { + do + { + if (is_token_symbol(moo, VOCA_BYTE_S)) + { + /* class(#byte) */ + if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_BYTE) <= -1) return -1; + GET_TOKEN (moo); + } + else if (is_token_symbol(moo, VOCA_CHARACTER_S)) + { + /* class(#character) */ + if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_CHAR) <= -1) return -1; + GET_TOKEN (moo); + } + else if (is_token_symbol(moo, VOCA_HALFWORD_S)) + { + /* class(#halfword) */ + if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_HALFWORD) <= -1) return -1; + GET_TOKEN (moo); + } + else if (is_token_symbol(moo, VOCA_WORD_S)) + { + /* class(#word) */ + if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_WORD) <= -1) return -1; + GET_TOKEN (moo); + } + else if (is_token_symbol(moo, VOCA_POINTER_S)) + { + /* class(#pointer) */ + if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_OOP) <= -1) return -1; + GET_TOKEN (moo); + } + else if (is_token_symbol(moo, VOCA_LIWORD_S)) + { + /* class(#liword) */ + if (_set_class_indexed_type (moo, MOO_OBJ_TYPE_LIWORD) <= -1) return -1; + GET_TOKEN (moo); + } + else if (is_token_symbol(moo, VOCA_LIMITED_S)) + { + if (moo->c->cls.flags & CLASS_LIMITED) + { + set_syntax_error (moo, MOO_SYNERR_MODIFIERDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + moo->c->cls.flags |= CLASS_LIMITED; + GET_TOKEN(moo); + } + else if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) + { + /* no modifier is present */ + set_syntax_error (moo, MOO_SYNERR_MODIFIER, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + else + { + /* invalid modifier */ + set_syntax_error (moo, MOO_SYNERR_MODIFIERINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) break; /* hopefully ) */ + GET_TOKEN (moo); /* get the token after , */ + } + while (1); + } + +#if 0 if (is_token_symbol(moo, VOCA_BYTE_S)) { /* class(#byte) */ @@ -6615,6 +6702,7 @@ static int __compile_class_definition (moo_t* moo, int extend) moo->c->cls.indexed_type = MOO_OBJ_TYPE_LIWORD; GET_TOKEN (moo); } +#endif if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) {