changed the error literal notation from error(NNN) to #\NNN.

prohibited the backslash character from forming a binary selector.
renamed quo: to div:, // to mdiv:, \ to mod:
This commit is contained in:
hyunghwan.chung 2018-04-08 17:47:38 +00:00
parent 8a6e2c601c
commit c85bf336ad
7 changed files with 101 additions and 101 deletions

View File

@ -8,17 +8,17 @@ class(#limited) Error(Apex)
pooldic Error.Code pooldic Error.Code
{ {
ENOERR := error(0). ENOERR := #\0.
EGENERIC := error(1). EGENERIC := #\1.
ENOIMPL := error(2). ENOIMPL := #\2.
ESYSERR := error(3). ESYSERR := #\3.
EINTERN := error(4). EINTERN := #\4.
ESYSMEM := error(5). ESYSMEM := #\5.
EOOMEM := error(6). EOOMEM := #\6.
EINVAL := error(7). EINVAL := #\7.
ENOENT := error(8). ENOENT := #\8.
EPERM := error(12). EPERM := #\12.
ERANGE := error(20). ERANGE := #\20.
(* add more items... *) (* add more items... *)
} }
@ -300,8 +300,8 @@ extend Error
pooldic/const pooldic/const
{ {
NONE := error(0). NONE := #\0.
GENERIC := error(1). GENERIC := #\1.
} }
-------------------------------- *) -------------------------------- *)

View File

@ -123,30 +123,39 @@ class(#limited) Number(Magnitude)
self primitiveFailed. self primitiveFailed.
} }
method quo: aNumber method div: aNumber
{ {
<primitive: #_integer_quo> ## integer division rounded toward zero
<primitive: #_integer_div>
self primitiveFailed. self primitiveFailed.
} }
method rem: aNumber method rem: aNumber
{ {
## integer remainder rounded toward zero
<primitive: #_integer_rem> <primitive: #_integer_rem>
self primitiveFailed. self primitiveFailed.
} }
method // aNumber method mdiv: aNumber
{ {
<primitive: #_integer_quo2> ## integer division quotient
<primitive: #_integer_mdiv>
self primitiveFailed. self primitiveFailed.
} }
method \\ aNumber method mod: aNumber
{ {
<primitive: #_integer_rem2> ## integer division remainder
<primitive: #_integer_mod>
self primitiveFailed. self primitiveFailed.
} }
##method / aNumber
##{
## ## fraction? fixed-point decimal? floating-point?
##}
method = aNumber method = aNumber
{ {
<primitive: #_integer_eq> <primitive: #_integer_eq>

View File

@ -117,7 +117,6 @@ static struct voca_t
{ 4, { 'e','l','s','e' } }, { 4, { 'e','l','s','e' } },
{ 5, { 'e','l','s','i','f' } }, { 5, { 'e','l','s','i','f' } },
{ 6, { 'e','n','s','u','r','e', } }, { 6, { 'e','n','s','u','r','e', } },
{ 5, { 'e','r','r','o','r' } },
{ 9, { 'e','x','c','e','p','t','i','o','n' } }, { 9, { 'e','x','c','e','p','t','i','o','n' } },
{ 6, { 'e','x','t','e','n','d' } }, { 6, { 'e','x','t','e','n','d' } },
{ 5, { 'f','a','l','s','e' } }, { 5, { 'f','a','l','s','e' } },
@ -182,7 +181,6 @@ enum voca_id_t
VOCA_ELSE, VOCA_ELSE,
VOCA_ELSIF, VOCA_ELSIF,
VOCA_ENSURE, VOCA_ENSURE,
VOCA_ERROR,
VOCA_EXCEPTION, VOCA_EXCEPTION,
VOCA_EXTEND, VOCA_EXTEND,
VOCA_FALSE, VOCA_FALSE,
@ -260,7 +258,6 @@ static MOO_INLINE int is_spacechar (moo_ooci_t c)
} }
} }
static MOO_INLINE int is_alphachar (moo_ooci_t c) static MOO_INLINE int is_alphachar (moo_ooci_t c)
{ {
/* TODO: support full unicode */ /* TODO: support full unicode */
@ -284,13 +281,14 @@ static MOO_INLINE int is_binselchar (moo_ooci_t c)
/* /*
* binary-selector-character := * binary-selector-character :=
* '&' | '*' | '+' | '-' | '/' | * '&' | '*' | '+' | '-' | '/' |
* '<' | '>' | '=' | '?' | '@' | * '<' | '>' | '=' | '@' | '~' | '|'
* '\' | '~' | '|'
* *
* - a comma is special in moo and doesn't form a binary selector. * - a comma is special in moo and doesn't form a binary selector.
* - a percent sign is special in moo and doesn't form a binary selector. * - a percent sign is special in moo and doesn't form a binary selector.
* - an exclamation mark is excluded intentioinally because i can't tell * - an exclamation mark is excluded intentioinally because i can't tell
* the method symbol #! from the comment introducer #!. * the method symbol #! from the comment introducer #!.
* - a question mark forms a normal identifier.
* - a backslash is used to form an error literal combined with a hash sign. (e.g. #\10)
*/ */
switch (c) switch (c)
@ -303,9 +301,7 @@ static MOO_INLINE int is_binselchar (moo_ooci_t c)
case '<': case '<':
case '>': case '>':
case '=': case '=':
case '?':
case '@': case '@':
case '\\':
case '|': case '|':
case '~': case '~':
return 1; return 1;
@ -322,7 +318,7 @@ static MOO_INLINE int is_leadidentchar (moo_ooci_t c)
static MOO_INLINE int is_identchar (moo_ooci_t c) static MOO_INLINE int is_identchar (moo_ooci_t c)
{ {
return is_alnumchar(c) || c == '_'; return is_alnumchar(c) || c == '_' || c == '?';
} }
#if 0 #if 0
@ -342,7 +338,7 @@ static MOO_INLINE int is_closing_char (moo_ooci_t c)
default: default:
return 0; return 0;
} }
} }VOCA_ERROR,
#endif #endif
static MOO_INLINE int is_word (const moo_oocs_t* oocs, voca_id_t id) static MOO_INLINE int is_word (const moo_oocs_t* oocs, voca_id_t id)
@ -360,7 +356,6 @@ static int is_reserved_word (const moo_oocs_t* ucs)
VOCA_NIL, VOCA_NIL,
VOCA_TRUE, VOCA_TRUE,
VOCA_FALSE, VOCA_FALSE,
VOCA_ERROR,
VOCA_THIS_CONTEXT, VOCA_THIS_CONTEXT,
VOCA_THIS_PROCESS, VOCA_THIS_PROCESS,
VOCA_SELFNS, VOCA_SELFNS,
@ -642,7 +637,7 @@ static moo_oop_t string_to_num (moo_t* moo, moo_oocs_t* str, int radixed)
return moo_strtoint (moo, ptr, end - ptr, base); return moo_strtoint (moo, ptr, end - ptr, base);
} }
static moo_oop_t string_to_error (moo_t* moo, moo_oocs_t* str) static moo_oop_t string_to_error (moo_t* moo, moo_oocs_t* str, moo_ioloc_t* loc)
{ {
moo_ooi_t num = 0; moo_ooi_t num = 0;
const moo_ooch_t* ptr, * end; const moo_ooch_t* ptr, * end;
@ -655,14 +650,25 @@ static moo_oop_t string_to_error (moo_t* moo, moo_oocs_t* str)
* i just skip all non-digit letters for simplicity sake. */ * i just skip all non-digit letters for simplicity sake. */
while (ptr < end) while (ptr < end)
{ {
if (is_digitchar(*ptr)) num = num * 10 + (*ptr - '0'); if (is_digitchar(*ptr))
{
moo_oow_t xnum;
xnum = num * 10 + (*ptr - '0');
if (xnum < num || xnum > MOO_ERROR_MAX)
{
/* overflowed */
moo_setsynerr (moo, MOO_SYNERR_ERRLITINVAL, loc, str);
return MOO_NULL;
}
num = xnum;
}
ptr++; ptr++;
} }
return MOO_ERROR_TO_OOP(num); return MOO_ERROR_TO_OOP(num);
} }
/* --------------------------------------------------------------------- /* ---------------------------------------------------------------------
* SOME PRIVIATE UTILITILES * SOME PRIVIATE UTILITILES
* --------------------------------------------------------------------- */ * --------------------------------------------------------------------- */
@ -1017,37 +1023,7 @@ static int get_ident (moo_t* moo, moo_ooci_t char_read_ahead)
GET_CHAR_TO (moo, c); GET_CHAR_TO (moo, c);
} }
if (c == '(' && is_token_word(moo, VOCA_ERROR)) if (c == ':')
{
/* error(NN) */
ADD_TOKEN_CHAR (moo, c);
GET_CHAR_TO (moo, c);
if (!is_digitchar(c))
{
ADD_TOKEN_CHAR (moo, c);
moo_setsynerr (moo, MOO_SYNERR_ERRLITINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
do
{
ADD_TOKEN_CHAR (moo, c);
GET_CHAR_TO (moo, c);
}
while (is_digitchar(c));
if (c != ')')
{
moo_setsynerr (moo, MOO_SYNERR_RPAREN, LEXER_LOC(moo), MOO_NULL);
return -1;
}
/* TODO: error number range check */
ADD_TOKEN_CHAR (moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_ERRLIT);
}
else if (c == ':')
{ {
#if 0 #if 0
read_more_kwsym: read_more_kwsym:
@ -1160,10 +1136,6 @@ static int get_ident (moo_t* moo, moo_ooci_t char_read_ahead)
{ {
SET_TOKEN_TYPE (moo, MOO_IOTOK_FALSE); SET_TOKEN_TYPE (moo, MOO_IOTOK_FALSE);
} }
else if (is_token_word(moo, VOCA_ERROR))
{
SET_TOKEN_TYPE (moo, MOO_IOTOK_ERROR);
}
else if (is_token_word(moo, VOCA_THIS_CONTEXT)) else if (is_token_word(moo, VOCA_THIS_CONTEXT))
{ {
SET_TOKEN_TYPE (moo, MOO_IOTOK_THIS_CONTEXT); SET_TOKEN_TYPE (moo, MOO_IOTOK_THIS_CONTEXT);
@ -1234,27 +1206,33 @@ static int get_numlit (moo_t* moo, int negated)
*/ */
moo_ooci_t c; moo_ooci_t c;
int radix = 0, r; moo_oow_t radix = 0;
int radix_overflowed = 0;
c = moo->c->lxc.c; c = moo->c->lxc.c;
SET_TOKEN_TYPE (moo, MOO_IOTOK_NUMLIT); SET_TOKEN_TYPE (moo, MOO_IOTOK_NUMLIT);
/*TODO: support a complex numeric literal */ /*TODO: support a complex numeric literal */
do do
{
if (radix <= 36)
{ {
/* collect the potential radix specifier */ /* collect the potential radix specifier */
r = CHAR_TO_NUM (c, 10); if (!radix_overflowed)
{
int r;
moo_oow_t rv;
r = CHAR_TO_NUM(c, 10);
MOO_ASSERT (moo, r < 10); MOO_ASSERT (moo, r < 10);
radix = radix * 10 + r; rv = radix * 10 + r;
if (rv < radix) radix_overflowed = 1;
radix = rv;
} }
ADD_TOKEN_CHAR(moo, c); ADD_TOKEN_CHAR(moo, c);
GET_CHAR_TO (moo, c); GET_CHAR_TO (moo, c);
if (c == '_') if (c == '_')
{ {
/* i allow digit separation with _ as in 123_456. */
moo_iolxc_t underscore; moo_iolxc_t underscore;
underscore = moo->c->lxc; underscore = moo->c->lxc;
GET_CHAR_TO(moo, c); GET_CHAR_TO(moo, c);
@ -1273,9 +1251,9 @@ static int get_numlit (moo_t* moo, int negated)
{ {
/* radix specifier */ /* radix specifier */
if (radix < 2 || radix > 36) if (radix_overflowed || radix < 2 || radix > 36)
{ {
/* no digit after the radix specifier */ /* radix too big */
moo_setsynerr (moo, MOO_SYNERR_RADIXINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo)); moo_setsynerr (moo, MOO_SYNERR_RADIXINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1; return -1;
} }
@ -1311,9 +1289,12 @@ static int get_numlit (moo_t* moo, int negated)
while (CHAR_TO_NUM(c, radix) < radix); while (CHAR_TO_NUM(c, radix) < radix);
SET_TOKEN_TYPE (moo, MOO_IOTOK_RADNUMLIT); SET_TOKEN_TYPE (moo, MOO_IOTOK_RADNUMLIT);
}
unget_char (moo, &moo->c->lxc); unget_char (moo, &moo->c->lxc);
}
else
{
unget_char (moo, &moo->c->lxc);
}
/* /*
* TODO: handle floating point number * TODO: handle floating point number
@ -1743,7 +1724,6 @@ retry:
ADD_TOKEN_CHAR(moo, c); ADD_TOKEN_CHAR(moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_HASHBRACK); SET_TOKEN_TYPE (moo, MOO_IOTOK_HASHBRACK);
break; break;
break;
case '\'': case '\'':
/* quoted symbol literal */ /* quoted symbol literal */
@ -1751,6 +1731,27 @@ retry:
SET_TOKEN_TYPE (moo, MOO_IOTOK_SYMLIT); /* change the symbol type to symbol */ SET_TOKEN_TYPE (moo, MOO_IOTOK_SYMLIT); /* change the symbol type to symbol */
break; break;
case '\\':
/* #\NNN - error literal - #\0, #\1234, etc */
SET_TOKEN_TYPE(moo, MOO_IOTOK_ERRLIT);
ADD_TOKEN_CHAR(moo, c);
GET_CHAR_TO (moo, c);
if (!is_digitchar(c))
{
ADD_TOKEN_CHAR(moo, c); /* to include it to the error messsage */
moo_setsynerr (moo, MOO_SYNERR_ERRLITINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
do
{
ADD_TOKEN_CHAR(moo, c);
GET_CHAR_TO (moo, c);
}
while (is_digitchar(c) || c == '_');
unget_char (moo, &moo->c->lxc);
break;
default: default:
/* symbol-literal := "#" symbol-body /* symbol-literal := "#" symbol-body
* symbol-body := identifier | keyword+ | binary-selector | string-literal * symbol-body := identifier | keyword+ | binary-selector | string-literal
@ -4936,17 +4937,11 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons
GET_TOKEN (moo); GET_TOKEN (moo);
break; break;
case MOO_IOTOK_ERROR:
if (add_literal(moo, MOO_ERROR_TO_OOP(MOO_EGENERIC), &index) <= -1 ||
emit_single_param_instruction(moo, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
GET_TOKEN (moo);
break;
case MOO_IOTOK_ERRLIT: case MOO_IOTOK_ERRLIT:
{ {
moo_oop_t tmp; moo_oop_t tmp;
tmp = string_to_error (moo, TOKEN_NAME(moo)); tmp = string_to_error (moo, TOKEN_NAME(moo), TOKEN_LOC(moo));
if (!tmp) return -1; if (!tmp) return -1;
if (add_literal(moo, tmp, &index) <= -1 || if (add_literal(moo, tmp, &index) <= -1 ||
@ -7783,11 +7778,8 @@ static moo_oop_t token_to_literal (moo_t* moo, int rdonly)
case MOO_IOTOK_FALSE: case MOO_IOTOK_FALSE:
return moo->_false; return moo->_false;
case MOO_IOTOK_ERROR:
return MOO_ERROR_TO_OOP(MOO_EGENERIC);
case MOO_IOTOK_ERRLIT: case MOO_IOTOK_ERRLIT:
return string_to_error (moo, TOKEN_NAME(moo)); return string_to_error(moo, TOKEN_NAME(moo), TOKEN_LOC(moo));
case MOO_IOTOK_CHARLIT: case MOO_IOTOK_CHARLIT:
MOO_ASSERT (moo, TOKEN_NAME_LEN(moo) == 1); MOO_ASSERT (moo, TOKEN_NAME_LEN(moo) == 1);

View File

@ -2775,7 +2775,7 @@ static moo_pfrc_t pf_integer_mul (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
} }
static moo_pfrc_t pf_integer_quo (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_integer_div (moo_t* moo, moo_ooi_t nargs)
{ {
moo_oop_t rcv, arg, quo; moo_oop_t rcv, arg, quo;
@ -2809,7 +2809,7 @@ static moo_pfrc_t pf_integer_rem (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
} }
static moo_pfrc_t pf_integer_quo2 (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_integer_mdiv (moo_t* moo, moo_ooi_t nargs)
{ {
moo_oop_t rcv, arg, quo; moo_oop_t rcv, arg, quo;
@ -2826,7 +2826,7 @@ static moo_pfrc_t pf_integer_quo2 (moo_t* moo, moo_ooi_t nargs)
return MOO_PF_SUCCESS; return MOO_PF_SUCCESS;
} }
static moo_pfrc_t pf_integer_rem2 (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_integer_mod (moo_t* moo, moo_ooi_t nargs)
{ {
moo_oop_t rcv, arg, quo, rem; moo_oop_t rcv, arg, quo, rem;
@ -3523,19 +3523,19 @@ static pf_t pftab[] =
{ "_integer_bitor", { pf_integer_bitor, 1, 1 } }, { "_integer_bitor", { pf_integer_bitor, 1, 1 } },
{ "_integer_bitshift", { pf_integer_bitshift, 1, 1 } }, { "_integer_bitshift", { pf_integer_bitshift, 1, 1 } },
{ "_integer_bitxor", { pf_integer_bitxor, 1, 1 } }, { "_integer_bitxor", { pf_integer_bitxor, 1, 1 } },
{ "_integer_div", { pf_integer_div, 1, 1 } },
{ "_integer_eq", { pf_integer_eq, 1, 1 } }, { "_integer_eq", { pf_integer_eq, 1, 1 } },
{ "_integer_ge", { pf_integer_ge, 1, 1 } }, { "_integer_ge", { pf_integer_ge, 1, 1 } },
{ "_integer_gt", { pf_integer_gt, 1, 1 } }, { "_integer_gt", { pf_integer_gt, 1, 1 } },
{ "_integer_inttostr", { pf_integer_inttostr, 1, 1 } }, { "_integer_inttostr", { pf_integer_inttostr, 1, 1 } },
{ "_integer_le", { pf_integer_le, 1, 1 } }, { "_integer_le", { pf_integer_le, 1, 1 } },
{ "_integer_lt", { pf_integer_lt, 1, 1 } }, { "_integer_lt", { pf_integer_lt, 1, 1 } },
{ "_integer_mdiv", { pf_integer_mdiv, 1, 1 } },
{ "_integer_mod", { pf_integer_mod, 1, 1 } },
{ "_integer_mul", { pf_integer_mul, 1, 1 } }, { "_integer_mul", { pf_integer_mul, 1, 1 } },
{ "_integer_ne", { pf_integer_ne, 1, 1 } }, { "_integer_ne", { pf_integer_ne, 1, 1 } },
{ "_integer_negated", { pf_integer_negated, 0, 0 } }, { "_integer_negated", { pf_integer_negated, 0, 0 } },
{ "_integer_quo", { pf_integer_quo, 1, 1 } },
{ "_integer_quo2", { pf_integer_quo2, 1, 1 } },
{ "_integer_rem", { pf_integer_rem, 1, 1 } }, { "_integer_rem", { pf_integer_rem, 1, 1 } },
{ "_integer_rem2", { pf_integer_rem2, 1, 1 } },
{ "_integer_sub", { pf_integer_sub, 1, 1 } } { "_integer_sub", { pf_integer_sub, 1, 1 } }
}; };

View File

@ -404,7 +404,7 @@ static int print_object (moo_t* moo, moo_oow_t mask, moo_oop_t oop, outbfmt_t ou
} }
else if (MOO_OOP_IS_ERROR(oop)) else if (MOO_OOP_IS_ERROR(oop))
{ {
if (outbfmt(moo, mask, "error(%zd)", MOO_OOP_TO_ERROR(oop)) <= -1) return -1; if (outbfmt(moo, mask, "#\\%zd", MOO_OOP_TO_ERROR(oop)) <= -1) return -1;
} }
else else
{ {

View File

@ -331,9 +331,8 @@ enum moo_iotok_type_t
MOO_IOTOK_SYMLIT, MOO_IOTOK_SYMLIT,
MOO_IOTOK_NUMLIT, MOO_IOTOK_NUMLIT,
MOO_IOTOK_RADNUMLIT, MOO_IOTOK_RADNUMLIT,
MOO_IOTOK_ERRLIT, /* error(NN) */ MOO_IOTOK_ERRLIT, /* #\NN */
MOO_IOTOK_ERROR, /* error */
MOO_IOTOK_NIL, MOO_IOTOK_NIL,
MOO_IOTOK_SELF, MOO_IOTOK_SELF,
MOO_IOTOK_SUPER, MOO_IOTOK_SUPER,

View File

@ -1541,7 +1541,7 @@ enum moo_synerrnum_t
MOO_SYNERR_CMTNC, /* comment not closed */ MOO_SYNERR_CMTNC, /* comment not closed */
MOO_SYNERR_STRNC, /* string not closed */ MOO_SYNERR_STRNC, /* string not closed */
MOO_SYNERR_CLTNT, /* character literal not terminated */ MOO_SYNERR_CLTNT, /* character literal not terminated */
MOO_SYNERR_HLTNT, /* hased literal not terminated */ MOO_SYNERR_HLTNT, /* hashed literal not terminated */
MOO_SYNERR_CHARLITINVAL, /* wrong character literal */ MOO_SYNERR_CHARLITINVAL, /* wrong character literal */
MOO_SYNERR_COLON, /* : expected */ MOO_SYNERR_COLON, /* : expected */
MOO_SYNERR_STRING, /* string expected */ MOO_SYNERR_STRING, /* string expected */