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:
parent
8a6e2c601c
commit
c85bf336ad
@ -8,17 +8,17 @@ class(#limited) Error(Apex)
|
||||
|
||||
pooldic Error.Code
|
||||
{
|
||||
ENOERR := error(0).
|
||||
EGENERIC := error(1).
|
||||
ENOIMPL := error(2).
|
||||
ESYSERR := error(3).
|
||||
EINTERN := error(4).
|
||||
ESYSMEM := error(5).
|
||||
EOOMEM := error(6).
|
||||
EINVAL := error(7).
|
||||
ENOENT := error(8).
|
||||
EPERM := error(12).
|
||||
ERANGE := error(20).
|
||||
ENOERR := #\0.
|
||||
EGENERIC := #\1.
|
||||
ENOIMPL := #\2.
|
||||
ESYSERR := #\3.
|
||||
EINTERN := #\4.
|
||||
ESYSMEM := #\5.
|
||||
EOOMEM := #\6.
|
||||
EINVAL := #\7.
|
||||
ENOENT := #\8.
|
||||
EPERM := #\12.
|
||||
ERANGE := #\20.
|
||||
(* add more items... *)
|
||||
}
|
||||
|
||||
@ -300,8 +300,8 @@ extend Error
|
||||
|
||||
pooldic/const
|
||||
{
|
||||
NONE := error(0).
|
||||
GENERIC := error(1).
|
||||
NONE := #\0.
|
||||
GENERIC := #\1.
|
||||
}
|
||||
-------------------------------- *)
|
||||
|
||||
|
@ -123,30 +123,39 @@ class(#limited) Number(Magnitude)
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
method quo: aNumber
|
||||
method div: aNumber
|
||||
{
|
||||
<primitive: #_integer_quo>
|
||||
## integer division rounded toward zero
|
||||
<primitive: #_integer_div>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
method rem: aNumber
|
||||
{
|
||||
## integer remainder rounded toward zero
|
||||
<primitive: #_integer_rem>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
method // aNumber
|
||||
method mdiv: aNumber
|
||||
{
|
||||
<primitive: #_integer_quo2>
|
||||
## integer division quotient
|
||||
<primitive: #_integer_mdiv>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
method \\ aNumber
|
||||
method mod: aNumber
|
||||
{
|
||||
<primitive: #_integer_rem2>
|
||||
## integer division remainder
|
||||
<primitive: #_integer_mod>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
##method / aNumber
|
||||
##{
|
||||
## ## fraction? fixed-point decimal? floating-point?
|
||||
##}
|
||||
|
||||
method = aNumber
|
||||
{
|
||||
<primitive: #_integer_eq>
|
||||
|
132
moo/lib/comp.c
132
moo/lib/comp.c
@ -117,7 +117,6 @@ static struct voca_t
|
||||
{ 4, { 'e','l','s','e' } },
|
||||
{ 5, { 'e','l','s','i','f' } },
|
||||
{ 6, { 'e','n','s','u','r','e', } },
|
||||
{ 5, { 'e','r','r','o','r' } },
|
||||
{ 9, { 'e','x','c','e','p','t','i','o','n' } },
|
||||
{ 6, { 'e','x','t','e','n','d' } },
|
||||
{ 5, { 'f','a','l','s','e' } },
|
||||
@ -182,7 +181,6 @@ enum voca_id_t
|
||||
VOCA_ELSE,
|
||||
VOCA_ELSIF,
|
||||
VOCA_ENSURE,
|
||||
VOCA_ERROR,
|
||||
VOCA_EXCEPTION,
|
||||
VOCA_EXTEND,
|
||||
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)
|
||||
{
|
||||
/* TODO: support full unicode */
|
||||
@ -284,13 +281,14 @@ static MOO_INLINE int is_binselchar (moo_ooci_t c)
|
||||
/*
|
||||
* binary-selector-character :=
|
||||
* '&' | '*' | '+' | '-' | '/' |
|
||||
* '<' | '>' | '=' | '?' | '@' |
|
||||
* '\' | '~' | '|'
|
||||
* '<' | '>' | '=' | '@' | '~' | '|'
|
||||
*
|
||||
* - 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.
|
||||
* - an exclamation mark is excluded intentioinally because i can't tell
|
||||
* 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)
|
||||
@ -303,9 +301,7 @@ static MOO_INLINE int is_binselchar (moo_ooci_t c)
|
||||
case '<':
|
||||
case '>':
|
||||
case '=':
|
||||
case '?':
|
||||
case '@':
|
||||
case '\\':
|
||||
case '|':
|
||||
case '~':
|
||||
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)
|
||||
{
|
||||
return is_alnumchar(c) || c == '_';
|
||||
return is_alnumchar(c) || c == '_' || c == '?';
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -342,7 +338,7 @@ static MOO_INLINE int is_closing_char (moo_ooci_t c)
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}VOCA_ERROR,
|
||||
#endif
|
||||
|
||||
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_TRUE,
|
||||
VOCA_FALSE,
|
||||
VOCA_ERROR,
|
||||
VOCA_THIS_CONTEXT,
|
||||
VOCA_THIS_PROCESS,
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
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. */
|
||||
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++;
|
||||
}
|
||||
|
||||
return MOO_ERROR_TO_OOP(num);
|
||||
}
|
||||
|
||||
|
||||
/* ---------------------------------------------------------------------
|
||||
* 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);
|
||||
}
|
||||
|
||||
if (c == '(' && is_token_word(moo, VOCA_ERROR))
|
||||
{
|
||||
/* 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 (c == ':')
|
||||
{
|
||||
#if 0
|
||||
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);
|
||||
}
|
||||
else if (is_token_word(moo, VOCA_ERROR))
|
||||
{
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_ERROR);
|
||||
}
|
||||
else if (is_token_word(moo, VOCA_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;
|
||||
int radix = 0, r;
|
||||
|
||||
moo_oow_t radix = 0;
|
||||
int radix_overflowed = 0;
|
||||
|
||||
c = moo->c->lxc.c;
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_NUMLIT);
|
||||
|
||||
/*TODO: support a complex numeric literal */
|
||||
do
|
||||
{
|
||||
if (radix <= 36)
|
||||
{
|
||||
/* 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);
|
||||
radix = radix * 10 + r;
|
||||
rv = radix * 10 + r;
|
||||
if (rv < radix) radix_overflowed = 1;
|
||||
radix = rv;
|
||||
}
|
||||
|
||||
ADD_TOKEN_CHAR(moo, c);
|
||||
GET_CHAR_TO (moo, c);
|
||||
if (c == '_')
|
||||
{
|
||||
/* i allow digit separation with _ as in 123_456. */
|
||||
moo_iolxc_t underscore;
|
||||
underscore = moo->c->lxc;
|
||||
GET_CHAR_TO(moo, c);
|
||||
@ -1273,9 +1251,9 @@ static int get_numlit (moo_t* moo, int negated)
|
||||
{
|
||||
/* 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));
|
||||
return -1;
|
||||
}
|
||||
@ -1311,9 +1289,12 @@ static int get_numlit (moo_t* moo, int negated)
|
||||
while (CHAR_TO_NUM(c, radix) < radix);
|
||||
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_RADNUMLIT);
|
||||
}
|
||||
|
||||
unget_char (moo, &moo->c->lxc);
|
||||
}
|
||||
else
|
||||
{
|
||||
unget_char (moo, &moo->c->lxc);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: handle floating point number
|
||||
@ -1743,7 +1724,6 @@ retry:
|
||||
ADD_TOKEN_CHAR(moo, c);
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_HASHBRACK);
|
||||
break;
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
/* quoted symbol literal */
|
||||
@ -1751,6 +1731,27 @@ retry:
|
||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_SYMLIT); /* change the symbol type to symbol */
|
||||
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:
|
||||
/* symbol-literal := "#" symbol-body
|
||||
* 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);
|
||||
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:
|
||||
{
|
||||
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 (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:
|
||||
return moo->_false;
|
||||
|
||||
case MOO_IOTOK_ERROR:
|
||||
return MOO_ERROR_TO_OOP(MOO_EGENERIC);
|
||||
|
||||
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:
|
||||
MOO_ASSERT (moo, TOKEN_NAME_LEN(moo) == 1);
|
||||
|
@ -2775,7 +2775,7 @@ static moo_pfrc_t pf_integer_mul (moo_t* moo, moo_ooi_t nargs)
|
||||
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;
|
||||
|
||||
@ -2809,7 +2809,7 @@ static moo_pfrc_t pf_integer_rem (moo_t* moo, moo_ooi_t nargs)
|
||||
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;
|
||||
|
||||
@ -2826,7 +2826,7 @@ static moo_pfrc_t pf_integer_quo2 (moo_t* moo, moo_ooi_t nargs)
|
||||
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;
|
||||
|
||||
@ -3523,19 +3523,19 @@ static pf_t pftab[] =
|
||||
{ "_integer_bitor", { pf_integer_bitor, 1, 1 } },
|
||||
{ "_integer_bitshift", { pf_integer_bitshift, 1, 1 } },
|
||||
{ "_integer_bitxor", { pf_integer_bitxor, 1, 1 } },
|
||||
{ "_integer_div", { pf_integer_div, 1, 1 } },
|
||||
{ "_integer_eq", { pf_integer_eq, 1, 1 } },
|
||||
{ "_integer_ge", { pf_integer_ge, 1, 1 } },
|
||||
{ "_integer_gt", { pf_integer_gt, 1, 1 } },
|
||||
{ "_integer_inttostr", { pf_integer_inttostr, 1, 1 } },
|
||||
{ "_integer_le", { pf_integer_le, 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_ne", { pf_integer_ne, 1, 1 } },
|
||||
{ "_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_rem2", { pf_integer_rem2, 1, 1 } },
|
||||
{ "_integer_sub", { pf_integer_sub, 1, 1 } }
|
||||
};
|
||||
|
||||
|
@ -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))
|
||||
{
|
||||
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
|
||||
{
|
||||
|
@ -331,9 +331,8 @@ enum moo_iotok_type_t
|
||||
MOO_IOTOK_SYMLIT,
|
||||
MOO_IOTOK_NUMLIT,
|
||||
MOO_IOTOK_RADNUMLIT,
|
||||
MOO_IOTOK_ERRLIT, /* error(NN) */
|
||||
MOO_IOTOK_ERRLIT, /* #\NN */
|
||||
|
||||
MOO_IOTOK_ERROR, /* error */
|
||||
MOO_IOTOK_NIL,
|
||||
MOO_IOTOK_SELF,
|
||||
MOO_IOTOK_SUPER,
|
||||
|
@ -1541,7 +1541,7 @@ enum moo_synerrnum_t
|
||||
MOO_SYNERR_CMTNC, /* comment not closed */
|
||||
MOO_SYNERR_STRNC, /* string not closed */
|
||||
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_COLON, /* : expected */
|
||||
MOO_SYNERR_STRING, /* string expected */
|
||||
|
Loading…
Reference in New Issue
Block a user