mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-11-22 07:20:05 +00:00
Added 'local' support for 'proto', fixed DOS bug in proto parser
This commit is contained in:
parent
300ffb89e9
commit
3a28de6b2a
29
src/cparse.c
29
src/cparse.c
@ -1036,13 +1036,12 @@ static void defineVariable(CParseState *pstate, uint16_t global, bool forceLocal
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _proto(CParseState *pstate) {
|
static void _proto(CParseState *pstate) {
|
||||||
uint16_t var = parseVariable(pstate, "Expected identifer!", false);
|
|
||||||
int entries = 0;
|
int entries = 0;
|
||||||
|
|
||||||
while (!match(pstate, TOKEN_END) && !match(pstate, TOKEN_EOF) && !pstate->hadError) {
|
while (!match(pstate, TOKEN_END) && !match(pstate, TOKEN_EOF) && !pstate->hadError) {
|
||||||
if (match(pstate, TOKEN_FUNCTION)) {
|
if (match(pstate, TOKEN_FUNCTION)) {
|
||||||
// define method
|
// define method
|
||||||
consume(pstate, TOKEN_IDENTIFIER, "Expected identifier!");
|
consume(pstate, TOKEN_IDENTIFIER, "Expected identifier for method!");
|
||||||
uint16_t fieldIdent = identifierConstant(pstate, &pstate->previous);
|
uint16_t fieldIdent = identifierConstant(pstate, &pstate->previous);
|
||||||
|
|
||||||
// OP_NEWOBJECT expects the key on the stack before the value
|
// OP_NEWOBJECT expects the key on the stack before the value
|
||||||
@ -1051,6 +1050,8 @@ static void _proto(CParseState *pstate) {
|
|||||||
|
|
||||||
function(pstate, FTYPE_METHOD);
|
function(pstate, FTYPE_METHOD);
|
||||||
valuePopped(pstate, 1);
|
valuePopped(pstate, 1);
|
||||||
|
} else {
|
||||||
|
errorAtCurrent(pstate, "Illegal syntax!");
|
||||||
}
|
}
|
||||||
|
|
||||||
entries++;
|
entries++;
|
||||||
@ -1059,9 +1060,27 @@ static void _proto(CParseState *pstate) {
|
|||||||
writeu8(pstate, OP_NEWOBJECT);
|
writeu8(pstate, OP_NEWOBJECT);
|
||||||
writeu16(pstate, entries);
|
writeu16(pstate, entries);
|
||||||
valuePushed(pstate, 1);
|
valuePushed(pstate, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void protoDeclaration(CParseState *pstate) {
|
||||||
|
uint16_t var = parseVariable(pstate, "Expected identifer for proto!", false);
|
||||||
|
|
||||||
|
// parse proto definiton
|
||||||
|
_proto(pstate);
|
||||||
|
|
||||||
defineVariable(pstate, var, false);
|
defineVariable(pstate, var, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void localProto(CParseState *pstate) {
|
||||||
|
// parses the variable, forcefully marking it as a local
|
||||||
|
uint16_t var = parseVariable(pstate, "Expected identifer for proto!", true);
|
||||||
|
|
||||||
|
// parse proto definiton
|
||||||
|
_proto(pstate);
|
||||||
|
|
||||||
|
defineVariable(pstate, var, true);
|
||||||
|
}
|
||||||
|
|
||||||
static void popLocals(CParseState *pstate, int toScope) {
|
static void popLocals(CParseState *pstate, int toScope) {
|
||||||
if (pstate->hadError)
|
if (pstate->hadError)
|
||||||
return;
|
return;
|
||||||
@ -1541,7 +1560,9 @@ static void expressionStatement(CParseState *pstate) {
|
|||||||
} 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 a local function declaration
|
||||||
|
else if (match(pstate, TOKEN_PROTO))
|
||||||
|
localProto(pstate); // force a local proto declaration
|
||||||
else
|
else
|
||||||
varDeclaration(pstate, true, 0); // force local a variable
|
varDeclaration(pstate, true, 0); // force local a variable
|
||||||
} else if (match(pstate, TOKEN_IF)) {
|
} else if (match(pstate, TOKEN_IF)) {
|
||||||
@ -1557,7 +1578,7 @@ static void expressionStatement(CParseState *pstate) {
|
|||||||
} else if (match(pstate, TOKEN_FUNCTION)) {
|
} else if (match(pstate, TOKEN_FUNCTION)) {
|
||||||
functionDeclaration(pstate);
|
functionDeclaration(pstate);
|
||||||
} else if (match(pstate, TOKEN_PROTO)) {
|
} else if (match(pstate, TOKEN_PROTO)) {
|
||||||
_proto(pstate);
|
protoDeclaration(pstate);
|
||||||
} else if (match(pstate, TOKEN_BREAK)) {
|
} else if (match(pstate, TOKEN_BREAK)) {
|
||||||
breakStatement(pstate);
|
breakStatement(pstate);
|
||||||
} else if (match(pstate, TOKEN_CONTINUE)) {
|
} else if (match(pstate, TOKEN_CONTINUE)) {
|
||||||
|
@ -307,7 +307,7 @@ bool callCValue(CState *state, CValue func, int args, int nresults, int offset)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!IS_OBJ(func)) {
|
if (!IS_OBJ(func)) {
|
||||||
cosmoV_error(state, "Cannot call non-function type %s!", cosmoV_typeStr(func));
|
cosmoV_error(state, "Cannot call non-callable type %s!", cosmoV_typeStr(func));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,7 +350,7 @@ bool callCValue(CState *state, CValue func, int args, int nresults, int offset)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
cosmoV_error(state, "Cannot call non-function type %s!", cosmoV_typeStr(func));
|
cosmoV_error(state, "Cannot call non-callable type %s!", cosmoV_typeStr(func));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user