diff --git a/stix/kernel/Stdio.st b/stix/kernel/Stdio.st index 04d408e..3abd54b 100644 --- a/stix/kernel/Stdio.st +++ b/stix/kernel/Stdio.st @@ -1,9 +1,11 @@ #class(#byte) Stdio(Object) from 'stdio' { -## #method(#class) _newInstSize -## { -## -## } + (* + * The following methods are generated by the module. + * #method(#class) _newInstSize { } + * #method open: name for: mode { } + * #method close { } + *) #method(#class) new: size { @@ -24,15 +26,35 @@ ^(self new) open: name for: mode } -## #method open: name for: mode -## { -## -## } -## #method close -## { -## -## } + #method(#class) input + { + ^(super new) open: 0 for: 'r' + } + + #method(#class) output + { + ^(super new) open: 1 for: 'w' + } + + #method(#class) error + { + ^(super new) open: 2 for: 'w' + } + + (* + #method format: fmt with: ... + { + + } + *) + + #method format (fmt. args) + { + 'THIS IS FORMAT' dump. + fmt dump. + args dump. + } } #extend Stdio diff --git a/stix/kernel/test-014.st b/stix/kernel/test-014.st index b97a0f2..f1e1381 100644 --- a/stix/kernel/test-014.st +++ b/stix/kernel/test-014.st @@ -130,6 +130,22 @@ v1 close. nil isNil ifTrue: [ 'NIL NIL NIL' dump. ]. (Apex new) notNil ifTrue: [ 'APEX NIL NIL NIL' dump. ]. + + +(* + v1 format(10 20 30) isNil +procecure call is treated as if it is a unary message... + + + v1 format(10 , 20 , 30) isNil ifTrue: [ + xxxx + ]. +*) + + v1 format(10 . 20) isNil ifFalse: [ + 'Beautiful life' dump. + ]. + } } diff --git a/stix/lib/comp.c b/stix/lib/comp.c index 8f64a7c..9e4bfe7 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -693,34 +693,57 @@ static int skip_comment (stix_t* stix) do { GET_CHAR_TO (stix, c); - if (c == STIX_UCI_EOF) - { - /* unterminated comment */ - set_syntax_error (stix, STIX_SYNERR_CMTNC, LEXER_LOC(stix), STIX_NULL); - return -1; - } + if (c == STIX_UCI_EOF) goto unterminated; } while (c != '"'); if (c == '"') GET_CHAR (stix); /* keep the next character in lxc */ return 1; /* double-quoted comment */ } - - /* handle #! or ## */ - if (c != '#') return 0; /* not a comment */ - - /* save the last character */ - lc = stix->c->lxc; - /* read a new character */ - GET_CHAR_TO (stix, c); - - if (c == '!' || c == '#') + else if (c == '(') { + /* handle (* ... *) */ + lc = stix->c->lxc; + GET_CHAR_TO (stix, c); + if (c != '*') goto not_comment; + + do + { + GET_CHAR_TO (stix, c); + if (c == STIX_UCI_EOF) goto unterminated; + + if (c == '*') + { + GET_CHAR_TO (stix, c); + if (c == STIX_UCI_EOF) goto unterminated; + + if (c == ')') + { + GET_CHAR (stix); /* keep the first meaningful character in lxc */ + break; + } + } + } + while (1); + + return 1; /* multi-line comment enclosed in (* and *) */ + } + else if (c == '#') + { + /* handle #! or ## */ + + /* save the last character */ + lc = stix->c->lxc; + /* read a new character */ + GET_CHAR_TO (stix, c); + + if (c != '!' && c != '#') goto not_comment; do { GET_CHAR_TO (stix, c); if (c == STIX_UCI_EOF) { + /* EOF on the comment line is ok for a single-line comment */ break; } else if (c == '\r' || c == '\n') @@ -733,13 +756,25 @@ static int skip_comment (stix_t* stix) return 1; /* single line comment led by ## or #! */ } + else + { + /* not comment. but no next character has been consumed. + * no need to unget a character */ + return 0; + } +not_comment: /* unget the leading '#' */ unget_char (stix, &stix->c->lxc); /* restore the previous state */ stix->c->lxc = lc; return 0; + + +unterminated: + set_syntax_error (stix, STIX_SYNERR_CMTNC, LEXER_LOC(stix), STIX_NULL); + return -1; } static int get_ident (stix_t* stix, stix_ooci_t char_read_ahead) @@ -2530,6 +2565,50 @@ static int compile_unary_method_name (stix_t* stix) if (add_method_name_fragment(stix, TOKEN_NAME(stix)) <= -1) return -1; GET_TOKEN (stix); + + if (TOKEN_TYPE(stix) == STIX_IOTOK_LPAREN) + { + /* this is a procedural style method */ + STIX_ASSERT (stix->c->mth.tmpr_nargs == 0); + + if (TOKEN_TYPE(stix) != STIX_IOTOK_RPAREN) + { + do + { + GET_TOKEN (stix); + + if (TOKEN_TYPE(stix) != STIX_IOTOK_IDENT) + { + /* wrong argument name. identifier is expected */ + set_syntax_error (stix, STIX_SYNERR_IDENT, TOKEN_LOC(stix), TOKEN_NAME(stix)); + return -1; + } + + if (find_temporary_variable(stix, TOKEN_NAME(stix), STIX_NULL) >= 0) + { + set_syntax_error (stix, STIX_SYNERR_ARGNAMEDUP, TOKEN_LOC(stix), TOKEN_NAME(stix)); + return -1; + } + + if (add_temporary_variable(stix, TOKEN_NAME(stix)) <= -1) return -1; + stix->c->mth.tmpr_nargs++; + + GET_TOKEN (stix); + if (TOKEN_TYPE(stix) == STIX_IOTOK_RPAREN) break; + + if (TOKEN_TYPE(stix) != STIX_IOTOK_PERIOD) /* TODO: change PERIOD to soemthing else... */ + { + set_syntax_error (stix, STIX_SYNERR_PERIOD, TOKEN_LOC(stix), TOKEN_NAME(stix)); + return -1; + } +/* TODO: indicate the method is in the procedural style... Do i need to??? */ + } + while (1); + } + + GET_TOKEN (stix); + } + return 0; } @@ -3733,14 +3812,44 @@ static stix_oob_t send_message_cmd[] = static int compile_unary_message (stix_t* stix, int to_super) { stix_oow_t index; + stix_oow_t nargs; STIX_ASSERT (TOKEN_TYPE(stix) == STIX_IOTOK_IDENT); do { - if (add_symbol_literal(stix, TOKEN_NAME(stix), 0, &index) <= -1 || - emit_double_param_instruction(stix, send_message_cmd[to_super], 0, index) <= -1) return -1; + nargs = 0; + if (add_symbol_literal(stix, TOKEN_NAME(stix), 0, &index) <= -1) return -1; + GET_TOKEN (stix); + if (TOKEN_TYPE(stix) == STIX_IOTOK_LPAREN) + { + /* parameterized procedure call */ + GET_TOKEN(stix); + if (TOKEN_TYPE(stix) != STIX_IOTOK_RPAREN) + { + do + { + if (compile_method_expression (stix, 0) <= -1) return -1; + nargs++; + + if (TOKEN_TYPE(stix) == STIX_IOTOK_RPAREN) break; + + if (TOKEN_TYPE(stix) != STIX_IOTOK_PERIOD) + { + set_syntax_error (stix, STIX_SYNERR_PERIOD, TOKEN_LOC(stix), TOKEN_NAME(stix)); + return -1; + } + + GET_TOKEN(stix); + } + while (1); + } + + GET_TOKEN(stix); + } + + if (emit_double_param_instruction(stix, send_message_cmd[to_super], nargs, index) <= -1) return -1; } while (TOKEN_TYPE(stix) == STIX_IOTOK_IDENT); diff --git a/stix/mod/stdio.c b/stix/mod/stdio.c index 82d2105..b51602e 100644 --- a/stix/mod/stdio.c +++ b/stix/mod/stdio.c @@ -38,6 +38,13 @@ struct stdio_t FILE* fp; }; +static int pf_newinstsize (stix_t* stix, stix_ooi_t nargs) +{ + stix_ooi_t newinstsize = STIX_SIZEOF(stdio_t) - STIX_SIZEOF(stix_obj_t); + STIX_STACK_SETRET (stix, nargs, STIX_SMOOI_TO_OOP(newinstsize)); + return 1; +} + static int pf_open (stix_t* stix, stix_ooi_t nargs) { stix_oop_char_t name; @@ -97,20 +104,21 @@ STIX_DEBUG1 (stix, "closing %p\n", rcv->fp); return 1; } -static int pf_puts (stix_t* stix, stix_ooi_t nargs) +static int pf_gets (stix_t* stix, stix_ooi_t nargs) { /* return how many bytes have been written.. */ - STIX_STACK_SETRETTORCV (stix, nargs); return 1; } -static int pf_newinstsize (stix_t* stix, stix_ooi_t nargs) +static int pf_puts (stix_t* stix, stix_ooi_t nargs) { - stix_ooi_t newinstsize = STIX_SIZEOF(stdio_t) - STIX_SIZEOF(stix_obj_t); - STIX_STACK_SETRET (stix, nargs, STIX_SMOOI_TO_OOP(newinstsize)); + /* return how many bytes have been written.. */ + STIX_STACK_SETRETTORCV (stix, nargs); return 1; } + + /* ------------------------------------------------------------------------ */ typedef struct fnctab_t fnctab_t; @@ -125,6 +133,7 @@ static fnctab_t fnctab[] = { { "_newInstSize", STIX_NULL, pf_newinstsize }, { "close", STIX_NULL, pf_close }, + { "gets", STIX_NULL, pf_gets }, { "open:for:", STIX_NULL, pf_open }, { "puts", STIX_NULL, pf_puts } };