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

View File

@ -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.
].
}
}

View File

@ -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);

View File

@ -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 }
};