added two experimental language/compiler enhancements - 1. multi-line comments enclosed in (* and *) 2. unary method and message with parenthensized parameters

This commit is contained in:
hyunghwan.chung 2016-12-06 17:21:47 +00:00
parent 0cc0339158
commit f88027af32
4 changed files with 191 additions and 35 deletions

View File

@ -1,9 +1,11 @@
#class(#byte) Stdio(Object) from 'stdio' #class(#byte) Stdio(Object) from 'stdio'
{ {
## #method(#class) _newInstSize (*
## { * The following methods are generated by the module.
## <primitive: #stdio._newInstSize> * #method(#class) _newInstSize { <primitive: #stdio._newInstSize> }
## } * #method open: name for: mode { <primitive: #stdio.open> }
* #method close { <primitive: #stdio.close> }
*)
#method(#class) new: size #method(#class) new: size
{ {
@ -24,15 +26,35 @@
^(self new) open: name for: mode ^(self new) open: name for: mode
} }
## #method open: name for: mode
## {
## <primitive: #stdio.open>
## }
## #method close #method(#class) input
## { {
## <primitive: #stdio.close> ^(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 #extend Stdio

View File

@ -130,6 +130,22 @@
v1 close. v1 close.
nil isNil ifTrue: [ 'NIL NIL NIL' dump. ]. nil isNil ifTrue: [ 'NIL NIL NIL' dump. ].
(Apex new) notNil ifTrue: [ 'APEX 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.
].
} }
} }

View File

@ -693,34 +693,57 @@ static int skip_comment (stix_t* stix)
do do
{ {
GET_CHAR_TO (stix, c); GET_CHAR_TO (stix, c);
if (c == STIX_UCI_EOF) if (c == STIX_UCI_EOF) goto unterminated;
{
/* unterminated comment */
set_syntax_error (stix, STIX_SYNERR_CMTNC, LEXER_LOC(stix), STIX_NULL);
return -1;
}
} }
while (c != '"'); while (c != '"');
if (c == '"') GET_CHAR (stix); /* keep the next character in lxc */ if (c == '"') GET_CHAR (stix); /* keep the next character in lxc */
return 1; /* double-quoted comment */ return 1; /* double-quoted comment */
} }
else if (c == '(')
/* 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 == '#')
{ {
/* 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 do
{ {
GET_CHAR_TO (stix, c); GET_CHAR_TO (stix, c);
if (c == STIX_UCI_EOF) if (c == STIX_UCI_EOF)
{ {
/* EOF on the comment line is ok for a single-line comment */
break; break;
} }
else if (c == '\r' || c == '\n') 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 #! */ 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 the leading '#' */
unget_char (stix, &stix->c->lxc); unget_char (stix, &stix->c->lxc);
/* restore the previous state */ /* restore the previous state */
stix->c->lxc = lc; stix->c->lxc = lc;
return 0; 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) 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; if (add_method_name_fragment(stix, TOKEN_NAME(stix)) <= -1) return -1;
GET_TOKEN (stix); 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; return 0;
} }
@ -3733,14 +3812,44 @@ static stix_oob_t send_message_cmd[] =
static int compile_unary_message (stix_t* stix, int to_super) static int compile_unary_message (stix_t* stix, int to_super)
{ {
stix_oow_t index; stix_oow_t index;
stix_oow_t nargs;
STIX_ASSERT (TOKEN_TYPE(stix) == STIX_IOTOK_IDENT); STIX_ASSERT (TOKEN_TYPE(stix) == STIX_IOTOK_IDENT);
do do
{ {
if (add_symbol_literal(stix, TOKEN_NAME(stix), 0, &index) <= -1 || nargs = 0;
emit_double_param_instruction(stix, send_message_cmd[to_super], 0, index) <= -1) return -1; if (add_symbol_literal(stix, TOKEN_NAME(stix), 0, &index) <= -1) return -1;
GET_TOKEN (stix); 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); while (TOKEN_TYPE(stix) == STIX_IOTOK_IDENT);

View File

@ -38,6 +38,13 @@ struct stdio_t
FILE* fp; 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) static int pf_open (stix_t* stix, stix_ooi_t nargs)
{ {
stix_oop_char_t name; stix_oop_char_t name;
@ -97,20 +104,21 @@ STIX_DEBUG1 (stix, "closing %p\n", rcv->fp);
return 1; 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.. */ /* return how many bytes have been written.. */
STIX_STACK_SETRETTORCV (stix, nargs); STIX_STACK_SETRETTORCV (stix, nargs);
return 1; 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); /* return how many bytes have been written.. */
STIX_STACK_SETRET (stix, nargs, STIX_SMOOI_TO_OOP(newinstsize)); STIX_STACK_SETRETTORCV (stix, nargs);
return 1; return 1;
} }
/* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */
typedef struct fnctab_t fnctab_t; typedef struct fnctab_t fnctab_t;
@ -125,6 +133,7 @@ static fnctab_t fnctab[] =
{ {
{ "_newInstSize", STIX_NULL, pf_newinstsize }, { "_newInstSize", STIX_NULL, pf_newinstsize },
{ "close", STIX_NULL, pf_close }, { "close", STIX_NULL, pf_close },
{ "gets", STIX_NULL, pf_gets },
{ "open:for:", STIX_NULL, pf_open }, { "open:for:", STIX_NULL, pf_open },
{ "puts", STIX_NULL, pf_puts } { "puts", STIX_NULL, pf_puts }
}; };