added two new keywords (and, or) for logical operations. work in progress
This commit is contained in:
parent
380395c910
commit
8965720926
@ -314,7 +314,7 @@ class OrderedCollection(SequenceableCollection)
|
|||||||
method initWithCapacity: capacity
|
method initWithCapacity: capacity
|
||||||
{
|
{
|
||||||
self.buffer := Array new: capacity.
|
self.buffer := Array new: capacity.
|
||||||
self.firstIndex := capacity div: 2.
|
self.firstIndex := capacity bitShift: -1.
|
||||||
self.lastIndex := self.firstIndex.
|
self.lastIndex := self.firstIndex.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +359,7 @@ class OrderedCollection(SequenceableCollection)
|
|||||||
|
|
||||||
method addFirst: obj
|
method addFirst: obj
|
||||||
{
|
{
|
||||||
if (self.firstIndex == 0) { self growBy: 8 shiftBy: 8 }.
|
if (self.firstIndex == 0) { self __grow_and_shift(8, 8) }.
|
||||||
self.firstIndex := self.firstIndex - 1.
|
self.firstIndex := self.firstIndex - 1.
|
||||||
self.buffer at: self.firstIndex put: obj.
|
self.buffer at: self.firstIndex put: obj.
|
||||||
^obj.
|
^obj.
|
||||||
@ -367,7 +367,7 @@ class OrderedCollection(SequenceableCollection)
|
|||||||
|
|
||||||
method addLast: obj
|
method addLast: obj
|
||||||
{
|
{
|
||||||
if (self.lastIndex == self.buffer size) { self growBy: 8 shiftBy: 0 }.
|
if (self.lastIndex == self.buffer size) { self __grow_and_shift(8, 0) }.
|
||||||
self.buffer at: self.lastIndex put: obj.
|
self.buffer at: self.lastIndex put: obj.
|
||||||
self.lastIndex := self.lastIndex + 1.
|
self.lastIndex := self.lastIndex + 1.
|
||||||
^obj.
|
^obj.
|
||||||
@ -377,7 +377,7 @@ class OrderedCollection(SequenceableCollection)
|
|||||||
{
|
{
|
||||||
| coll_to_add |
|
| coll_to_add |
|
||||||
coll_to_add := if (self == coll) { coll shallowCopy } else { coll }.
|
coll_to_add := if (self == coll) { coll shallowCopy } else { coll }.
|
||||||
self ensureHeadRoom: (coll_to_add size).
|
self __ensure_head_room(coll_to_add size).
|
||||||
coll_to_add reverseDo: [:obj |
|
coll_to_add reverseDo: [:obj |
|
||||||
self.firstIndex := self.firstIndex - 1.
|
self.firstIndex := self.firstIndex - 1.
|
||||||
self.buffer at: self.firstIndex put: obj.
|
self.buffer at: self.firstIndex put: obj.
|
||||||
@ -389,7 +389,7 @@ class OrderedCollection(SequenceableCollection)
|
|||||||
{
|
{
|
||||||
| coll_to_add |
|
| coll_to_add |
|
||||||
coll_to_add := if (self == coll) { coll shallowCopy } else { coll }.
|
coll_to_add := if (self == coll) { coll shallowCopy } else { coll }.
|
||||||
self ensureTailRoom: (coll_to_add size).
|
self __ensure_tail_room(coll_to_add size).
|
||||||
coll_to_add do: [:obj |
|
coll_to_add do: [:obj |
|
||||||
self.buffer at: self.lastIndex put: obj.
|
self.buffer at: self.lastIndex put: obj.
|
||||||
self.lastIndex := self.lastIndex + 1.
|
self.lastIndex := self.lastIndex + 1.
|
||||||
@ -399,8 +399,14 @@ class OrderedCollection(SequenceableCollection)
|
|||||||
|
|
||||||
method add: obj beforeIndex: index
|
method add: obj beforeIndex: index
|
||||||
{
|
{
|
||||||
self insert: obj beforeIndex: index.
|
self __insert_before_index(obj, index).
|
||||||
^obj
|
^obj.
|
||||||
|
}
|
||||||
|
|
||||||
|
method add: obj afterIndex: index
|
||||||
|
{
|
||||||
|
self __insert_before_index(obj, index + 1).
|
||||||
|
^obj.
|
||||||
}
|
}
|
||||||
|
|
||||||
method removeFirst
|
method removeFirst
|
||||||
@ -462,7 +468,7 @@ class OrderedCollection(SequenceableCollection)
|
|||||||
## remove the element at the given position.
|
## remove the element at the given position.
|
||||||
| obj |
|
| obj |
|
||||||
obj := self at: index. ## the range is checed by the at: method.
|
obj := self at: index. ## the range is checed by the at: method.
|
||||||
self removeIndex: index + self.firstIndex.
|
self __remove_Index(index + self.firstIndex).
|
||||||
^obj
|
^obj
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,7 +483,7 @@ class OrderedCollection(SequenceableCollection)
|
|||||||
while (i < self.lastIndex)
|
while (i < self.lastIndex)
|
||||||
{
|
{
|
||||||
cand := self.buffer at: i.
|
cand := self.buffer at: i.
|
||||||
if (obj = cand) { self removeIndex: i. ^cand }.
|
if (obj = cand) { self __remove_index(i). ^cand }.
|
||||||
i := i + 1.
|
i := i + 1.
|
||||||
}.
|
}.
|
||||||
^error_block value.
|
^error_block value.
|
||||||
@ -525,7 +531,7 @@ class OrderedCollection(SequenceableCollection)
|
|||||||
## ------------------------------------------------
|
## ------------------------------------------------
|
||||||
## PRIVATE METHODS
|
## PRIVATE METHODS
|
||||||
## ------------------------------------------------
|
## ------------------------------------------------
|
||||||
method growBy: grow_size shiftBy: shift_count
|
method __grow_and_shift(grow_size, shift_count)
|
||||||
{
|
{
|
||||||
| newcon |
|
| newcon |
|
||||||
newcon := (self.buffer class) new: (self.buffer size + grow_size).
|
newcon := (self.buffer class) new: (self.buffer size + grow_size).
|
||||||
@ -537,46 +543,71 @@ class OrderedCollection(SequenceableCollection)
|
|||||||
self.lastIndex := self.lastIndex + shift_count.
|
self.lastIndex := self.lastIndex + shift_count.
|
||||||
}
|
}
|
||||||
|
|
||||||
method ensureHeadRoom: size
|
method __ensure_head_room(size)
|
||||||
{
|
{
|
||||||
| grow_size |
|
| grow_size |
|
||||||
if (self.firstIndex < size)
|
if (self.firstIndex < size)
|
||||||
{
|
{
|
||||||
grow_size := size - self.firstIndex + 8.
|
grow_size := size - self.firstIndex + 8.
|
||||||
self growBy: grow_size shiftBy: grow_size.
|
self __grow_and_shift(grow_size, grow_size).
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
method ensureTailRoom: size
|
method __ensure_tail_room(size)
|
||||||
{
|
{
|
||||||
| tmp |
|
| tmp |
|
||||||
tmp := (self.buffer size) - self.lastIndex. ## remaining capacity
|
tmp := (self.buffer size) - self.lastIndex. ## remaining capacity
|
||||||
if (tmp < size)
|
if (tmp < size)
|
||||||
{
|
{
|
||||||
tmp := size - tmp + 8. ## grow by this
|
tmp := size - tmp + 8. ## grow by this amount
|
||||||
self growBy: tmp shiftBy: 0.
|
self __grow_and_shift(tmp, 0).
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
method insert: obj beforeIndex: index
|
method __insert_before_index(obj, index)
|
||||||
{
|
{
|
||||||
## internal use only - index must be between 0 and self size inclusive
|
| i start pos cursize reqsize |
|
||||||
|
|
||||||
| i start |
|
if (index <= 0)
|
||||||
if (self size == self.buffer size) { self growBy: 8 shiftBy: 8 }.
|
|
||||||
start := self.firstIndex + index.
|
|
||||||
i := self.lastIndex.
|
|
||||||
while (i > start)
|
|
||||||
{
|
{
|
||||||
self.buffer at: i put: (self.buffer at: i - 1).
|
## treat a negative index as the indicator to
|
||||||
i := i - 1.
|
## grow space in the front side.
|
||||||
|
reqsize := index * -1 + 1.
|
||||||
|
if (reqsize >= self.firstIndex) { self __ensure_head_room(reqsize) }.
|
||||||
|
self.firstIndex := self.firstIndex + index - 1.
|
||||||
|
self.buffer at: self.firstIndex put: obj.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cursize := self size.
|
||||||
|
if (self.firstIndex > 0 and: [index <= (cursize bitShift: -1)])
|
||||||
|
{
|
||||||
|
start := self.firstIndex - 1.
|
||||||
|
self.buffer replaceFrom: start to: (start + index - 1) with: self.buffer startingAt: self.firstIndex.
|
||||||
|
self.buffer at: (start + index) put: obj.
|
||||||
|
self.firstIndex := start.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
reqsize := if (index > cursize) { index - cursize } else { 1 }.
|
||||||
|
if (reqsize < 8) { reqsize := 8 }.
|
||||||
|
self __grow_and_shift(reqsize + 8, 0).
|
||||||
|
|
||||||
|
start := self.firstIndex + index.
|
||||||
|
i := self.lastIndex.
|
||||||
|
while (i > start)
|
||||||
|
{
|
||||||
|
self.buffer at: i put: (self.buffer at: i - 1).
|
||||||
|
i := i - 1.
|
||||||
|
}.
|
||||||
|
pos := index + self.firstIndex.
|
||||||
|
self.lastIndex := if (pos > self.lastIndex) { pos + 1 } else { self.lastIndex + 1 }.
|
||||||
|
self.buffer at: pos put: obj.
|
||||||
|
}.
|
||||||
}.
|
}.
|
||||||
self.lastIndex := self.lastIndex + 1.
|
|
||||||
self.buffer at: index + self.firstIndex put: obj.
|
|
||||||
^obj
|
|
||||||
}
|
}
|
||||||
|
|
||||||
method removeIndex: index
|
method __remove_index(index)
|
||||||
{
|
{
|
||||||
## remove an element at the given index from the internal buffer's
|
## remove an element at the given index from the internal buffer's
|
||||||
## angle. as it is for internal use only, no check is performed
|
## angle. as it is for internal use only, no check is performed
|
||||||
|
@ -105,6 +105,7 @@ static struct voca_t
|
|||||||
moo_oow_t len;
|
moo_oow_t len;
|
||||||
moo_ooch_t str[11];
|
moo_ooch_t str[11];
|
||||||
} vocas[] = {
|
} vocas[] = {
|
||||||
|
{ 3, { 'a','n','d' } },
|
||||||
{ 5, { 'b','r','e','a','k' } },
|
{ 5, { 'b','r','e','a','k' } },
|
||||||
{ 5, { '#','b','y','t','e' } },
|
{ 5, { '#','b','y','t','e' } },
|
||||||
{ 10, { '#','c','h','a','r','a','c','t','e','r' } },
|
{ 10, { '#','c','h','a','r','a','c','t','e','r' } },
|
||||||
@ -137,6 +138,7 @@ static struct voca_t
|
|||||||
{ 3, { 'n','i','l' } },
|
{ 3, { 'n','i','l' } },
|
||||||
{ 3, { 'o','f','f' } },
|
{ 3, { 'o','f','f' } },
|
||||||
{ 2, { 'o','n' } },
|
{ 2, { 'o','n' } },
|
||||||
|
{ 2, { 'o','r' } },
|
||||||
{ 8, { '#','p','o','i','n','t','e','r' } },
|
{ 8, { '#','p','o','i','n','t','e','r' } },
|
||||||
{ 7, { 'p','o','o','l','d','i','c' } },
|
{ 7, { 'p','o','o','l','d','i','c' } },
|
||||||
{ 8, { '#','p','o','o','l','d','i','c' } },
|
{ 8, { '#','p','o','o','l','d','i','c' } },
|
||||||
@ -169,6 +171,7 @@ static struct voca_t
|
|||||||
|
|
||||||
enum voca_id_t
|
enum voca_id_t
|
||||||
{
|
{
|
||||||
|
VOCA_AND,
|
||||||
VOCA_BREAK,
|
VOCA_BREAK,
|
||||||
VOCA_BYTE_S,
|
VOCA_BYTE_S,
|
||||||
VOCA_CHARACTER_S,
|
VOCA_CHARACTER_S,
|
||||||
@ -201,6 +204,7 @@ enum voca_id_t
|
|||||||
VOCA_NIL,
|
VOCA_NIL,
|
||||||
VOCA_OFF,
|
VOCA_OFF,
|
||||||
VOCA_ON,
|
VOCA_ON,
|
||||||
|
VOCA_OR,
|
||||||
VOCA_POINTER_S,
|
VOCA_POINTER_S,
|
||||||
VOCA_POOLDIC,
|
VOCA_POOLDIC,
|
||||||
VOCA_POOLDIC_S,
|
VOCA_POOLDIC_S,
|
||||||
@ -1228,6 +1232,14 @@ static int get_ident (moo_t* moo, moo_ooci_t char_read_ahead)
|
|||||||
{
|
{
|
||||||
SET_TOKEN_TYPE (moo, MOO_IOTOK_CONTINUE);
|
SET_TOKEN_TYPE (moo, MOO_IOTOK_CONTINUE);
|
||||||
}
|
}
|
||||||
|
else if (is_token_word(moo, VOCA_AND))
|
||||||
|
{
|
||||||
|
SET_TOKEN_TYPE (moo, MOO_IOTOK_AND);
|
||||||
|
}
|
||||||
|
else if (is_token_word(moo, VOCA_OR))
|
||||||
|
{
|
||||||
|
SET_TOKEN_TYPE (moo, MOO_IOTOK_OR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2621,7 +2633,6 @@ static void eliminate_instructions (moo_t* moo, moo_oow_t start, moo_oow_t end)
|
|||||||
|
|
||||||
last = moo->c->mth.code.len - 1;
|
last = moo->c->mth.code.len - 1;
|
||||||
|
|
||||||
|
|
||||||
if (end >= last)
|
if (end >= last)
|
||||||
{
|
{
|
||||||
/* eliminate all instructions starting from the start index.
|
/* eliminate all instructions starting from the start index.
|
||||||
@ -5494,9 +5505,17 @@ static int compile_basic_expression (moo_t* moo, const moo_oocs_t* ident, const
|
|||||||
/*
|
/*
|
||||||
* basic-expression := expression-primary message-expression?
|
* basic-expression := expression-primary message-expression?
|
||||||
*/
|
*/
|
||||||
|
moo_oow_pool_t jumptoend;
|
||||||
|
moo_oow_pool_chunk_t* jumptoend_chunk;
|
||||||
|
moo_ioloc_t expr_loc;
|
||||||
|
moo_oow_t i, j;
|
||||||
int to_super;
|
int to_super;
|
||||||
|
|
||||||
if (compile_expression_primary(moo, ident, ident_loc, ident_dotted, &to_super) <= -1) return -1;
|
expr_loc = *TOKEN_LOC(moo);
|
||||||
|
init_oow_pool (moo, &jumptoend);
|
||||||
|
|
||||||
|
start_over:
|
||||||
|
if (compile_expression_primary(moo, ident, ident_loc, ident_dotted, &to_super) <= -1) goto oops;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (TOKEN_TYPE(moo) != MOO_IOTOK_EOF &&
|
if (TOKEN_TYPE(moo) != MOO_IOTOK_EOF &&
|
||||||
@ -5504,18 +5523,54 @@ static int compile_basic_expression (moo_t* moo, const moo_oocs_t* ident, const
|
|||||||
TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD &&
|
TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD &&
|
||||||
TOKEN_TYPE(moo) != MOO_IOTOK_SEMICOLON)
|
TOKEN_TYPE(moo) != MOO_IOTOK_SEMICOLON)
|
||||||
{
|
{
|
||||||
if (compile_message_expression(moo, to_super) <= -1) return -1;
|
if (compile_message_expression(moo, to_super) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT ||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT ||
|
||||||
TOKEN_TYPE(moo) == MOO_IOTOK_BINSEL ||
|
TOKEN_TYPE(moo) == MOO_IOTOK_BINSEL ||
|
||||||
TOKEN_TYPE(moo) == MOO_IOTOK_KEYWORD)
|
TOKEN_TYPE(moo) == MOO_IOTOK_KEYWORD)
|
||||||
{
|
{
|
||||||
if (compile_message_expression(moo, to_super) <= -1) return -1;
|
if (compile_message_expression(moo, to_super) <= -1) goto oops;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
if (TOKEN_TYPE(moo) == MOO_IOTOK_AND)
|
||||||
|
{
|
||||||
|
if (add_to_oow_pool(moo, &jumptoend, moo->c->mth.code.len) <= -1 ||
|
||||||
|
emit_single_param_instruction(moo, BCODE_JUMP_FORWARD_IF_FALSE, MAX_CODE_JUMP) <= -1 ||
|
||||||
|
emit_byte_instruction(moo, BCODE_POP_STACKTOP) <= -1) goto oops;
|
||||||
|
GET_TOKEN (moo);
|
||||||
|
goto start_over;
|
||||||
|
}
|
||||||
|
else if (TOKEN_TYPE(moo) == MOO_IOTOK_OR)
|
||||||
|
{
|
||||||
|
if (add_to_oow_pool(moo, &jumptoend, moo->c->mth.code.len) <= -1 ||
|
||||||
|
emit_single_param_instruction(moo, BCODE_JUMP_FORWARD_IF_TRUE, MAX_CODE_JUMP) <= -1 ||
|
||||||
|
emit_byte_instruction(moo, BCODE_POP_STACKTOP) <= -1) goto oops;
|
||||||
|
GET_TOKEN (moo);
|
||||||
|
goto start_over;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* patch instructions that jumps to the end of if expression */
|
||||||
|
for (jumptoend_chunk = jumptoend.head, i = 0; jumptoend_chunk; jumptoend_chunk = jumptoend_chunk->next)
|
||||||
|
{
|
||||||
|
/* pass expr_loc to every call to patch_long_forward_jump_instruction().
|
||||||
|
* it's harmless because if the first call doesn't flood, the subseqent
|
||||||
|
* call will never flood either. */
|
||||||
|
for (j = 0; j < MOO_COUNTOF(jumptoend.static_chunk.buf) && i < jumptoend.count; j++)
|
||||||
|
{
|
||||||
|
if (patch_long_forward_jump_instruction (moo, jumptoend_chunk->buf[j], moo->c->mth.code.len, &expr_loc) <= -1) goto oops;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fini_oow_pool (moo, &jumptoend);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
fini_oow_pool (moo, &jumptoend);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compile_braced_block (moo_t* moo)
|
static int compile_braced_block (moo_t* moo)
|
||||||
|
@ -3630,7 +3630,7 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
|||||||
|
|
||||||
#if defined(MOO_DEBUG_VM_EXEC)
|
#if defined(MOO_DEBUG_VM_EXEC)
|
||||||
/* set it to a fake value */
|
/* set it to a fake value */
|
||||||
moo->last_instruction_pointer = 0;
|
moo->last_inst_pointer = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
preamble = MOO_OOP_TO_SMOOI(method->preamble);
|
preamble = MOO_OOP_TO_SMOOI(method->preamble);
|
||||||
@ -3765,7 +3765,7 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
|
|||||||
stack_base = moo->sp - nargs - 1; /* stack base before receiver and arguments */
|
stack_base = moo->sp - nargs - 1; /* stack base before receiver and arguments */
|
||||||
|
|
||||||
pfnum = MOO_METHOD_GET_PREAMBLE_INDEX(preamble);
|
pfnum = MOO_METHOD_GET_PREAMBLE_INDEX(preamble);
|
||||||
LOG_INST1 (moo, "preamble_primitive %zd", pf_no);
|
LOG_INST1 (moo, "preamble_primitive %zd", pfnum);
|
||||||
|
|
||||||
if (pfnum >= 0 && pfnum < MOO_COUNTOF(pftab))
|
if (pfnum >= 0 && pfnum < MOO_COUNTOF(pftab))
|
||||||
{
|
{
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
/*#define MOO_DEBUG_LEXER 1*/
|
/*#define MOO_DEBUG_LEXER 1*/
|
||||||
#define MOO_DEBUG_COMPILER 1
|
#define MOO_DEBUG_COMPILER 1
|
||||||
#define MOO_DEBUG_VM_PROCESSOR 1
|
#define MOO_DEBUG_VM_PROCESSOR 1
|
||||||
/*#define MOO_DEBUG_VM_EXEC*/
|
#define MOO_DEBUG_VM_EXEC
|
||||||
#define MOO_PROFILE_VM 1
|
#define MOO_PROFILE_VM 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -353,6 +353,9 @@ enum moo_iotok_type_t
|
|||||||
MOO_IOTOK_BREAK,
|
MOO_IOTOK_BREAK,
|
||||||
MOO_IOTOK_CONTINUE,
|
MOO_IOTOK_CONTINUE,
|
||||||
|
|
||||||
|
MOO_IOTOK_AND,
|
||||||
|
MOO_IOTOK_OR,
|
||||||
|
|
||||||
MOO_IOTOK_IDENT,
|
MOO_IOTOK_IDENT,
|
||||||
MOO_IOTOK_IDENT_DOTTED,
|
MOO_IOTOK_IDENT_DOTTED,
|
||||||
MOO_IOTOK_BINSEL,
|
MOO_IOTOK_BINSEL,
|
||||||
|
Loading…
Reference in New Issue
Block a user