mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-05 08:10:05 +00:00
fixed multiple assignment
This commit is contained in:
parent
ec3552a155
commit
417a1f15f1
46
src/cparse.c
46
src/cparse.c
@ -465,7 +465,7 @@ static void _etterOP(CParseState *pstate, uint8_t op, int arg) {
|
|||||||
writeu8(pstate, arg);
|
writeu8(pstate, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void namedVariable(CParseState *pstate, CToken name, bool canAssign, bool canIncrement) {
|
static void namedVariable(CParseState *pstate, CToken name, bool canAssign, bool canIncrement, int expectedValues) {
|
||||||
uint8_t opGet, opSet, inc;
|
uint8_t opGet, opSet, inc;
|
||||||
int arg = getLocal(pstate->compiler, &name);
|
int arg = getLocal(pstate->compiler, &name);
|
||||||
|
|
||||||
@ -486,9 +486,35 @@ static void namedVariable(CParseState *pstate, CToken name, bool canAssign, bool
|
|||||||
inc = OP_INCGLOBAL;
|
inc = OP_INCGLOBAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canAssign && match(pstate, TOKEN_EQUAL)) {
|
if (canAssign && match(pstate, TOKEN_COMMA)) {
|
||||||
// setter
|
expectedValues++;
|
||||||
expression(pstate, 1, true);
|
|
||||||
|
consume(pstate, TOKEN_IDENTIFIER, "Expected another identifer!");
|
||||||
|
|
||||||
|
namedVariable(pstate, pstate->previous, true, false, expectedValues);
|
||||||
|
_etterOP(pstate, opSet, arg);
|
||||||
|
valuePopped(pstate, 1);
|
||||||
|
} else if (canAssign && match(pstate, TOKEN_EQUAL)) {
|
||||||
|
expectedValues++;
|
||||||
|
|
||||||
|
// consume all the ','
|
||||||
|
do {
|
||||||
|
int pushed = expression(pstate, expectedValues, false);
|
||||||
|
expectedValues -= pushed;
|
||||||
|
|
||||||
|
if (expectedValues < 0) { // these values need to be thrown away
|
||||||
|
writePop(pstate, -expectedValues);
|
||||||
|
valuePopped(pstate, -expectedValues);
|
||||||
|
expectedValues = 1;
|
||||||
|
}
|
||||||
|
} while (match(pstate, TOKEN_COMMA));
|
||||||
|
|
||||||
|
// for any expected value we didn't get
|
||||||
|
while (expectedValues-- > 0) {
|
||||||
|
valuePushed(pstate, 1);
|
||||||
|
writeu8(pstate, OP_NIL);
|
||||||
|
}
|
||||||
|
|
||||||
_etterOP(pstate, opSet, arg);
|
_etterOP(pstate, opSet, arg);
|
||||||
valuePopped(pstate, 1);
|
valuePopped(pstate, 1);
|
||||||
} else if (canIncrement && match(pstate, TOKEN_PLUS_PLUS)) { // i++
|
} else if (canIncrement && match(pstate, TOKEN_PLUS_PLUS)) { // i++
|
||||||
@ -542,7 +568,7 @@ static void anonFunction(CParseState *pstate, bool canAssign) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void variable(CParseState *pstate, bool canAssign) {
|
static void variable(CParseState *pstate, bool canAssign) {
|
||||||
namedVariable(pstate, pstate->previous, canAssign, true);
|
namedVariable(pstate, pstate->previous, canAssign, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void concat(CParseState *pstate, bool canAssign) {
|
static void concat(CParseState *pstate, bool canAssign) {
|
||||||
@ -713,14 +739,14 @@ static void walkIndexes(CParseState *pstate, int lastIndexType, uint16_t lastIde
|
|||||||
static void increment(CParseState *pstate, int val) {
|
static void increment(CParseState *pstate, int val) {
|
||||||
CToken name = pstate->previous;
|
CToken name = pstate->previous;
|
||||||
if (match(pstate, TOKEN_DOT)) { // object?
|
if (match(pstate, TOKEN_DOT)) { // object?
|
||||||
namedVariable(pstate, name, false, false); // just get the object
|
namedVariable(pstate, name, false, false, 0); // just get the object
|
||||||
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);
|
||||||
|
|
||||||
// walk the indexes
|
// walk the indexes
|
||||||
walkIndexes(pstate, 0, ident, val);
|
walkIndexes(pstate, 0, ident, val);
|
||||||
} else if (match(pstate, TOKEN_LEFT_BRACKET)) { // dictionary?
|
} else if (match(pstate, TOKEN_LEFT_BRACKET)) { // dictionary?
|
||||||
namedVariable(pstate, name, false, false); // just get the dictionary
|
namedVariable(pstate, name, false, false, 0); // just get the dictionary
|
||||||
|
|
||||||
// grab key
|
// grab key
|
||||||
expression(pstate, 1, true);
|
expression(pstate, 1, true);
|
||||||
@ -1398,7 +1424,7 @@ static int expressionPrecedence(CParseState *pstate, int needed, Precedence prec
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int expression(CParseState *pstate, int needed, bool forceNeeded) {
|
static int expression(CParseState *pstate, int needed, bool forceNeeded) {
|
||||||
return expressionPrecedence(pstate, needed, PREC_ASSIGNMENT, forceNeeded);
|
return expressionPrecedence(pstate, needed, PREC_ASSIGNMENT + 1, forceNeeded); // anything above assignments are an expression
|
||||||
}
|
}
|
||||||
|
|
||||||
static void expressionStatement(CParseState *pstate) {
|
static void expressionStatement(CParseState *pstate) {
|
||||||
@ -1433,8 +1459,8 @@ static void expressionStatement(CParseState *pstate) {
|
|||||||
} else if (match(pstate, TOKEN_RETURN)) {
|
} else if (match(pstate, TOKEN_RETURN)) {
|
||||||
returnStatement(pstate);
|
returnStatement(pstate);
|
||||||
} else {
|
} else {
|
||||||
// we don't need/want any values on the stack, so call expression with 0 values needed
|
// expression or assignment
|
||||||
expression(pstate, 0, false);
|
expressionPrecedence(pstate, 0, PREC_ASSIGNMENT, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// realign the stack
|
// realign the stack
|
||||||
|
Loading…
Reference in New Issue
Block a user