From bcaf4e5e1eab5e50b3982ef18f4eec0bdc8dbc28 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Tue, 13 Dec 2016 15:18:19 +0000 Subject: [PATCH] started using a comma as a parameter/argument separator. changed to use & as a string concatenation method in the string class. added some code to support variadic arguments --- stix/kernel/Apex.st | 2 +- stix/kernel/Collect.st | 2 +- stix/kernel/Context.st | 39 +++++++++++++++++++++++++++++++++++++++ stix/kernel/Except.st | 6 +++--- stix/kernel/Stdio.st | 6 +++++- stix/kernel/test-010.st | 14 +++++++------- stix/kernel/test-011.st | 2 +- stix/kernel/test-014.st | 6 ++++-- stix/lib/comp.c | 32 +++++++++++++++++++++++--------- stix/lib/exec.c | 14 +++++++++++--- stix/lib/main.c | 3 ++- stix/lib/stix-prv.h | 5 +++++ stix/lib/stix.c | 3 ++- stix/lib/stix.h | 19 +++++++++++++------ stix/mod/console.c | 1 + 15 files changed, 118 insertions(+), 36 deletions(-) diff --git a/stix/kernel/Apex.st b/stix/kernel/Apex.st index 5d0aaa3..afd4ef3 100644 --- a/stix/kernel/Apex.st +++ b/stix/kernel/Apex.st @@ -325,7 +325,7 @@ #method handleException: exception { - ('### EXCEPTION NOT HANDLED #### ', exception class name, ' - ', exception messageText) dump. + ('### EXCEPTION NOT HANDLED #### ' & exception class name & ' - ' & exception messageText) dump. ## TODO: debug the current process???? " ## TODO: ensure to execute ensure blocks as well.... ####Processor activeProcess terminate. diff --git a/stix/kernel/Collect.st b/stix/kernel/Collect.st index 225374b..2005025 100644 --- a/stix/kernel/Collect.st +++ b/stix/kernel/Collect.st @@ -51,7 +51,7 @@ #class(#character) String(Array) { - #method , aString + #method & aString { ## concatenate two strings. ## TOOD: make this a primitive for performance. diff --git a/stix/kernel/Context.st b/stix/kernel/Context.st index 404bdb3..8916581 100644 --- a/stix/kernel/Context.st +++ b/stix/kernel/Context.st @@ -11,6 +11,35 @@ { ^self.ip < 0 } + + #method temporaryCount + { + ^self.ntmprs + } + +(* --------------------------------- +#method varargCount +{ +method context, + + + ^do calculation... + +for a block context, it must access homeContext first and call varargCount + + ^self.home varargCount... +} + +#method varargAt: index +{ +method context + ^do calculation... + +block context... + ^self.home varargAt: index +} + +---------------------------------- *) } #class(#pointer) MethodContext(Context) @@ -58,12 +87,22 @@ { ^self.method } + + #method varArgCount + { + ^self basicSize - self class specNumInstVars - self.ntmprs + } } #class(#pointer) BlockContext(Context) { #dcl nargs source home origin. + #method varArgCount + { + ^self.home varArgCount + } + #method fork { "crate a new process in the runnable state" diff --git a/stix/kernel/Except.st b/stix/kernel/Except.st index 5051db5..0073053 100644 --- a/stix/kernel/Except.st +++ b/stix/kernel/Except.st @@ -62,7 +62,7 @@ ##thisContext unwindTo: nil return: nil. ##thisContext unwindTo: (Processor activeProcess initialContext) return: nil. thisContext unwindTo: (thisProcess initialContext) return: nil. - ('### EXCEPTION NOT HANDLED #### ', self class name, ' - ', self messageText) dump. + ('### EXCEPTION NOT HANDLED #### ' & self class name & ' - ' & self messageText) dump. ## TODO: debug the current process???? " ##Processor activeProcess terminate. @@ -352,7 +352,7 @@ ctx := thisContext. [ctx notNil] whileTrue: [ (ctx class == MethodContext) - ifTrue: [ (ctx method owner name, '>>', ctx method name) dump ]. + ifTrue: [ (ctx method owner name & '>>' & ctx method name) dump ]. ## TODO: include blockcontext??? ctx := ctx sender. ]. @@ -368,7 +368,7 @@ ctx := thisContext. #method(#class) doesNotUnderstand: messageSymbol { ## TODO: implement this properly - NoSuchMessageException signal: (messageSymbol, ' not understood by ', (self name)). + NoSuchMessageException signal: (messageSymbol & ' not understood by ' & (self name)). } } diff --git a/stix/kernel/Stdio.st b/stix/kernel/Stdio.st index 3abd54b..f4e5c37 100644 --- a/stix/kernel/Stdio.st +++ b/stix/kernel/Stdio.st @@ -27,6 +27,7 @@ } +(* --------------------- #method(#class) input { ^(super new) open: 0 for: 'r' @@ -41,6 +42,7 @@ { ^(super new) open: 2 for: 'w' } +------------------------ *) (* #method format: fmt with: ... @@ -49,11 +51,13 @@ } *) - #method format (fmt. args) + #method format (fmt, args) { + | a b c | 'THIS IS FORMAT' dump. fmt dump. args dump. + thisContext temporaryCount dump. } } diff --git a/stix/kernel/test-010.st b/stix/kernel/test-010.st index 6ee2bae..dbbf14b 100644 --- a/stix/kernel/test-010.st +++ b/stix/kernel/test-010.st @@ -120,12 +120,12 @@ k := 99. [ [ - ##[ Exception signal: 'simulated error' ] ensure: [('ensure 1 ', (k asString)) dump ]. - [ ^ 20 ] ensure: [ ('ensure 1 ', (k asString)) dump. ]. + ##[ Exception signal: 'simulated error' ] ensure: [('ensure 1 ' & (k asString)) dump ]. + [ ^ 20 ] ensure: [ ('ensure 1 ' & (k asString)) dump. ]. ] ensure: ['ensure 2' dump ]. ] ensure: ['ensure 3' dump ]. ] on: Exception do: [:ex | - ('EXCETION - ' , ex messageText) dump. + ('EXCETION - ' & ex messageText) dump. ## Exception signal: 'qqq'. ]. ^v1 @@ -145,7 +145,7 @@ "[ [ Exception signal: 'simulated error' ] ensure: ['ensure 1' dump ]. - ] on: Exception do: [:ex | ('EXCETION - ' , ex messageText) dump. Exception signal: 'qqq'. ]." + ] on: Exception do: [:ex | ('EXCETION - ' & ex messageText) dump. Exception signal: 'qqq'. ]." "[1 xxx] ifCurtailed: ['XXXXXXXX CURTAILED XXXXXXXXX' dump. Exception signal: 'jjjj']." @@ -154,12 +154,12 @@ k := 99. [ [ - ##[ Exception signal: 'simulated error' ] ensure: [('ensure 1 ', (k asString)) dump ]. - [ ^20 ] ensure: [('ensure 1 ', (k asString)) dump ]. + ##[ Exception signal: 'simulated error' ] ensure: [('ensure 1 ' & (k asString)) dump ]. + [ ^20 ] ensure: [('ensure 1 ' & (k asString)) dump ]. ] ensure: ['ensure 2' dump ]. ] ensure: ['ensure 3' dump ]. ] on: Exception do: [:ex | - ('EXCETION - ' , ex messageText) dump. + ('EXCETION - ' & ex messageText) dump. ## Exception signal: 'qqq'. ]. " diff --git a/stix/kernel/test-011.st b/stix/kernel/test-011.st index 8718c8f..1ccb91f 100644 --- a/stix/kernel/test-011.st +++ b/stix/kernel/test-011.st @@ -165,7 +165,7 @@ p := [ [ Exception signal: 'Exception in a new process of test12' ] on: Exception do: [:ex | - ('EXCEPTION CAUGHT...in test12 ==> ', (ex messageText)) dump. + ('EXCEPTION CAUGHT...in test12 ==> ' & (ex messageText)) dump. ] ] newProcess. 'JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ' dump. diff --git a/stix/kernel/test-014.st b/stix/kernel/test-014.st index f1e1381..9d24150 100644 --- a/stix/kernel/test-014.st +++ b/stix/kernel/test-014.st @@ -100,7 +100,7 @@ v2 at: 0 put: $H. - System logNl: ('START OF MAIN - ' , v2). + System logNl: ('START OF MAIN - ' & v2). v1 := MyConsole output. v1 clear. @@ -142,10 +142,12 @@ procecure call is treated as if it is a unary message... ]. *) - v1 format(10 . 20) isNil ifFalse: [ + v1 format(10, 20) isNil ifFalse: [ 'Beautiful life' dump. ]. + thisContext varArgCount dump. + thisContext varArgCount (10, 20) dump. } } diff --git a/stix/lib/comp.c b/stix/lib/comp.c index 9e4bfe7..857a5f6 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -193,7 +193,7 @@ static STIX_INLINE int is_binselchar (stix_ooci_t c) { /* * binary-selector-character := - * '!' | '%' | '&' | '*' | '+' | ',' | + * '!' | '%' | '&' | '*' | '+' | * '/' | '<' | '>' | '=' | '?' | '@' | * '\' | '~' | '|' | '-' */ @@ -205,7 +205,6 @@ static STIX_INLINE int is_binselchar (stix_ooci_t c) case '&': case '*': case '+': - case ',': case '/': case '<': case '>': @@ -1345,6 +1344,9 @@ retry: case '.': SET_TOKEN_TYPE (stix, STIX_IOTOK_PERIOD); goto single_char_token; + case ',': + SET_TOKEN_TYPE (stix, STIX_IOTOK_COMMA); + goto single_char_token; case ';': SET_TOKEN_TYPE (stix, STIX_IOTOK_SEMICOLON); goto single_char_token; @@ -2596,16 +2598,18 @@ static int compile_unary_method_name (stix_t* stix) GET_TOKEN (stix); if (TOKEN_TYPE(stix) == STIX_IOTOK_RPAREN) break; - if (TOKEN_TYPE(stix) != STIX_IOTOK_PERIOD) /* TODO: change PERIOD to soemthing else... */ + if (TOKEN_TYPE(stix) != STIX_IOTOK_COMMA) { - set_syntax_error (stix, STIX_SYNERR_PERIOD, TOKEN_LOC(stix), TOKEN_NAME(stix)); + set_syntax_error (stix, STIX_SYNERR_COMMA, TOKEN_LOC(stix), TOKEN_NAME(stix)); return -1; } -/* TODO: indicate the method is in the procedural style... Do i need to??? */ + } while (1); } + /* indicate that the unary method name is followed by a parameter list */ + stix->c->mth.parunary = 1; GET_TOKEN (stix); } @@ -3835,9 +3839,9 @@ static int compile_unary_message (stix_t* stix, int to_super) if (TOKEN_TYPE(stix) == STIX_IOTOK_RPAREN) break; - if (TOKEN_TYPE(stix) != STIX_IOTOK_PERIOD) + if (TOKEN_TYPE(stix) != STIX_IOTOK_COMMA) { - set_syntax_error (stix, STIX_SYNERR_PERIOD, TOKEN_LOC(stix), TOKEN_NAME(stix)); + set_syntax_error (stix, STIX_SYNERR_COMMA, TOKEN_LOC(stix), TOKEN_NAME(stix)); return -1; } @@ -3847,6 +3851,10 @@ static int compile_unary_message (stix_t* stix, int to_super) } GET_TOKEN(stix); + + /* NOTE: since the actual method may not be known at the compile time, + * i can't check if nargs will match the number of arguments + * expected by the method */ } if (emit_double_param_instruction(stix, send_message_cmd[to_super], nargs, index) <= -1) return -1; @@ -4326,7 +4334,7 @@ static int add_compiled_method (stix_t* stix) #endif stix_oow_t tmp_count = 0; stix_oow_t i; - stix_ooi_t preamble_code, preamble_index; + stix_ooi_t preamble_code, preamble_index, preamble_flags; name = (stix_oop_char_t)stix_makesymbol (stix, stix->c->mth.name.ptr, stix->c->mth.name.len); if (!name) return -1; @@ -4357,6 +4365,7 @@ static int add_compiled_method (stix_t* stix) preamble_code = STIX_METHOD_PREAMBLE_NONE; preamble_index = 0; + preamble_flags = 0; if (stix->c->mth.pftype <= 0) { @@ -4481,11 +4490,15 @@ static int add_compiled_method (stix_t* stix) preamble_index = 0; } + + if (stix->c->mth.parunary /*&& stix->c->mth.tmpr_nargs > 0*/) + preamble_flags |= STIX_METHOD_PREAMBLE_FLAG_PARUNARY; + STIX_ASSERT (STIX_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(preamble_index)); mth->owner = stix->c->cls.self_oop; mth->name = name; - mth->preamble = STIX_SMOOI_TO_OOP(STIX_METHOD_MAKE_PREAMBLE(preamble_code, preamble_index)); + mth->preamble = STIX_SMOOI_TO_OOP(STIX_METHOD_MAKE_PREAMBLE(preamble_code, preamble_index, preamble_flags)); mth->preamble_data[0] = STIX_SMOOI_TO_OOP(0); mth->preamble_data[1] = STIX_SMOOI_TO_OOP(0); mth->tmpr_count = STIX_SMOOI_TO_OOP(stix->c->mth.tmpr_count); @@ -4531,6 +4544,7 @@ static int compile_method_definition (stix_t* stix) stix->c->mth.kwsels.len = 0; stix->c->mth.name.len = 0; STIX_MEMSET (&stix->c->mth.name_loc, 0, STIX_SIZEOF(stix->c->mth.name_loc)); + stix->c->mth.parunary = 0; stix->c->mth.tmprs.len = 0; stix->c->mth.tmpr_count = 0; stix->c->mth.tmpr_nargs = 0; diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 5cd908a..c8ca565 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -900,6 +900,7 @@ static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth) STIX_ASSERT (nargs <= ntmprs); stix_pushtmp (stix, (stix_oop_t*)&mth); +/* TODO: check if the method is pused some extra arguments... */ ctx = (stix_oop_context_t)stix_instantiate (stix, stix->_method_context, STIX_NULL, ntmprs); stix_poptmp (stix); if (!ctx) return -1; @@ -909,7 +910,7 @@ static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth) /* ctx->sp will be set further down */ /* A context is compose of a fixed part and a variable part. - * the variable part hold temporary varibles including arguments. + * the variable part holds temporary varibles including arguments. * * Assuming a method context with 2 arguments and 3 local temporary * variables, the context will look like this. @@ -2764,7 +2765,14 @@ static int start_method (stix_t* stix, stix_oop_method_t method, stix_oow_t narg stix_ooi_t fetched_instruction_pointer = 0; /* set it to a fake value */ #endif - STIX_ASSERT (STIX_OOP_TO_SMOOI(method->tmpr_nargs) == nargs); + /*STIX_ASSERT (STIX_OOP_TO_SMOOI(method->tmpr_nargs) == nargs);*/ + if (nargs != STIX_OOP_TO_SMOOI(method->tmpr_nargs)) + { + /* TODO: throw exception??? */ + STIX_DEBUG1 (stix, "Argument count mismatch [%O]\n", method->name); + stix->errnum = STIX_EINVAL; + return -1; + } preamble = STIX_OOP_TO_SMOOI(method->preamble); preamble_code = STIX_METHOD_GET_PREAMBLE_CODE(preamble); @@ -2907,7 +2915,7 @@ static int start_method (stix_t* stix, stix_oop_method_t method, stix_oow_t narg exec_handler: stix_pushtmp (stix, (stix_oop_t*)&method); n = handler (stix, nargs); - + stix_poptmp (stix); if (n <= -1) { diff --git a/stix/lib/main.c b/stix/lib/main.c index 71ebe74..1e9250f 100644 --- a/stix/lib/main.c +++ b/stix/lib/main.c @@ -325,7 +325,7 @@ static void dl_close (stix_t* stix, void* handle) #elif defined(__MSDOS__) && defined(QSE_ENABLE_DOS_DYNAMIC_MODULE) FreeModule (handle); #else - /* nothing to do */ + /* nothing to do */ #endif } @@ -488,6 +488,7 @@ static char* syntax_error_msg[] = ") expected", "] expected", ". expected", + ", expected", "| expected", "> expected", ":= expected", diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index 38f98e4..eb8e6b8 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -347,6 +347,7 @@ struct stix_iotok_t STIX_IOTOK_ARPAREN, /* #( */ STIX_IOTOK_BAPAREN, /* #[ */ STIX_IOTOK_PERIOD, + STIX_IOTOK_COMMA, STIX_IOTOK_SEMICOLON } type; @@ -377,6 +378,7 @@ enum stix_synerrnum_t STIX_SYNERR_RPAREN, /* ) expected */ STIX_SYNERR_RBRACK, /* ] expected */ STIX_SYNERR_PERIOD, /* . expected */ + STIX_SYNERR_COMMA, /* , expected */ STIX_SYNERR_VBAR, /* | expected */ STIX_SYNERR_GT, /* > expected */ STIX_SYNERR_ASSIGN, /* := expected */ @@ -541,6 +543,9 @@ struct stix_compiler_t stix_oow_t name_capa; stix_ioloc_t name_loc; + /* is the unary method followed by parameter list? */ + int parunary; + /* single string containing a space separated list of temporaries */ stix_oocs_t tmprs; stix_oow_t tmprs_capa; diff --git a/stix/lib/stix.c b/stix/lib/stix.c index 8af5dc3..92bd9d5 100644 --- a/stix/lib/stix.c +++ b/stix/lib/stix.c @@ -777,7 +777,8 @@ int stix_genpfmethod (stix_t* stix, stix_mod_t* mod, stix_oop_t _class, stix_met /* premable should contain the index to the literal frame which is always 0 */ mth->owner = cls; mth->name = mnsym; - mth->preamble = STIX_SMOOI_TO_OOP(STIX_METHOD_MAKE_PREAMBLE(STIX_METHOD_PREAMBLE_NAMED_PRIMITIVE, 0)); +/* TODO: premable flag -> VARIADIC, PARUNARY??? */ + mth->preamble = STIX_SMOOI_TO_OOP(STIX_METHOD_MAKE_PREAMBLE(STIX_METHOD_PREAMBLE_NAMED_PRIMITIVE, 0, 0)); mth->preamble_data[0] = STIX_SMOOI_TO_OOP(0); mth->preamble_data[1] = STIX_SMOOI_TO_OOP(0); mth->tmpr_count = STIX_SMOOI_TO_OOP(arg_count); diff --git a/stix/lib/stix.h b/stix/lib/stix.h index cbbb1f7..65f814b 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -160,7 +160,6 @@ typedef struct stix_obj_word_t* stix_oop_word_t; #endif - enum stix_method_type_t { STIX_METHOD_INSTANCE, @@ -503,8 +502,10 @@ struct stix_method_t # define STIX_METHOD_GET_CODE_SIZE(m) STIX_OBJ_GET_SIZE((m)->code) #endif -/* The preamble field is composed of a 8-bit code and a 16-bit - * index. +/* The preamble field is composed of: + * 2-bit flag + * 6-bit code + * 16-bit index * * The code can be one of the following values: * 0 - no special action @@ -519,10 +520,12 @@ struct stix_method_t * 9 - do named primitive[index] * 10 - exception handler */ -#define STIX_METHOD_MAKE_PREAMBLE(code,index) ((((stix_ooi_t)index) << 8) | ((stix_ooi_t)code)) -#define STIX_METHOD_GET_PREAMBLE_CODE(preamble) (((stix_ooi_t)preamble) & 0xFF) +#define STIX_METHOD_MAKE_PREAMBLE(code,index,flags) ((((stix_ooi_t)index) << 8) | ((stix_ooi_t)code << 2) | flags) +#define STIX_METHOD_GET_PREAMBLE_CODE(preamble) ((((stix_ooi_t)preamble) & 0xFF) >> 2) #define STIX_METHOD_GET_PREAMBLE_INDEX(preamble) (((stix_ooi_t)preamble) >> 8) +#define STIX_METHOD_GET_PREAMBLE_FLAGS(preamble) (((stix_ooi_t)preamble) & 0x3) +/* preamble codes */ #define STIX_METHOD_PREAMBLE_NONE 0 #define STIX_METHOD_PREAMBLE_RETURN_RECEIVER 1 #define STIX_METHOD_PREAMBLE_RETURN_NIL 2 @@ -541,6 +544,10 @@ struct stix_method_t #define STIX_METHOD_PREAMBLE_INDEX_MAX 0xFFFF #define STIX_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(num) ((num) >= STIX_METHOD_PREAMBLE_INDEX_MIN && (num) <= STIX_METHOD_PREAMBLE_INDEX_MAX) +/* preamble flags */ +#define STIX_METHOD_PREAMBLE_FLAG_PARUNARY (1 << 0) +#define STIX_METHOD_PREAMBLE_FLAG_VARIADIC (1 << 1) + #define STIX_CONTEXT_NAMED_INSTVARS 8 typedef struct stix_context_t stix_context_t; typedef struct stix_context_t* stix_oop_context_t; @@ -595,7 +602,7 @@ struct stix_context_t * the source block context. */ stix_oop_context_t origin; - /* variable indexed part */ + /* variable indexed part - actual arguments and temporaries are placed here */ stix_oop_t slot[1]; /* stack */ }; diff --git a/stix/mod/console.c b/stix/mod/console.c index 137a0ea..655b7c5 100644 --- a/stix/mod/console.c +++ b/stix/mod/console.c @@ -138,6 +138,7 @@ static int pf_close (stix_t* stix, stix_ooi_t nargs) if (con->fd_opened) close (con->fd); + stix_freemem (stix, con); STIX_STACK_SETRETTORCV (stix, nargs); return 1; }