changed %(, %[, %{ to ##(, ##[, ##{ respectively

put back % into is_binselchar().
attempting to support a string-like byte array literal - B"XXXX"
This commit is contained in:
hyunghwan.chung 2019-06-27 07:43:17 +00:00
parent fcb987891e
commit ea4d782c1d
13 changed files with 147 additions and 97 deletions

View File

@ -24,32 +24,28 @@
* C'X' -> charcter??
* C"X" -> character??
* 'XXXX' string
* "XXXX" string with escaping
* B"XXXXX" -> byte array with escaping?
* B'XXXXXX' -> byte array
* 'XXXX' string literal
* "XXXX" string litearl with escaping
* B'XXXXXX' -> byte array literal
* B"XXXXX" -> byte array literal with escaping
* #XXXX symbol
* #'XXXX' quoted symbol
* #"XXXX" quoted symbol with escaping
* #\eNNNN error literal
* #\pNNNN smptr literal
* %eNNNN <---------
* %pNNNN <---------
* #\e123 Error literal
* #\pB8000000 SmallPointer(smptr) literal
* #() Array
* #[] ByteArray
* #{} Dictionary
* #{} Dictionary - not supported yet
The following are not literals.
* %() Array
* %[] ByteArray
* %{} Dictionary
* ##() Array expression
* ##[] ByteArray expression
* ##{} Dictionary expression
* S%[] String literal with each character specified
** S%{A B C '\n'}

View File

@ -1284,7 +1284,7 @@ class Dictionary(AssociativeCollection)
{
/* [NOTE]
* VM require Dictionary to implement new: and __put_assoc
* for the dictionary expression notation - %{ }
* for the dictionary expression notation - ##{ }
*/
// TODO: implement Dictionary as a Hashed List/Table or Red-Black Tree
@ -1299,7 +1299,7 @@ class Dictionary(AssociativeCollection)
* to a dictionary with the dictionary/association expression notation
* like this:
*
* %{ 1 -> 20, #moo -> 999 }
* ##{ 1 -> 20, #moo -> 999 }
*
* it must return self for the way VM works.
*/

View File

@ -221,7 +221,7 @@ class Fcgi.ParamRecord(Fcgi.Record)
{
//# TODO: implement this...
/*
(aString subStrings: %(char)) do: [:each |
(aString subStrings: ##(char)) do: [:each |
equal := each indexOf: $=.
equal = 0
ifTrue: [tempFields at: each put: nil]
@ -737,7 +737,7 @@ class MyObject(Object)
fcgi := FcgiServer new.
[
| ss |
fcgi start: %(
fcgi start: ##(
SocketAddress fromString: ('[::]:' & base_port asString),
SocketAddress fromString: ('0.0.0.0:' & (base_port + 1) asString)
).
@ -783,7 +783,7 @@ fcgi connect: addr.
fcgi := FcgiServer new.
[
| ss |
fcgi start: %(
fcgi start: ##(
SocketAddress fromString: '[::]:7777',
SocketAddress fromString: '0.0.0.0:7776'
).
@ -811,7 +811,7 @@ fcgi connect: addr.
[
fcgi := FcgiServer new.
[
fcgi start: %(
fcgi start: ##(
SocketAddress fromString: '[::]:7777',
SocketAddress fromString: '0.0.0.0:7776'
).

View File

@ -420,7 +420,7 @@ class MyObject(Object)
httpd := HttpServer new.
[
| ss |
httpd start: %(
httpd start: ##(
SocketAddress fromString: ('[::]:' & base_port asString),
SocketAddress fromString: ('0.0.0.0:' & (base_port + 1) asString)
).
@ -462,7 +462,7 @@ httpd connect: addr.
httpd := HttpServer new.
[
| ss |
httpd start: %(
httpd start: ##(
SocketAddress fromString: '[::]:7777',
SocketAddress fromString: '0.0.0.0:7776'
).
@ -490,7 +490,7 @@ httpd connect: addr.
[
httpd := HttpServer new.
[
httpd start: %(
httpd start: ##(
SocketAddress fromString: '[::]:7777',
SocketAddress fromString: '0.0.0.0:7776'
).

View File

@ -217,19 +217,19 @@ class MyObject(Object)
a :=999.
a := %(
a := ##(
1,
2,
a,
4,
1 + 1,
%( 1, 2, %(a, a := a + 1, a, if (a > 10) { a + 20 } ), 3),
##( 1, 2, ##(a, a := a + 1, a, if (a > 10) { a + 20 } ), 3),
2 + 2,
#'a b c'
).
/* Dictionary ???
a := %{
a := ##{
key -> value ,
key -> value ,
key -> value ,
@ -275,7 +275,7 @@ class MyObject(Object)
}.*/
a := %{
a := ##{
'aaa' -> 10,
'bbb' -> 20,
'bbb' -> 30,
@ -365,6 +365,6 @@ a free.
/*
pooldic XXD {
#abc := #(1 2 3).
#def := %( 1, 3, 4 ). // syntax error - literal expected where %( is
#def := ##( 1, 3, 4 ). // syntax error - literal expected where ##( is
}
*/

View File

@ -611,7 +611,7 @@ extend X11
at: self.LLEventType.CONFIGURE_NOTIFY put: #__handle_configure_notify:on:;
at: self.LLEventType.CLIENT_MESSAGE put: #__handle_client_message:on:.
*/
self.llevent_blocks := %{
self.llevent_blocks := ##{
self.LLEventType.KEY_PRESS -> #__handle_key_event:on:,
self.LLEventType.KEY_RELEASE -> #__handle_key_event:on:,
self.LLEventType.BUTTON_PRESS -> #__handle_button_event:on:,

View File

@ -161,7 +161,7 @@ extend MyObject
{
| tc limit |
tc := %(
tc := ##(
// 0 - 4
[MyObject.Donkey v == 901982],
[selfns.MyObject.Donkey v == 901982],
@ -396,7 +396,7 @@ extend MyObject
[
| k |
k := String new.
(%( 1 + 2, -21391239218392 * +291382913821, 19p10 div: 3 ) asOrderedCollection) doWithIndex: [:each :index | k := k & (index asString) & '=>' & (each asString) & ' '. ].
(##( 1 + 2, -21391239218392 * +291382913821, 19p10 div: 3 ) asOrderedCollection) doWithIndex: [:each :index | k := k & (index asString) & '=>' & (each asString) & ' '. ].
k = '0=>3 1=>-6233041613697111534195832 2=>3.3333333333333333333 '.
],

View File

@ -126,7 +126,7 @@ class MyObject(Object)
sem wait.
sem wait.
^%( v, p ) // v must be 2000, p must be 6000
^##( v, p ) // v must be 2000, p must be 6000
}
/*
@ -154,10 +154,10 @@ class MyObject(Object)
{
| tc limit |
tc := %(
tc := ##(
// 0 - 4
[ (self test_quicksort: #(7 12 3 20 5 8 2) copy) = #(2 3 5 7 8 12 20)],
[ (self test_quicksort: %(99, 12, 18, 7, 12, 3, 20, 5, 8, 2)) = #(2 3 5 7 8 12 12 18 20 99)],
[ (self test_quicksort: ##(99, 12, 18, 7, 12, 3, 20, 5, 8, 2)) = #(2 3 5 7 8 12 12 18 20 99)],
[ (self test_on_do_with: 10 with: 2) == 5 ],
[ (self test_on_do_with: -10 with: 0) == 0 ],
[ self test_ensure_with: -20945. self.ensure_tester_v == -20945 ],

View File

@ -34,7 +34,7 @@ class MyObject(Object)
rec := [ :y :z | 22p108 - (18p815 - (16p1500 div: z) div: y) ].
// results := %( 4.0, 425 div: 100.0 ) asOrderedCollection.
// results := ##( 4.0, 425 div: 100.0 ) asOrderedCollection.
results := OrderedCollection new.
results add: 4.0; add: (425.00 div: 100.00).
@ -56,7 +56,7 @@ class MyObject(Object)
{
| tc limit |
tc := %(
tc := ##(
// 0 - 4
[(Object isKindOf: Class) == true],
[(Object isKindOf: Apex) == true],

View File

@ -56,7 +56,7 @@ sg removeSemaphore: s1.
{
| tc limit |
tc := %(
tc := ##(
// 0 - 4
[self test_terminate == 180],
[self test_sg == nil]

View File

@ -42,8 +42,8 @@ class MyObject(Object)
ffi := FFI new: 'libc.so.6'.
now := ffi call: #time signature: 'l)i' arguments: #(0).
////ffi call: #srand signature: 'i)' arguments: %(now).
ffi call: #srandom signature: 'i)' arguments: %(now).
////ffi call: #srand signature: 'i)' arguments: ##(now).
ffi call: #srandom signature: 'i)' arguments: ##(now).
[
divr_ubound := 16rFFFFFFFFFFFFFFFFFFFFFFFF.

View File

@ -307,11 +307,10 @@ 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.
@ -325,6 +324,7 @@ static MOO_INLINE int is_binselchar (moo_ooci_t c)
case '+':
case '-':
case '/':
case '%':
case '<':
case '>':
case '=':
@ -1169,7 +1169,7 @@ static int skip_comment (moo_t* moo)
}
else if (c == '#')
{
/* handle #! or ## */
/* handle #! */
/* save the last character */
lc = moo->c->lxc;
@ -1626,7 +1626,7 @@ static int get_charlit (moo_t* moo)
return 0;
}
static int get_strlit (moo_t* moo)
static int get_strlit (moo_t* moo, int byte_only)
{
/*
* string-literal := single-quote string-character* single-quote
@ -1676,7 +1676,7 @@ static int get_strlit (moo_t* moo)
return 0;
}
static int get_string (moo_t* moo, moo_ooch_t end_char, moo_ooch_t esc_char, int regex, moo_oow_t preescaped)
static int get_string (moo_t* moo, moo_ooch_t end_char, moo_ooch_t esc_char, int byte_only, int regex, moo_oow_t preescaped)
{
moo_ooci_t c;
moo_oow_t escaped = preescaped;
@ -1918,7 +1918,7 @@ retry:
break;
case '\'': /* string literal */
if (get_strlit(moo) <= -1) return -1;
if (get_strlit(moo, 0) <= -1) return -1;
break;
case ':':
@ -1981,39 +1981,6 @@ retry:
SET_TOKEN_TYPE (moo, MOO_IOTOK_SEMICOLON);
goto single_char_token;
case '%':
SET_TOKEN_TYPE (moo, MOO_IOTOK_PERCENT);
ADD_TOKEN_CHAR (moo, c);
GET_CHAR_TO (moo, c);
if (c == '(')
{
/* %( - array expression */
ADD_TOKEN_CHAR (moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_PERCPAREN);
}
else if (c == '[')
{
/* %[ - byte-array expression */
ADD_TOKEN_CHAR (moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_PERCBRACK);
}
else if (c == '{')
{
/* %{ - dictionary expression */
ADD_TOKEN_CHAR (moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_PERCBRACE);
}
else
{
/* NOTE the percent sign not followed by ( or } is
* meaningless at this moment. however, i return
* it as a token so that the compiler anyway
* will fail eventually */
unget_char (moo, &moo->c->lxc);
}
break;
case '#':
ADD_TOKEN_CHAR (moo, c);
GET_CHAR_TO (moo, c);
@ -2023,6 +1990,38 @@ retry:
moo_setsynerr (moo, MOO_SYNERR_HLTNT, LEXER_LOC(moo), MOO_NULL);
return -1;
case '#':
SET_TOKEN_TYPE (moo, MOO_IOTOK_DHASH);
ADD_TOKEN_CHAR (moo, c);
GET_CHAR_TO (moo, c);
if (c == '(')
{
/* ##( - array expression */
ADD_TOKEN_CHAR (moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_DHASHPAREN);
}
else if (c == '[')
{
/* ##[ - byte array expression */
ADD_TOKEN_CHAR (moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_DHASHBRACK);
}
else if (c == '{')
{
/* ##{ - dictionary expression */
ADD_TOKEN_CHAR (moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_DHASHBRACE);
}
else
{
/* NOTE the double hashes not followed by (, [, or { is
* meaningless at this moment. however, i return
* it as a token so that the compiler anyway
* will fail eventually */
unget_char (moo, &moo->c->lxc);
}
break;
case '(':
/* #( - array literal */
ADD_TOKEN_CHAR (moo, c);
@ -2040,10 +2039,10 @@ retry:
ADD_TOKEN_CHAR (moo, c);
SET_TOKEN_TYPE (moo, MOO_IOTOK_HASHBRACE);
break;
case '\'':
/* #'XXXX' - quoted symbol literal */
if (get_strlit(moo) <= -1) return -1; /* reuse the string literal tokenizer */
if (get_strlit(moo, 0) <= -1) return -1; /* reuse the string literal tokenizer */
SET_TOKEN_TYPE (moo, MOO_IOTOK_SYMLIT); /* change the symbol type to symbol */
break;
@ -2051,7 +2050,7 @@ retry:
/* #"XXXX" - quoted symbol literal with C-style escape sequences.
* if MOO_PRAGMA_QC is set, this part should never be reached */
MOO_ASSERT (moo, !(moo->c->pragma_flags & MOO_PRAGMA_QC));
if (get_string(moo, '"', '\\', 0, 0) <= -1) return -1;
if (get_string(moo, '"', '\\', 0, 0, 0) <= -1) return -1;
SET_TOKEN_TYPE (moo, MOO_IOTOK_SYMLIT); /* change the symbol type to symbol */
break;
@ -2214,12 +2213,12 @@ retry:
case '"':
/* if MOO_PRAGMA_QC is set, this part should never be reached */
MOO_ASSERT (moo, !(moo->c->pragma_flags & MOO_PRAGMA_QC));
if (get_string(moo, '"', '\\', 0, 0) <= -1) return -1;
if (get_string(moo, '"', '\\', 0, 0, 0) <= -1) return -1;
break;
case 'C': /* a character with a C-style escape sequence */
case 'S': /* a string with a C-style escape sequences */
case 'M': /* a symbol with a C-style escape sequences */
case 'B': /* byte array in a string like notation */
{
moo_ooci_t saved_c = c;
@ -2227,7 +2226,7 @@ retry:
if (c == '\'')
{
/*GET_CHAR (moo);*/
if (get_string(moo, '\'', '\\', 0, 0) <= -1) return -1;
if (get_strlit(moo, (saved_c == 'B')) <= -1) return -1;
if (saved_c == 'C')
{
@ -2238,9 +2237,28 @@ retry:
}
SET_TOKEN_TYPE (moo, MOO_IOTOK_CHARLIT);
}
else if (saved_c == 'M')
else if (saved_c == 'B')
{
SET_TOKEN_TYPE (moo, MOO_IOTOK_SYMLIT);
SET_TOKEN_TYPE (moo, MOO_IOTOK_BYTEARRAYLIT);
}
}
else if (c == '\"')
{
/*GET_CHAR (moo);*/
if (get_string(moo, '\"', '\\', (saved_c == 'B'), 0, 0) <= -1) return -1;
if (saved_c == 'C')
{
if (moo->c->tok.name.len != 1)
{
moo_setsynerr (moo, MOO_SYNERR_CHARLITINVAL, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
SET_TOKEN_TYPE (moo, MOO_IOTOK_CHARLIT);
}
else if (saved_c == 'B')
{
SET_TOKEN_TYPE (moo, MOO_IOTOK_BYTEARRAYLIT);
}
}
else
@ -2991,6 +3009,18 @@ static int add_symbol_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t offs
return add_literal(moo, tmp, index);
}
static int add_byte_array_literal (moo_t* moo, const moo_oocs_t* str, moo_oow_t* index)
{
/* see read_byte_array_literal for comparision */
moo_oop_t tmp;
moo_oow_t i;
tmp = moo_instantiate(moo, moo->_byte_array, MOO_NULL, str->len);
if (!tmp) return -1;
for (i = 0; i < str->len; i++) MOO_OBJ_SET_BYTE_VAL(tmp, i, str->ptr[i]);
return add_literal(moo, tmp, index);
}
static MOO_INLINE int set_class_fqn (moo_t* moo, moo_cunit_class_t* cc, const moo_oocs_t* name)
{
if (copy_string_to(moo, name, &cc->fqn, &cc->fqn_capa, 0, '\0') <= -1) return -1;
@ -5026,7 +5056,7 @@ static int read_array_literal (moo_t* moo, int rdonly, moo_oop_t* xlit)
}
else if (TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) break;
lit = token_to_literal (moo, rdonly);
lit = token_to_literal(moo, rdonly);
if (!lit || add_to_array_literal_buffer(moo, lit) <= -1) goto oops;
GET_TOKEN_GOTO (moo, oops);
@ -5094,7 +5124,7 @@ static int _compile_array_expression (moo_t* moo, int closer_token, int bcode_ma
moo_oow_t maip;
moo_ioloc_t aeloc;
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_PERCPAREN || TOKEN_TYPE(moo) == MOO_IOTOK_PERCBRACK);
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_DHASHPAREN || TOKEN_TYPE(moo) == MOO_IOTOK_DHASHBRACK);
maip = cc->mth.code.len;
if (emit_single_param_instruction(moo, bcode_make, 0) <= -1) return -1;
@ -5159,7 +5189,7 @@ static int compile_dictionary_expression (moo_t* moo)
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
moo_oow_t mdip;
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_PERCBRACE);
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_DHASHBRACE);
GET_TOKEN (moo); /* read a token after :{ */
@ -5425,6 +5455,11 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons
GET_TOKEN (moo);
break;
case MOO_IOTOK_BYTEARRAYLIT:
/* B"xxxxx". see MOO_IOTOK_HASHBRACK below for comparision */
if (add_byte_array_literal(moo, TOKEN_NAME(moo), &index) <= -1 ||
emit_single_param_instruction(moo, BCODE_PUSH_LITERAL_0, index) <= -1) return -1;
break;
case MOO_IOTOK_HASHPAREN: /* #( */
/*GET_TOKEN (moo);*/
@ -5443,15 +5478,15 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons
break;
#endif
case MOO_IOTOK_PERCPAREN: /* %( */
case MOO_IOTOK_DHASHPAREN: /* ##( */
if (compile_array_expression(moo) <= -1) return -1;
break;
case MOO_IOTOK_PERCBRACK: /* %[ */
case MOO_IOTOK_DHASHBRACK: /* ##[ */
if (compile_bytearray_expression(moo) <= -1) return -1;
break;
case MOO_IOTOK_PERCBRACE: /* %{ */
case MOO_IOTOK_DHASHBRACE: /* ##{ */
if (compile_dictionary_expression(moo) <= -1) return -1;
break;
@ -8832,6 +8867,24 @@ static moo_oop_t token_to_literal (moo_t* moo, int rdonly)
return lit;
}
case MOO_IOTOK_BYTEARRAYLIT:
{
moo_oop_t lit;
moo_oow_t i;
lit = moo_instantiate(moo, moo->_byte_array, MOO_NULL, TOKEN_NAME_LEN(moo));
if (lit)
{
for (i = 0; i < MOO_OBJ_GET_SIZE(lit); i++) MOO_OBJ_SET_BYTE_VAL(lit, i, TOKEN_NAME_PTR(moo)[i]);
if (rdonly)
{
MOO_ASSERT (moo, MOO_OOP_IS_POINTER(lit));
MOO_OBJ_SET_FLAGS_RDONLY (lit, 1);
}
}
return lit;
}
case MOO_IOTOK_IDENT:
case MOO_IOTOK_IDENT_DOTTED:
{

View File

@ -286,6 +286,7 @@ enum moo_iotok_type_t
MOO_IOTOK_SCALEDFPDECLIT, /* NNpNNNN.NN e.g. 5p10.3 ===> 10.30000 */
MOO_IOTOK_ERRLIT, /* #\eNN */
MOO_IOTOK_SMPTRLIT, /* #\pXX */
MOO_IOTOK_BYTEARRAYLIT, /* B"ab\x99\x77" */
MOO_IOTOK_NIL,
MOO_IOTOK_SELF,
@ -317,7 +318,7 @@ enum moo_iotok_type_t
MOO_IOTOK_KEYWORD,
MOO_IOTOK_ASSIGN, /* := */
MOO_IOTOK_COLON, /* : */
MOO_IOTOK_PERCENT, /* % */
MOO_IOTOK_DHASH, /* ## */
MOO_IOTOK_RETURN, /* ^ */
MOO_IOTOK_LOCAL_RETURN, /* ^^ */
MOO_IOTOK_LBRACE,
@ -329,9 +330,9 @@ enum moo_iotok_type_t
MOO_IOTOK_HASHPAREN, /* #( - array literal */
MOO_IOTOK_HASHBRACK, /* #[ - byte array literal */
MOO_IOTOK_HASHBRACE, /* #{ - dictionary literal */
MOO_IOTOK_PERCPAREN, /* %( - array expression */
MOO_IOTOK_PERCBRACK, /* %[ - byte array expression */
MOO_IOTOK_PERCBRACE, /* %{ - dictionary expression */
MOO_IOTOK_DHASHPAREN, /* #( - array expression */
MOO_IOTOK_DHASHBRACK, /* #[ - byte array expression */
MOO_IOTOK_DHASHBRACE, /* #{ - dictionary expression */
MOO_IOTOK_PERIOD,
MOO_IOTOK_COMMA,
MOO_IOTOK_SEMICOLON