mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-05 08:10:05 +00:00
better unary increment support for indexes & fields
This commit is contained in:
parent
be7a291ff2
commit
c96b155412
78
src/cparse.c
78
src/cparse.c
@ -646,7 +646,62 @@ static void _index(CParseState *pstate, bool canAssign) {
|
|||||||
writeu8(pstate, OP_INDEX);
|
writeu8(pstate, OP_INDEX);
|
||||||
}
|
}
|
||||||
|
|
||||||
valuePopped(pstate, 1); // pops key & object but also pushes the field so total popped is 1
|
valuePopped(pstate, 1); // pops key & object but also pushes the value so total popped is 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// ++test.field[1]
|
||||||
|
static void walkIndexes(CParseState *pstate, int lastIndexType, uint16_t lastIdent, int val) {
|
||||||
|
uint16_t ident = lastIdent;
|
||||||
|
int indexType = lastIndexType;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (match(pstate, TOKEN_DOT)) {
|
||||||
|
consume(pstate, TOKEN_IDENTIFIER, "Expected property name after '.'.");
|
||||||
|
ident = identifierConstant(pstate, &pstate->previous);
|
||||||
|
indexType = 0;
|
||||||
|
} else if (match(pstate, TOKEN_LEFT_BRACKET)) {
|
||||||
|
indexType = 1;
|
||||||
|
} else // end of indexes, break out of the loop
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (lastIndexType) {
|
||||||
|
case 0: // .
|
||||||
|
writeu8(pstate, OP_LOADCONST); // pushes ident to stack
|
||||||
|
writeu16(pstate, lastIdent);
|
||||||
|
writeu8(pstate, OP_GETOBJECT); // grabs property
|
||||||
|
break;
|
||||||
|
case 1: // []
|
||||||
|
writeu8(pstate, OP_INDEX); // so, that was a normal index, perform that
|
||||||
|
valuePopped(pstate, 1); // pops the key & dict off the stack, but pushes the value
|
||||||
|
break;
|
||||||
|
default: // no previous index
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexType == 1) { // currently parsed token was a TOKEN_LEFT_BRACKET, meaning an index
|
||||||
|
expression(pstate, 1, true); // grabs key
|
||||||
|
consume(pstate, TOKEN_RIGHT_BRACKET, "Expected ']' to end index.");
|
||||||
|
}
|
||||||
|
|
||||||
|
lastIndexType = indexType;
|
||||||
|
lastIdent = ident;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (indexType) {
|
||||||
|
case 0: // .
|
||||||
|
writeu8(pstate, OP_INCOBJECT);
|
||||||
|
writeu8(pstate, 128 + val); // setting signed values in an unsigned int
|
||||||
|
writeu16(pstate, ident);
|
||||||
|
valuePopped(pstate, 1); // popped the object off the stack
|
||||||
|
break;
|
||||||
|
case 1: // []
|
||||||
|
writeu8(pstate, OP_INCINDEX);
|
||||||
|
writeu8(pstate, 128 + val);
|
||||||
|
valuePopped(pstate, 2); // popped the dictionary & the key off the stack, but pushes the previous value
|
||||||
|
break;
|
||||||
|
default: // no previous index
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void increment(CParseState *pstate, int val) {
|
static void increment(CParseState *pstate, int val) {
|
||||||
@ -656,20 +711,17 @@ static void increment(CParseState *pstate, int val) {
|
|||||||
consume(pstate, TOKEN_IDENTIFIER, "Expected property name after '.'.");
|
consume(pstate, TOKEN_IDENTIFIER, "Expected property name after '.'.");
|
||||||
uint16_t ident = identifierConstant(pstate, &pstate->previous);
|
uint16_t ident = identifierConstant(pstate, &pstate->previous);
|
||||||
|
|
||||||
while (match(pstate, TOKEN_DOT)) {
|
// walk the indexes
|
||||||
// grab the field from the object
|
walkIndexes(pstate, 0, ident, val);
|
||||||
writeu8(pstate, OP_LOADCONST); // pushes ident to stack
|
} else if (match(pstate, TOKEN_LEFT_BRACKET)) { // dictionary?
|
||||||
writeu16(pstate, ident);
|
namedVariable(pstate, name, false, false); // just get the dictionary
|
||||||
writeu8(pstate, OP_GETOBJECT);
|
|
||||||
|
|
||||||
consume(pstate, TOKEN_IDENTIFIER, "Expected property name after '.'.");
|
// grab key
|
||||||
ident = identifierConstant(pstate, &pstate->previous);
|
expression(pstate, 1, true);
|
||||||
}
|
consume(pstate, TOKEN_RIGHT_BRACKET, "Expected ']' to end index.");
|
||||||
|
|
||||||
writeu8(pstate, OP_INCOBJECT);
|
// walk the indexes
|
||||||
writeu8(pstate, 128 + val); // setting signed values in an unsigned int
|
walkIndexes(pstate, 1, 0, val);
|
||||||
writeu16(pstate, ident);
|
|
||||||
valuePopped(pstate, 1); // popped the object off the stack
|
|
||||||
} else {
|
} else {
|
||||||
uint8_t op;
|
uint8_t op;
|
||||||
int arg = getLocal(pstate->compiler, &name);
|
int arg = getLocal(pstate->compiler, &name);
|
||||||
|
Loading…
Reference in New Issue
Block a user