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
{
self do: [ :el | if (block value: el) { ^el } ].
^Error.Code.ENOENT
self detect: block ifNone: [ ^self error: 'not found' ].
}
method detect: block ifNone: exception_block
@ -43,6 +42,15 @@ class Collection(Object)
{
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
{
@ -56,11 +64,9 @@ class Collection(Object)
{
| coll |
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
}
*)
method emptyCheck
{

View File

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

View File

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

View File

@ -117,6 +117,7 @@ static struct voca_t
{ 5, { '#','d','u','a','l' } },
{ 4, { 'e','l','s','e' } },
{ 5, { 'e','l','s','i','f' } },
{ 8, { 'e','l','s','i','f','n','o','t' } },
{ 6, { 'e','n','s','u','r','e', } },
{ 9, { 'e','x','c','e','p','t','i','o','n' } },
{ 6, { 'e','x','t','e','n','d' } },
@ -126,6 +127,7 @@ static struct voca_t
{ 4, { '#','g','e','t' } },
{ 9, { '#','h','a','l','f','w','o','r','d' } },
{ 2, { 'i','f' } },
{ 5, { 'i','f','n','o','t' } },
{ 10, { '#','i','m','m','u','t','a','b','l','e' } },
{ 6, { 'i','m','p','o','r','t' } },
{ 8, { '#','i','n','c','l','u','d','e' } },
@ -183,6 +185,7 @@ enum voca_id_t
VOCA_DUAL_S,
VOCA_ELSE,
VOCA_ELSIF,
VOCA_ELSIFNOT,
VOCA_ENSURE,
VOCA_EXCEPTION,
VOCA_EXTEND,
@ -192,6 +195,7 @@ enum voca_id_t
VOCA_GET_S,
VOCA_HALFWORD_S,
VOCA_IF,
VOCA_IFNOT,
VOCA_IMMUTABLE_S,
VOCA_IMPORT,
VOCA_INCLUDE_S,
@ -372,6 +376,7 @@ static int is_reserved_word (const moo_oocs_t* ucs)
VOCA_IF,
VOCA_ELSE,
VOCA_ELSIF,
VOCA_ELSIFNOT,
VOCA_WHILE,
VOCA_UNTIL,
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);
}
else if (is_token_word(moo, VOCA_IFNOT))
{
SET_TOKEN_TYPE (moo, MOO_IOTOK_IFNOT);
}
else if (is_token_word(moo, VOCA_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);
}
else if (is_token_word(moo, VOCA_ELSIFNOT))
{
SET_TOKEN_TYPE (moo, MOO_IOTOK_ELSIFNOT);
}
else if (is_token_word(moo, VOCA_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 jumptonext, precondpos, postcondpos, endoftrueblock;
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);
init_oow_pool (moo, &jumptoend);
jumptonext = 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
{
int falseblock = 0;
@ -5682,7 +5709,7 @@ static int compile_if_expression (moo_t* moo)
if (compile_conditional(moo) <= -1) goto oops;
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 */
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);
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;
/* 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;
/* BCODE_JUMPOP_FORWARD_IF_FALSE is always a long jump instruction.
* 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 { */
@ -5737,7 +5764,23 @@ static int compile_if_expression (moo_t* moo)
}
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 &&
patch_long_forward_jump_instruction(moo, jumptonext, moo->c->mth.code.len, &brace_loc) <= -1) goto oops;
@ -6033,7 +6076,7 @@ static int compile_method_expression (moo_t* moo, int pop)
MOO_ASSERT (moo, pop == 0 || pop == 1);
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;
}

View File

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