added new keywords to the compiler - ifnot, elsifnot

This commit is contained in:
hyunghwan.chung 2018-06-19 16:11:20 +00:00
parent 2c6072adf9
commit a6d72b928c
5 changed files with 72 additions and 18 deletions

View File

@ -28,8 +28,7 @@ class Collection(Object)
method detect: block method detect: block
{ {
self do: [ :el | if (block value: el) { ^el } ]. self detect: block ifNone: [ ^self error: 'not found' ].
^Error.Code.ENOENT
} }
method detect: block ifNone: exception_block method detect: block ifNone: exception_block
@ -43,6 +42,15 @@ class Collection(Object)
{ {
self subclassResponsibility: #add:. self subclassResponsibility: #add:.
} }
*)
method collect: block
{
| coll |
coll := self class new: self basicSize.
self do: [ :el | coll add: (block value: el) ].
^coll
}
method select: condition_block method select: condition_block
{ {
@ -56,11 +64,9 @@ class Collection(Object)
{ {
| coll | | coll |
coll := self class new: self basicSize. coll := self class new: self basicSize.
self do: [ :el | if (condition_block value: el) { } else { coll add: el } ]. self do: [ :el | ifnot (condition_block value: el) { coll add: el } ].
^coll ^coll
} }
*)
method emptyCheck method emptyCheck
{ {

View File

@ -219,6 +219,8 @@ class Fcgi.ParamRecord(Fcgi.Record)
if (aString notNil) if (aString notNil)
{ {
### TODO: implement this...
(*
(aString subStrings: %(char)) do: [:each | (aString subStrings: %(char)) do: [:each |
equal := each indexOf: $=. equal := each indexOf: $=.
equal = 0 equal = 0
@ -227,7 +229,7 @@ class Fcgi.ParamRecord(Fcgi.Record)
tempFields tempFields
at: (each first: equal - 1) at: (each first: equal - 1)
put: (each allButFirst: equal)] put: (each allButFirst: equal)]
] ] *)
}. }.
^tempFields ^tempFields

View File

@ -33,10 +33,10 @@ class System(Apex)
self.asyncsg := SemaphoreGroup new. self.asyncsg := SemaphoreGroup new.
class := System at: class_name. class := self at: class_name. ## System at: class_name.
if (class isError) if (class isError)
{ {
System error: ('Cannot find the class - ' & class_name). self error: ('Cannot find the class - ' & class_name).
}. }.
## start the gc finalizer process ## start the gc finalizer process

View File

@ -117,6 +117,7 @@ static struct voca_t
{ 5, { '#','d','u','a','l' } }, { 5, { '#','d','u','a','l' } },
{ 4, { 'e','l','s','e' } }, { 4, { 'e','l','s','e' } },
{ 5, { 'e','l','s','i','f' } }, { 5, { 'e','l','s','i','f' } },
{ 8, { 'e','l','s','i','f','n','o','t' } },
{ 6, { 'e','n','s','u','r','e', } }, { 6, { 'e','n','s','u','r','e', } },
{ 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' } },
@ -126,6 +127,7 @@ static struct voca_t
{ 4, { '#','g','e','t' } }, { 4, { '#','g','e','t' } },
{ 9, { '#','h','a','l','f','w','o','r','d' } }, { 9, { '#','h','a','l','f','w','o','r','d' } },
{ 2, { 'i','f' } }, { 2, { 'i','f' } },
{ 5, { 'i','f','n','o','t' } },
{ 10, { '#','i','m','m','u','t','a','b','l','e' } }, { 10, { '#','i','m','m','u','t','a','b','l','e' } },
{ 6, { 'i','m','p','o','r','t' } }, { 6, { 'i','m','p','o','r','t' } },
{ 8, { '#','i','n','c','l','u','d','e' } }, { 8, { '#','i','n','c','l','u','d','e' } },
@ -183,6 +185,7 @@ enum voca_id_t
VOCA_DUAL_S, VOCA_DUAL_S,
VOCA_ELSE, VOCA_ELSE,
VOCA_ELSIF, VOCA_ELSIF,
VOCA_ELSIFNOT,
VOCA_ENSURE, VOCA_ENSURE,
VOCA_EXCEPTION, VOCA_EXCEPTION,
VOCA_EXTEND, VOCA_EXTEND,
@ -192,6 +195,7 @@ enum voca_id_t
VOCA_GET_S, VOCA_GET_S,
VOCA_HALFWORD_S, VOCA_HALFWORD_S,
VOCA_IF, VOCA_IF,
VOCA_IFNOT,
VOCA_IMMUTABLE_S, VOCA_IMMUTABLE_S,
VOCA_IMPORT, VOCA_IMPORT,
VOCA_INCLUDE_S, VOCA_INCLUDE_S,
@ -372,6 +376,7 @@ static int is_reserved_word (const moo_oocs_t* ucs)
VOCA_IF, VOCA_IF,
VOCA_ELSE, VOCA_ELSE,
VOCA_ELSIF, VOCA_ELSIF,
VOCA_ELSIFNOT,
VOCA_WHILE, VOCA_WHILE,
VOCA_UNTIL, VOCA_UNTIL,
VOCA_DO, VOCA_DO,
@ -1204,6 +1209,10 @@ static int get_ident (moo_t* moo, moo_ooci_t char_read_ahead)
{ {
SET_TOKEN_TYPE (moo, MOO_IOTOK_IF); SET_TOKEN_TYPE (moo, MOO_IOTOK_IF);
} }
else if (is_token_word(moo, VOCA_IFNOT))
{
SET_TOKEN_TYPE (moo, MOO_IOTOK_IFNOT);
}
else if (is_token_word(moo, VOCA_ELSE)) else if (is_token_word(moo, VOCA_ELSE))
{ {
SET_TOKEN_TYPE (moo, MOO_IOTOK_ELSE); SET_TOKEN_TYPE (moo, MOO_IOTOK_ELSE);
@ -1212,6 +1221,10 @@ static int get_ident (moo_t* moo, moo_ooci_t char_read_ahead)
{ {
SET_TOKEN_TYPE (moo, MOO_IOTOK_ELSIF); SET_TOKEN_TYPE (moo, MOO_IOTOK_ELSIF);
} }
else if (is_token_word(moo, VOCA_ELSIFNOT))
{
SET_TOKEN_TYPE (moo, MOO_IOTOK_ELSIFNOT);
}
else if (is_token_word(moo, VOCA_WHILE)) else if (is_token_word(moo, VOCA_WHILE))
{ {
SET_TOKEN_TYPE (moo, MOO_IOTOK_WHILE); SET_TOKEN_TYPE (moo, MOO_IOTOK_WHILE);
@ -5661,14 +5674,28 @@ static int compile_if_expression (moo_t* moo)
moo_oow_t i, j; moo_oow_t i, j;
moo_oow_t jumptonext, precondpos, postcondpos, endoftrueblock; moo_oow_t jumptonext, precondpos, postcondpos, endoftrueblock;
moo_ioloc_t if_loc, brace_loc; moo_ioloc_t if_loc, brace_loc;
int jumpop_inst, push_true_inst, push_false_inst;
MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_IF); MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_IF || TOKEN_TYPE(moo) == MOO_IOTOK_IFNOT);
if_loc = *TOKEN_LOC(moo); if_loc = *TOKEN_LOC(moo);
init_oow_pool (moo, &jumptoend); init_oow_pool (moo, &jumptoend);
jumptonext = INVALID_IP; jumptonext = INVALID_IP;
endoftrueblock = INVALID_IP; endoftrueblock = INVALID_IP;
if (TOKEN_TYPE(moo) == MOO_IOTOK_IF)
{
push_true_inst = BCODE_PUSH_TRUE;
push_false_inst = BCODE_PUSH_FALSE;
jumpop_inst = BCODE_JUMPOP_FORWARD_IF_FALSE;
}
else
{
push_true_inst = BCODE_PUSH_FALSE;
push_false_inst = BCODE_PUSH_TRUE;
jumpop_inst = BCODE_JUMPOP_FORWARD_IF_TRUE;
}
do do
{ {
int falseblock = 0; int falseblock = 0;
@ -5677,12 +5704,12 @@ static int compile_if_expression (moo_t* moo)
precondpos = moo->c->mth.code.len; precondpos = moo->c->mth.code.len;
if (jumptonext != INVALID_IP && if (jumptonext != INVALID_IP &&
patch_long_forward_jump_instruction (moo, jumptonext, precondpos, &brace_loc) <= -1) goto oops; patch_long_forward_jump_instruction(moo, jumptonext, precondpos, &brace_loc) <= -1) goto oops;
if (compile_conditional(moo) <= -1) goto oops; if (compile_conditional(moo) <= -1) goto oops;
postcondpos = moo->c->mth.code.len; postcondpos = moo->c->mth.code.len;
if (precondpos + 1 == postcondpos && moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_TRUE) if (precondpos + 1 == postcondpos && moo->c->mth.code.ptr[precondpos] == push_true_inst)
{ {
/* do not generate jump */ /* do not generate jump */
jumptonext = INVALID_IP; jumptonext = INVALID_IP;
@ -5692,7 +5719,7 @@ static int compile_if_expression (moo_t* moo)
eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1); eliminate_instructions (moo, precondpos, moo->c->mth.code.len - 1);
postcondpos = precondpos; postcondpos = precondpos;
} }
else if (precondpos + 1 == postcondpos && moo->c->mth.code.ptr[precondpos] == BCODE_PUSH_FALSE) else if (precondpos + 1 == postcondpos && moo->c->mth.code.ptr[precondpos] == push_false_inst)
{ {
jumptonext = INVALID_IP; jumptonext = INVALID_IP;
/* mark that the conditional is false. instructions will get eliminated below */ /* mark that the conditional is false. instructions will get eliminated below */
@ -5704,7 +5731,7 @@ static int compile_if_expression (moo_t* moo)
jumptonext = moo->c->mth.code.len; jumptonext = moo->c->mth.code.len;
/* BCODE_JUMPOP_FORWARD_IF_FALSE is always a long jump instruction. /* BCODE_JUMPOP_FORWARD_IF_FALSE is always a long jump instruction.
* just specify MAX_CODE_JUMP for consistency with short jump variants */ * just specify MAX_CODE_JUMP for consistency with short jump variants */
if (emit_single_param_instruction (moo, BCODE_JUMPOP_FORWARD_IF_FALSE, MAX_CODE_JUMP) <= -1) goto oops; if (emit_single_param_instruction(moo, jumpop_inst, MAX_CODE_JUMP) <= -1) goto oops;
} }
GET_TOKEN (moo); /* get { */ GET_TOKEN (moo); /* get { */
@ -5737,10 +5764,26 @@ static int compile_if_expression (moo_t* moo)
} }
GET_TOKEN (moo); /* get the next token after } */ GET_TOKEN (moo); /* get the next token after } */
} while (TOKEN_TYPE(moo) == MOO_IOTOK_ELSIF);
if (TOKEN_TYPE(moo) != MOO_IOTOK_ELSIF && TOKEN_TYPE(moo) != MOO_IOTOK_ELSIFNOT) break;
if (TOKEN_TYPE(moo) == MOO_IOTOK_ELSIF)
{
push_true_inst = BCODE_PUSH_TRUE;
push_false_inst = BCODE_PUSH_FALSE;
jumpop_inst = BCODE_JUMPOP_FORWARD_IF_FALSE;
}
else
{
push_true_inst = BCODE_PUSH_FALSE;
push_false_inst = BCODE_PUSH_TRUE;
jumpop_inst = BCODE_JUMPOP_FORWARD_IF_TRUE;
}
}
while (1);
if (jumptonext != INVALID_IP && if (jumptonext != INVALID_IP &&
patch_long_forward_jump_instruction (moo, jumptonext, moo->c->mth.code.len, &brace_loc) <= -1) goto oops; patch_long_forward_jump_instruction(moo, jumptonext, moo->c->mth.code.len, &brace_loc) <= -1) goto oops;
if (TOKEN_TYPE(moo) == MOO_IOTOK_ELSE) if (TOKEN_TYPE(moo) == MOO_IOTOK_ELSE)
{ {
@ -6033,7 +6076,7 @@ static int compile_method_expression (moo_t* moo, int pop)
MOO_ASSERT (moo, pop == 0 || pop == 1); MOO_ASSERT (moo, pop == 0 || pop == 1);
MOO_MEMSET (&assignee, 0, MOO_SIZEOF(assignee)); MOO_MEMSET (&assignee, 0, MOO_SIZEOF(assignee));
if (TOKEN_TYPE(moo) == MOO_IOTOK_IF) if (TOKEN_TYPE(moo) == MOO_IOTOK_IF || TOKEN_TYPE(moo) == MOO_IOTOK_IFNOT)
{ {
if (compile_if_expression (moo) <= -1) return -1; if (compile_if_expression (moo) <= -1) return -1;
} }

View File

@ -342,8 +342,10 @@ enum moo_iotok_type_t
MOO_IOTOK_SELFNS, MOO_IOTOK_SELFNS,
MOO_IOTOK_IF, MOO_IOTOK_IF,
MOO_IOTOK_IFNOT,
MOO_IOTOK_ELSE, MOO_IOTOK_ELSE,
MOO_IOTOK_ELSIF, MOO_IOTOK_ELSIF,
MOO_IOTOK_ELSIFNOT,
MOO_IOTOK_WHILE, MOO_IOTOK_WHILE,
MOO_IOTOK_UNTIL, MOO_IOTOK_UNTIL,
@ -852,6 +854,7 @@ enum moo_bcode_t
BCODE_JUMP_BACKWARD_2 = 0x4A, /* 74 */ BCODE_JUMP_BACKWARD_2 = 0x4A, /* 74 */
BCODE_JUMP_BACKWARD_3 = 0x4B, /* 75 */ BCODE_JUMP_BACKWARD_3 = 0x4B, /* 75 */
/* JUMPOP = JUMP + POP */
BCODE_JUMPOP_BACKWARD_IF_FALSE_0 = 0x4C, /* 76 */ BCODE_JUMPOP_BACKWARD_IF_FALSE_0 = 0x4C, /* 76 */
BCODE_JUMPOP_BACKWARD_IF_FALSE_1 = 0x4D, /* 77 */ BCODE_JUMPOP_BACKWARD_IF_FALSE_1 = 0x4D, /* 77 */
BCODE_JUMPOP_BACKWARD_IF_FALSE_2 = 0x4E, /* 78 */ BCODE_JUMPOP_BACKWARD_IF_FALSE_2 = 0x4E, /* 78 */