diff --git a/moo/kernel/System.moo b/moo/kernel/System.moo index 9dbebf8..ec3ce33 100644 --- a/moo/kernel/System.moo +++ b/moo/kernel/System.moo @@ -33,21 +33,30 @@ extend System ## output production from the moo code. ## System logNl: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'. ## + method(#class,#variadic,#primitive) log(level,msg1). + +(* +TODO: how to pass all variadic arguments to another variadic methods??? + method(#class,#variadic) logInfo (msg1) + { + ^self log (System.Log.INFO,msg1) + } +*) method(#class) atLevel: level log: message { - + ## do nothing upon logging failure } method(#class) atLevel: level log: message and: message2 { - + ## do nothing upon logging failure } method(#class) atLevel: level log: message and: message2 and: message3 { - + ## do nothing upon logging failure } @@ -88,7 +97,7 @@ extend System { ^self atLevel: System.Log.INFO logNl: message and: message2. } - + (* nsdic access *) method(#class) at: key { diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 8c29e20..7eeaafb 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -3433,6 +3433,140 @@ static int compile_class_level_imports (moo_t* moo) return 0; } +static int compile_class_level_constants (moo_t* moo) +{ +#if 0 + if (moo->c->cls.self_oop) + { + /* the current class has been created already */ + } + else + { + } +#endif + if (TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN) + { + /* process variable declaration modifiers */ + GET_TOKEN (moo); + + if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) + { + do + { + /* [NOTE] no modifier is supported for constant declarations. + * the following code is for consistency sake only */ + 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 (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) + { + /* ) expected */ + set_syntax_error (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + GET_TOKEN (moo); + } + + /* variable declaration */ + do + { + if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) + { + var_info_t var; + +#if 0 + if (dcl_type == VAR_INSTANCE && (moo->c->cls.flags & CLASS_INDEXED) && (moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP)) + { + set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + if (find_class_level_variable(moo, MOO_NULL, TOKEN_NAME(moo), &var) >= 0 || + moo_lookupdic (moo, (moo_oop_dic_t)moo->sysdic, TOKEN_NAME(moo)) || /* conflicts with a top global name */ + moo_lookupdic (moo, (moo_oop_dic_t)moo->c->cls.ns_oop, TOKEN_NAME(moo))) /* conflicts with a global name in the class'es name space */ + { + set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + if (add_class_level_variable(moo, dcl_type, TOKEN_NAME(moo)) <= -1) return -1; +#endif + + GET_TOKEN (moo); + + if (TOKEN_TYPE(moo) == MOO_IOTOK_ASSIGN) + { + moo_oop_t lit; + + GET_TOKEN (moo); /* skip := and go on the the value token */ + + /* [NOTE] default value assignment. only a literal is allowed + * the initial values for instance variables and + * class instance variables are set to read-only. + * this is likely to change if the actual initial + * value assignment upon instantiation employes + * deep-copying in moo_instantiate() and in the compiler. */ + lit = token_to_literal (moo, 1); + if (!lit) return -1; + + /* TODO: store the constannt value... */ + + GET_TOKEN (moo); + } + else + { + set_syntax_error (moo, MOO_SYNERR_ASSIGN, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + } + else if (TOKEN_TYPE(moo) == MOO_IOTOK_COMMA || TOKEN_TYPE(moo) == MOO_IOTOK_EOF || TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD) + { + /* no variable name is present */ + set_syntax_error (moo, MOO_SYNERR_VARNAMEDUPL, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + else + { + break; + } + + if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT) + { + set_syntax_error (moo, MOO_SYNERR_COMMA, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + else if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA) break; /* hopefully . */ + GET_TOKEN (moo); + } + while (1); + + if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD) + { + set_syntax_error (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo)); + return -1; + } + + GET_TOKEN (moo); + return 0; +} + static int compile_unary_method_name (moo_t* moo) { MOO_ASSERT (moo, moo->c->mth.name.len == 0); @@ -3870,7 +4004,7 @@ static int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, const moo_iolo /* indicate that it's not a global variable */ return 1; } - goto self_no_class_level; + goto self_not_class_level; } else { @@ -3882,8 +4016,8 @@ static int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, const moo_iolo { if (moo->c->cls.self_oop) { - self_no_class_level: - top_dic = moo->c->cls.self_oop->nsdic; + self_not_class_level: + top_dic = moo->c->cls.ns_oop; if ((moo_oop_t)top_dic == moo->_nil) top_dic = MOO_NULL; xname.ptr += 5; xname.len -= 5; @@ -7070,6 +7204,12 @@ static int __compile_class_definition (moo_t* moo, int extend) GET_TOKEN (moo); if (compile_class_level_imports(moo) <= -1) return -1; } + else if (is_token_word(moo, VOCA_CONST) || is_token_word(moo, VOCA_CONSTANT)) + { + /* constant declaration */ + GET_TOKEN (moo); + if (compile_class_level_constants(moo) <= -1) return -1; + } else break; } while (1); @@ -7107,6 +7247,12 @@ static int __compile_class_definition (moo_t* moo, int extend) GET_TOKEN (moo); if (compile_method_definition(moo) <= -1) return -1; } + else if (is_token_word(moo, VOCA_CONST) || is_token_word(moo, VOCA_CONSTANT)) + { + /* constant declaration */ + GET_TOKEN (moo); + if (compile_class_level_constants(moo) <= -1) return -1; + } else break; } while (1); diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 64e335e..d73a8b3 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1262,72 +1262,6 @@ start_over: } } -static moo_pfrc_t pf_log (moo_t* moo, moo_ooi_t nargs) -{ - moo_oop_t msg, level; - moo_oow_t mask; - moo_ooi_t k; - - MOO_ASSERT (moo, nargs >= 2); - - level = MOO_STACK_GETARG(moo, nargs, 0); - if (!MOO_OOP_IS_SMOOI(level)) mask = MOO_LOG_APP | MOO_LOG_INFO; - else mask = MOO_LOG_APP | MOO_OOP_TO_SMOOI(level); - - for (k = 1; k < nargs; k++) - { - msg = MOO_STACK_GETARG (moo, nargs, k); - - if (msg == moo->_nil || msg == moo->_true || msg == moo->_false) - { - goto dump_object; - } - else if (MOO_OOP_IS_POINTER(msg)) - { - if (MOO_OBJ_GET_FLAGS_TYPE(msg) == MOO_OBJ_TYPE_CHAR) - { - log_char_object (moo, mask, (moo_oop_char_t)msg); - } - else if (MOO_OBJ_GET_FLAGS_TYPE(msg) == MOO_OBJ_TYPE_OOP) - { - /* visit only 1-level down into an array-like object */ - moo_oop_t inner; - moo_oop_class_t _class; - moo_oow_t i, spec; - - _class = MOO_CLASSOF(moo, msg); - - spec = MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->spec); - if (MOO_CLASS_SPEC_NAMED_INSTVARS(spec) > 0 || !MOO_CLASS_SPEC_IS_INDEXED(spec)) goto dump_object; - - for (i = 0; i < MOO_OBJ_GET_SIZE(msg); i++) - { - inner = ((moo_oop_oop_t)msg)->slot[i]; - - if (i > 0) moo_logbfmt (moo, mask, " "); - if (MOO_OOP_IS_POINTER(inner) && - MOO_OBJ_GET_FLAGS_TYPE(inner) == MOO_OBJ_TYPE_CHAR) - { - log_char_object (moo, mask, (moo_oop_char_t)inner); - } - else - { - moo_logbfmt (moo, mask, "%O", inner); - } - } - } - else goto dump_object; - } - else - { - dump_object: - moo_logbfmt (moo, mask, "%O", msg); - } - } - - MOO_STACK_SETRETTORCV (moo, nargs); /* ^self */ - return MOO_PF_SUCCESS; -} static moo_pfrc_t pf_identical (moo_t* moo, moo_ooi_t nargs) { @@ -2975,6 +2909,76 @@ static moo_pfrc_t pf_strlen (moo_t* moo, moo_ooi_t nargs) return MOO_PF_SUCCESS; } +/* ------------------------------------------------------------------ */ + +static moo_pfrc_t pf_system_log (moo_t* moo, moo_ooi_t nargs) +{ + moo_oop_t msg, level; + moo_oow_t mask; + moo_ooi_t k; + + MOO_ASSERT (moo, nargs >= 2); + +/* TODO: enhance this primitive */ + level = MOO_STACK_GETARG(moo, nargs, 0); + if (!MOO_OOP_IS_SMOOI(level)) mask = MOO_LOG_APP | MOO_LOG_INFO; + else mask = MOO_LOG_APP | MOO_OOP_TO_SMOOI(level); + + for (k = 1; k < nargs; k++) + { + msg = MOO_STACK_GETARG (moo, nargs, k); + + if (msg == moo->_nil || msg == moo->_true || msg == moo->_false) + { + goto dump_object; + } + else if (MOO_OOP_IS_POINTER(msg)) + { + if (MOO_OBJ_GET_FLAGS_TYPE(msg) == MOO_OBJ_TYPE_CHAR) + { + log_char_object (moo, mask, (moo_oop_char_t)msg); + } + else if (MOO_OBJ_GET_FLAGS_TYPE(msg) == MOO_OBJ_TYPE_OOP) + { + /* visit only 1-level down into an array-like object */ + moo_oop_t inner; + moo_oop_class_t _class; + moo_oow_t i, spec; + + _class = MOO_CLASSOF(moo, msg); + + spec = MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->spec); + if (MOO_CLASS_SPEC_NAMED_INSTVARS(spec) > 0 || !MOO_CLASS_SPEC_IS_INDEXED(spec)) goto dump_object; + + for (i = 0; i < MOO_OBJ_GET_SIZE(msg); i++) + { + inner = ((moo_oop_oop_t)msg)->slot[i]; + + if (i > 0) moo_logbfmt (moo, mask, " "); + if (MOO_OOP_IS_POINTER(inner) && + MOO_OBJ_GET_FLAGS_TYPE(inner) == MOO_OBJ_TYPE_CHAR) + { + log_char_object (moo, mask, (moo_oop_char_t)inner); + } + else + { + moo_logbfmt (moo, mask, "%O", inner); + } + } + } + else goto dump_object; + } + else + { + dump_object: + moo_logbfmt (moo, mask, "%O", msg); + } + } + + MOO_STACK_SETRETTORCV (moo, nargs); /* ^self */ + return MOO_PF_SUCCESS; +} + static MOO_INLINE moo_pfrc_t _system_alloc (moo_t* moo, moo_ooi_t nargs, int clear) { moo_oop_t tmp; @@ -3734,7 +3738,7 @@ typedef struct pf_t pf_t; static pf_t pftab[] = { { "_dump", { pf_dump, 0, MA } }, - { "_log", { pf_log, 2, MA } }, + { "_identical", { pf_identical, 1, 1 } }, { "_not_identical", { pf_not_identical, 1, 1 } }, @@ -3855,6 +3859,8 @@ static pf_t pftab[] = { "System__putUint16", { pf_system_put_uint16, 3, 3 } }, { "System__putUint32", { pf_system_put_uint32, 3, 3 } }, { "System__putUint64", { pf_system_put_uint64, 3, 3 } }, + + { "System_log", { pf_system_log, 2, MA } } }; moo_pfbase_t* moo_getpfnum (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len, moo_ooi_t* pfnum) diff --git a/moo/lib/logfmt.c b/moo/lib/logfmt.c index 4065c8a..ca765a3 100644 --- a/moo/lib/logfmt.c +++ b/moo/lib/logfmt.c @@ -607,7 +607,6 @@ static int _logufmtv (moo_t* moo, const moo_uch_t* fmt, moo_fmtout_t* data, va_l return __logufmtv (moo, fmt, data, ap, moo_logbfmt); } - moo_ooi_t moo_logbfmt (moo_t* moo, moo_oow_t mask, const moo_bch_t* fmt, ...) { int x; diff --git a/moo/lib/main.c b/moo/lib/main.c index ed8f09e..046dba7 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -670,9 +670,6 @@ static void log_write (moo_t* moo, moo_oow_t mask, const moo_ooch_t* msg, moo_oo struct tm tm, *tmp; time_t now; - -if (mask & MOO_LOG_GC) return; /* don't show gc logs */ - /* TODO: beautify the log message. * do classification based on mask. */ @@ -1737,14 +1734,20 @@ int main (int argc, char* argv[]) moo_setoption (moo, MOO_SYSDIC_SIZE, &tab_size); tab_size = 600; moo_setoption (moo, MOO_PROCSTK_SIZE, &tab_size); + + } { - int trait = 0; + unsigned int trait = 0; /*trait |= MOO_NOGC;*/ trait |= MOO_AWAIT_PROCS; moo_setoption (moo, MOO_TRAIT, &trait); + + /* disable GC logs */ + trait = ~MOO_LOG_GC; + moo_setoption (moo, MOO_LOG_MASK, &trait); } if (moo_ignite(moo) <= -1) diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 1c7beab..aba0274 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -296,7 +296,7 @@ int moo_getoption (moo_t* moo, moo_option_t id, void* value) return 0; case MOO_LOG_MAXCAPA: - *(moo_oow_t*)value = moo->option.log_mask; + *(moo_oow_t*)value = moo->option.log_maxcapa; return 0; case MOO_SYMTAB_SIZE: diff --git a/moo/lib/moo.h b/moo/lib/moo.h index b39adcb..e03ebeb 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -1211,7 +1211,8 @@ enum moo_log_mask_t }; typedef enum moo_log_mask_t moo_log_mask_t; -#define MOO_LOG_ENABLED(moo,mask) ((moo)->option.log_mask & (mask)) +/* all bits must be set to get enabled */ +#define MOO_LOG_ENABLED(moo,mask) (((moo)->option.log_mask & (mask)) == (mask)) #define MOO_LOG0(moo,mask,fmt) do { if (MOO_LOG_ENABLED(moo,mask)) moo_logbfmt(moo, mask, fmt); } while(0) #define MOO_LOG1(moo,mask,fmt,a1) do { if (MOO_LOG_ENABLED(moo,mask)) moo_logbfmt(moo, mask, fmt, a1); } while(0)