mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-05 08:10:05 +00:00
added multiple return value support to the parser
This commit is contained in:
parent
48ceca1834
commit
4f3f594b82
@ -175,7 +175,7 @@ int disasmInstr(CChunk *chunk, int offset, int indent) {
|
|||||||
case OP_INCOBJECT:
|
case OP_INCOBJECT:
|
||||||
return u8u16OperandInstruction("OP_INCOBJECT", chunk, offset);
|
return u8u16OperandInstruction("OP_INCOBJECT", chunk, offset);
|
||||||
case OP_RETURN:
|
case OP_RETURN:
|
||||||
return simpleInstruction("OP_RETURN", offset);
|
return u8OperandInstruction("OP_RETURN", chunk, offset);
|
||||||
default:
|
default:
|
||||||
printf("Unknown opcode! [%d]\n", i);
|
printf("Unknown opcode! [%d]\n", i);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
102
src/cparse.c
102
src/cparse.c
@ -36,6 +36,7 @@ typedef struct CCompilerState {
|
|||||||
int scopeDepth;
|
int scopeDepth;
|
||||||
int pushedValues;
|
int pushedValues;
|
||||||
int savedPushed;
|
int savedPushed;
|
||||||
|
int expectedValues;
|
||||||
struct CCompilerState* enclosing;
|
struct CCompilerState* enclosing;
|
||||||
} CCompilerState;
|
} CCompilerState;
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ typedef struct {
|
|||||||
|
|
||||||
static void parsePrecedence(CParseState*, Precedence);
|
static void parsePrecedence(CParseState*, Precedence);
|
||||||
static void variable(CParseState *pstate, bool canAssign);
|
static void variable(CParseState *pstate, bool canAssign);
|
||||||
static void expression(CParseState*);
|
static int expression(CParseState *pstate, int needed, bool forceNeeded);
|
||||||
static void statement(CParseState *pstate);
|
static void statement(CParseState *pstate);
|
||||||
static void declaration(CParseState *pstate);
|
static void declaration(CParseState *pstate);
|
||||||
static void function(CParseState *pstate, FunctionType type);
|
static void function(CParseState *pstate, FunctionType type);
|
||||||
@ -94,6 +95,7 @@ static void initCompilerState(CParseState* pstate, CCompilerState *ccstate, Func
|
|||||||
ccstate->scopeDepth = 0;
|
ccstate->scopeDepth = 0;
|
||||||
ccstate->pushedValues = 0;
|
ccstate->pushedValues = 0;
|
||||||
ccstate->savedPushed = 0;
|
ccstate->savedPushed = 0;
|
||||||
|
ccstate->expectedValues = 0;
|
||||||
ccstate->type = type;
|
ccstate->type = type;
|
||||||
ccstate->function = cosmoO_newFunction(pstate->state);
|
ccstate->function = cosmoO_newFunction(pstate->state);
|
||||||
ccstate->function->module = pstate->module;
|
ccstate->function->module = pstate->module;
|
||||||
@ -340,7 +342,7 @@ static int parseArguments(CParseState *pstate) {
|
|||||||
// there are args to parse!
|
// there are args to parse!
|
||||||
if (!check(pstate, TOKEN_RIGHT_PAREN)) {
|
if (!check(pstate, TOKEN_RIGHT_PAREN)) {
|
||||||
do {
|
do {
|
||||||
expression(pstate);
|
expression(pstate, 1, true);
|
||||||
args++;
|
args++;
|
||||||
} while(match(pstate, TOKEN_COMMA));
|
} while(match(pstate, TOKEN_COMMA));
|
||||||
}
|
}
|
||||||
@ -434,7 +436,7 @@ static void binary(CParseState *pstate, bool canAssign) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void group(CParseState *pstate, bool canAssign) {
|
static void group(CParseState *pstate, bool canAssign) {
|
||||||
expression(pstate);
|
expression(pstate, 1, true);
|
||||||
consume(pstate, TOKEN_RIGHT_PAREN, "Expected ')'");
|
consume(pstate, TOKEN_RIGHT_PAREN, "Expected ')'");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,7 +471,7 @@ static void namedVariable(CParseState *pstate, CToken name, bool canAssign, bool
|
|||||||
|
|
||||||
if (canAssign && match(pstate, TOKEN_EQUAL)) {
|
if (canAssign && match(pstate, TOKEN_EQUAL)) {
|
||||||
// setter
|
// setter
|
||||||
expression(pstate);
|
expression(pstate, 1, true);
|
||||||
_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++
|
||||||
@ -549,8 +551,8 @@ static void call_(CParseState *pstate, bool canAssign) {
|
|||||||
valuePopped(pstate, argCount + 1); // all of these values will be popped off the stack when returned (+1 for the function)
|
valuePopped(pstate, argCount + 1); // all of these values will be popped off the stack when returned (+1 for the function)
|
||||||
writeu8(pstate, OP_CALL);
|
writeu8(pstate, OP_CALL);
|
||||||
writeu8(pstate, argCount);
|
writeu8(pstate, argCount);
|
||||||
writeu8(pstate, 1); // TODO
|
writeu8(pstate, pstate->compiler->expectedValues); // TODO
|
||||||
valuePushed(pstate, 1);
|
valuePushed(pstate, pstate->compiler->expectedValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void object(CParseState *pstate, bool canAssign) {
|
static void object(CParseState *pstate, bool canAssign) {
|
||||||
@ -560,12 +562,12 @@ static void object(CParseState *pstate, bool canAssign) {
|
|||||||
if (!match(pstate, TOKEN_RIGHT_BRACE)) {
|
if (!match(pstate, TOKEN_RIGHT_BRACE)) {
|
||||||
do {
|
do {
|
||||||
// parse the key first
|
// parse the key first
|
||||||
expression(pstate); // should parse until ':'
|
expression(pstate, 1, true); // should parse until ':'
|
||||||
|
|
||||||
consume(pstate, TOKEN_COLON, "Expected ':' to mark end of key and start of value!");
|
consume(pstate, TOKEN_COLON, "Expected ':' to mark end of key and start of value!");
|
||||||
|
|
||||||
// now, parse the value (until comma)
|
// now, parse the value (until comma)
|
||||||
expression(pstate);
|
expression(pstate, 1, true);
|
||||||
|
|
||||||
// "pop" the 2 values
|
// "pop" the 2 values
|
||||||
valuePopped(pstate, 2);
|
valuePopped(pstate, 2);
|
||||||
@ -587,7 +589,7 @@ static void dot(CParseState *pstate, bool canAssign) {
|
|||||||
if (canAssign && match(pstate, TOKEN_EQUAL)) {
|
if (canAssign && match(pstate, TOKEN_EQUAL)) {
|
||||||
writeu8(pstate, OP_LOADCONST);
|
writeu8(pstate, OP_LOADCONST);
|
||||||
writeu16(pstate, name);
|
writeu16(pstate, name);
|
||||||
expression(pstate);
|
expression(pstate, 1, true);
|
||||||
writeu8(pstate, OP_SETOBJECT);
|
writeu8(pstate, OP_SETOBJECT);
|
||||||
valuePopped(pstate, 2); // pops key, value & object
|
valuePopped(pstate, 2); // pops key, value & object
|
||||||
} else if (match(pstate, TOKEN_PLUS_PLUS)) { // increment the field
|
} else if (match(pstate, TOKEN_PLUS_PLUS)) { // increment the field
|
||||||
@ -604,8 +606,9 @@ static void dot(CParseState *pstate, bool canAssign) {
|
|||||||
uint8_t args = parseArguments(pstate);
|
uint8_t args = parseArguments(pstate);
|
||||||
writeu8(pstate, OP_INVOKE);
|
writeu8(pstate, OP_INVOKE);
|
||||||
writeu8(pstate, args);
|
writeu8(pstate, args);
|
||||||
writeu8(pstate, 1); // TODO
|
writeu8(pstate, pstate->compiler->expectedValues); // TODO
|
||||||
valuePopped(pstate, args); // pops the function & the object but pushes a result
|
valuePopped(pstate, args+1); // args + function
|
||||||
|
valuePushed(pstate, pstate->compiler->expectedValues);
|
||||||
} else {
|
} else {
|
||||||
writeu8(pstate, OP_LOADCONST);
|
writeu8(pstate, OP_LOADCONST);
|
||||||
writeu16(pstate, name);
|
writeu16(pstate, name);
|
||||||
@ -615,11 +618,11 @@ static void dot(CParseState *pstate, bool canAssign) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _index(CParseState *pstate, bool canAssign) {
|
static void _index(CParseState *pstate, bool canAssign) {
|
||||||
expression(pstate);
|
expression(pstate, 1, true);
|
||||||
consume(pstate, TOKEN_RIGHT_BRACKET, "Expected ']' to end index.");
|
consume(pstate, TOKEN_RIGHT_BRACKET, "Expected ']' to end index.");
|
||||||
|
|
||||||
if (canAssign && match(pstate, TOKEN_EQUAL)) {
|
if (canAssign && match(pstate, TOKEN_EQUAL)) {
|
||||||
expression(pstate);
|
expression(pstate, 1, true);
|
||||||
writeu8(pstate, OP_NEWINDEX);
|
writeu8(pstate, OP_NEWINDEX);
|
||||||
valuePopped(pstate, 2); // pops key, value & object
|
valuePopped(pstate, 2); // pops key, value & object
|
||||||
} else if (match(pstate, TOKEN_PLUS_PLUS)) { // increment the field
|
} else if (match(pstate, TOKEN_PLUS_PLUS)) { // increment the field
|
||||||
@ -903,28 +906,44 @@ static void block(CParseState *pstate) {
|
|||||||
consume(pstate, TOKEN_END, "'end' expected to end block.'");
|
consume(pstate, TOKEN_END, "'end' expected to end block.'");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void varDeclaration(CParseState *pstate, bool forceLocal) {
|
static void varDeclaration(CParseState *pstate, bool forceLocal, int expectedValues) {
|
||||||
uint16_t global = parseVariable(pstate, "Expected identifer!", forceLocal);
|
uint16_t ident = parseVariable(pstate, "Expected identifer!", forceLocal);
|
||||||
|
expectedValues++;
|
||||||
|
|
||||||
if (match(pstate, TOKEN_EQUAL)) { // assigning a variable
|
if (match(pstate, TOKEN_EQUAL)) { // assigning a variable
|
||||||
valuePopped(pstate, 1); // we are expecting a value
|
|
||||||
|
|
||||||
// consume all the ','
|
// consume all the ','
|
||||||
do {
|
do {
|
||||||
expression(pstate);
|
valuePopped(pstate, 1);
|
||||||
|
int pushed = expression(pstate, expectedValues, false);
|
||||||
|
valuePushed(pstate, 1);
|
||||||
|
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));
|
} while (match(pstate, TOKEN_COMMA));
|
||||||
|
|
||||||
|
// for any expected value we didn't get
|
||||||
|
while (expectedValues-- > 0) {
|
||||||
valuePushed(pstate, 1);
|
valuePushed(pstate, 1);
|
||||||
|
writeu8(pstate, OP_NIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (match(pstate, TOKEN_COMMA)) {
|
||||||
|
varDeclaration(pstate, forceLocal, expectedValues);
|
||||||
} else {
|
} else {
|
||||||
writeu8(pstate, OP_NIL);
|
writeu8(pstate, OP_NIL);
|
||||||
valuePushed(pstate, 1);
|
valuePushed(pstate, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
defineVariable(pstate, global, forceLocal);
|
defineVariable(pstate, ident, forceLocal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ifStatement(CParseState *pstate) {
|
static void ifStatement(CParseState *pstate) {
|
||||||
expression(pstate);
|
expression(pstate, 1, true);
|
||||||
consume(pstate, TOKEN_THEN, "Expect 'then' after expression.");
|
consume(pstate, TOKEN_THEN, "Expect 'then' after expression.");
|
||||||
|
|
||||||
int jump = writeJmp(pstate, OP_PEJMP);
|
int jump = writeJmp(pstate, OP_PEJMP);
|
||||||
@ -967,7 +986,7 @@ static void ifStatement(CParseState *pstate) {
|
|||||||
|
|
||||||
static void whileStatement(CParseState *pstate) {
|
static void whileStatement(CParseState *pstate) {
|
||||||
int jumpLocation = getChunk(pstate)->count;
|
int jumpLocation = getChunk(pstate)->count;
|
||||||
expression(pstate);
|
expression(pstate, 1, true);
|
||||||
|
|
||||||
consume(pstate, TOKEN_DO, "expected 'do' after conditional expression.");
|
consume(pstate, TOKEN_DO, "expected 'do' after conditional expression.");
|
||||||
|
|
||||||
@ -1047,12 +1066,20 @@ static void returnStatement(CParseState *pstate) {
|
|||||||
if (blockFollow(pstate->current)) { // does this return have a value
|
if (blockFollow(pstate->current)) { // does this return have a value
|
||||||
writeu8(pstate, OP_NIL);
|
writeu8(pstate, OP_NIL);
|
||||||
writeu8(pstate, OP_RETURN);
|
writeu8(pstate, OP_RETURN);
|
||||||
|
writeu8(pstate, 1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
expression(pstate);
|
// grab return values
|
||||||
|
int rvalues = 0;
|
||||||
|
do {
|
||||||
|
expression(pstate, 1, true);
|
||||||
|
rvalues++;
|
||||||
|
} while (match(pstate, TOKEN_COMMA));
|
||||||
|
|
||||||
writeu8(pstate, OP_RETURN);
|
writeu8(pstate, OP_RETURN);
|
||||||
valuePopped(pstate, 1);
|
writeu8(pstate, rvalues);
|
||||||
|
valuePopped(pstate, rvalues);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void localFunction(CParseState *pstate) {
|
static void localFunction(CParseState *pstate) {
|
||||||
@ -1080,7 +1107,7 @@ static void forLoop(CParseState *pstate) {
|
|||||||
// parse conditional
|
// parse conditional
|
||||||
int exitJmp = -1;
|
int exitJmp = -1;
|
||||||
if (!match(pstate, TOKEN_EOS)) {
|
if (!match(pstate, TOKEN_EOS)) {
|
||||||
expression(pstate);
|
expression(pstate, 1, true);
|
||||||
consume(pstate, TOKEN_EOS, "Expected ';' after conditional");
|
consume(pstate, TOKEN_EOS, "Expected ';' after conditional");
|
||||||
|
|
||||||
exitJmp = writeJmp(pstate, OP_PEJMP);
|
exitJmp = writeJmp(pstate, OP_PEJMP);
|
||||||
@ -1092,9 +1119,7 @@ static void forLoop(CParseState *pstate) {
|
|||||||
int bodyJmp = writeJmp(pstate, OP_JMP);
|
int bodyJmp = writeJmp(pstate, OP_JMP);
|
||||||
|
|
||||||
int iteratorStart = getChunk(pstate)->count;
|
int iteratorStart = getChunk(pstate)->count;
|
||||||
int savedPushed = pstate->compiler->pushedValues;
|
expression(pstate, 0, true);
|
||||||
expression(pstate);
|
|
||||||
alignStack(pstate, savedPushed);
|
|
||||||
consume(pstate, TOKEN_RIGHT_PAREN, "Expected ')' after iterator");
|
consume(pstate, TOKEN_RIGHT_PAREN, "Expected ')' after iterator");
|
||||||
|
|
||||||
writeJmpBack(pstate, loopStart);
|
writeJmpBack(pstate, loopStart);
|
||||||
@ -1128,21 +1153,36 @@ static void synchronize(CParseState *pstate) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void expression(CParseState *pstate) {
|
static int expression(CParseState *pstate, int needed, bool forceNeeded) {
|
||||||
|
int lastExpected = pstate->compiler->expectedValues;
|
||||||
|
int saved = pstate->compiler->pushedValues + needed;
|
||||||
|
pstate->compiler->expectedValues = needed;
|
||||||
|
|
||||||
parsePrecedence(pstate, PREC_ASSIGNMENT);
|
parsePrecedence(pstate, PREC_ASSIGNMENT);
|
||||||
|
|
||||||
|
if (pstate->compiler->pushedValues > saved) {
|
||||||
|
writePop(pstate, pstate->compiler->pushedValues - saved);
|
||||||
|
valuePopped(pstate, pstate->compiler->pushedValues - saved);
|
||||||
|
} else if (forceNeeded && pstate->compiler->pushedValues < saved) {
|
||||||
|
error(pstate, "Missing expression!");
|
||||||
|
}
|
||||||
|
|
||||||
|
pstate->compiler->expectedValues = lastExpected;
|
||||||
|
|
||||||
|
return pstate->compiler->pushedValues - (saved - needed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void expressionStatement(CParseState *pstate) {
|
static void expressionStatement(CParseState *pstate) {
|
||||||
pstate->compiler->savedPushed = pstate->compiler->pushedValues;
|
pstate->compiler->savedPushed = pstate->compiler->pushedValues;
|
||||||
|
|
||||||
if (match(pstate, TOKEN_VAR)) {
|
if (match(pstate, TOKEN_VAR)) {
|
||||||
varDeclaration(pstate, false);
|
varDeclaration(pstate, false, 0);
|
||||||
} else if (match(pstate, TOKEN_LOCAL)) {
|
} else if (match(pstate, TOKEN_LOCAL)) {
|
||||||
// force declare a local
|
// force declare a local
|
||||||
if (match(pstate, TOKEN_FUNCTION))
|
if (match(pstate, TOKEN_FUNCTION))
|
||||||
localFunction(pstate); // force local a function
|
localFunction(pstate); // force local a function
|
||||||
else
|
else
|
||||||
varDeclaration(pstate, true); // force local a variable
|
varDeclaration(pstate, true, 0); // force local a variable
|
||||||
} else if (match(pstate, TOKEN_IF)) {
|
} else if (match(pstate, TOKEN_IF)) {
|
||||||
ifStatement(pstate);
|
ifStatement(pstate);
|
||||||
} else if (match(pstate, TOKEN_DO)) {
|
} else if (match(pstate, TOKEN_DO)) {
|
||||||
@ -1160,7 +1200,8 @@ static void expressionStatement(CParseState *pstate) {
|
|||||||
} else if (match(pstate, TOKEN_RETURN)) {
|
} else if (match(pstate, TOKEN_RETURN)) {
|
||||||
returnStatement(pstate);
|
returnStatement(pstate);
|
||||||
} else {
|
} else {
|
||||||
expression(pstate);
|
// we don't need/want any values on the stack, so call expression with 0 values needed
|
||||||
|
expression(pstate, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// realign the stack
|
// realign the stack
|
||||||
@ -1183,6 +1224,7 @@ static CObjFunction *endCompiler(CParseState *pstate) {
|
|||||||
popLocals(pstate, pstate->compiler->scopeDepth); // remove the locals from other scopes
|
popLocals(pstate, pstate->compiler->scopeDepth); // remove the locals from other scopes
|
||||||
writeu8(pstate, OP_NIL);
|
writeu8(pstate, OP_NIL);
|
||||||
writeu8(pstate, OP_RETURN);
|
writeu8(pstate, OP_RETURN);
|
||||||
|
writeu8(pstate, 1);
|
||||||
|
|
||||||
// update pstate to next compiler state
|
// update pstate to next compiler state
|
||||||
CCompilerState *cachedCCState = pstate->compiler;
|
CCompilerState *cachedCCState = pstate->compiler;
|
||||||
|
23
src/cvm.c
23
src/cvm.c
@ -116,7 +116,7 @@ static inline void callCFunction(CState *state, CosmoCFunction cfunc, int args,
|
|||||||
cosmoM_unfreezeGC(state);
|
cosmoM_unfreezeGC(state);
|
||||||
|
|
||||||
// remember where the return values are
|
// remember where the return values are
|
||||||
CValue* results = cosmoV_getTop(state, 0);
|
CValue* results = cosmoV_getTop(state, nres-1);
|
||||||
|
|
||||||
state->top = savedBase + offset; // set stack
|
state->top = savedBase + offset; // set stack
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ bool call(CState *state, CObjClosure *closure, int args, int nresults, int offse
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// remember where the return values are
|
// remember where the return values are
|
||||||
CValue* results = cosmoV_getTop(state, 0);
|
CValue* results = cosmoV_getTop(state, nres-1);
|
||||||
|
|
||||||
// pop the callframe and return results :)
|
// pop the callframe and return results :)
|
||||||
popCallFrame(state, offset);
|
popCallFrame(state, offset);
|
||||||
@ -167,15 +167,15 @@ bool call(CState *state, CObjClosure *closure, int args, int nresults, int offse
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool invokeMethod(CState* state, CObjObject *obj, CValue func, int args, int nresults) {
|
bool invokeMethod(CState* state, CObjObject *obj, CValue func, int args, int nresults, int offset) {
|
||||||
// first, set the first argument to the object
|
// first, set the first argument to the object
|
||||||
StkPtr temp = cosmoV_getTop(state, args);
|
StkPtr temp = cosmoV_getTop(state, args);
|
||||||
*temp = cosmoV_newObj(obj);
|
*temp = cosmoV_newObj(obj);
|
||||||
|
|
||||||
if (IS_CFUNCTION(func)) {
|
if (IS_CFUNCTION(func)) {
|
||||||
callCFunction(state, cosmoV_readCFunction(func), args+1, nresults, 1);
|
callCFunction(state, cosmoV_readCFunction(func), args+1, nresults, offset);
|
||||||
} else if (IS_CLOSURE(func)) {
|
} else if (IS_CLOSURE(func)) {
|
||||||
call(state, cosmoV_readClosure(func), args+1, nresults, 1); // offset = 1 so our stack is properly reset
|
call(state, cosmoV_readClosure(func), args+1, nresults, offset); // offset = 1 so our stack is properly reset
|
||||||
} else {
|
} else {
|
||||||
cosmoV_error(state, "Cannot invoke non-function type %s!", cosmoV_typeStr(func));
|
cosmoV_error(state, "Cannot invoke non-function type %s!", cosmoV_typeStr(func));
|
||||||
}
|
}
|
||||||
@ -202,7 +202,7 @@ COSMOVMRESULT cosmoV_call(CState *state, int args, int nresults) {
|
|||||||
}
|
}
|
||||||
case COBJ_METHOD: {
|
case COBJ_METHOD: {
|
||||||
CObjMethod *method = (CObjMethod*)cosmoV_readObj(*val);
|
CObjMethod *method = (CObjMethod*)cosmoV_readObj(*val);
|
||||||
invokeMethod(state, method->obj, method->func, args, nresults);
|
invokeMethod(state, method->obj, method->func, args, nresults, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_OBJECT: { // object is being instantiated, making another object
|
case COBJ_OBJECT: { // object is being instantiated, making another object
|
||||||
@ -213,7 +213,7 @@ COSMOVMRESULT cosmoV_call(CState *state, int args, int nresults) {
|
|||||||
|
|
||||||
// check if they defined an initalizer
|
// check if they defined an initalizer
|
||||||
if (cosmoO_getIString(state, protoObj, ISTRING_INIT, &ret)) {
|
if (cosmoO_getIString(state, protoObj, ISTRING_INIT, &ret)) {
|
||||||
invokeMethod(state, newObj, ret, args, nresults);
|
invokeMethod(state, newObj, ret, args, nresults, 1);
|
||||||
} else {
|
} else {
|
||||||
// no default initalizer
|
// no default initalizer
|
||||||
if (args != 0) {
|
if (args != 0) {
|
||||||
@ -549,11 +549,7 @@ int cosmoV_execute(CState *state) {
|
|||||||
cosmoO_getObject(state, object, *key, &val); // we use cosmoO_getObject instead of the cosmoV_getObject wrapper so we get the raw value from the object instead of the CObjMethod wrapper
|
cosmoO_getObject(state, object, *key, &val); // we use cosmoO_getObject instead of the cosmoV_getObject wrapper so we get the raw value from the object instead of the CObjMethod wrapper
|
||||||
|
|
||||||
// now invoke the method!
|
// now invoke the method!
|
||||||
invokeMethod(state, object, val, args, nres);
|
invokeMethod(state, object, val, args, nres, 0);
|
||||||
|
|
||||||
// moves return value & resets stack (key now points to the stack location of our return value)
|
|
||||||
*temp = *key;
|
|
||||||
state->top = key;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_ADD: { // pop 2 values off the stack & try to add them together
|
case OP_ADD: { // pop 2 values off the stack & try to add them together
|
||||||
@ -770,7 +766,8 @@ int cosmoV_execute(CState *state) {
|
|||||||
case OP_FALSE: cosmoV_pushBoolean(state, false); break;
|
case OP_FALSE: cosmoV_pushBoolean(state, false); break;
|
||||||
case OP_NIL: cosmoV_pushValue(state, cosmoV_newNil()); break;
|
case OP_NIL: cosmoV_pushValue(state, cosmoV_newNil()); break;
|
||||||
case OP_RETURN: {
|
case OP_RETURN: {
|
||||||
return 1;
|
uint8_t res = READBYTE();
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
CERROR("unknown opcode!");
|
CERROR("unknown opcode!");
|
||||||
|
Loading…
Reference in New Issue
Block a user