From 3a28de6b2ae1a8efa9dc68fb11e75fe110407412 Mon Sep 17 00:00:00 2001 From: CPunch Date: Sun, 31 Jan 2021 12:06:20 -0600 Subject: [PATCH] Added 'local' support for 'proto', fixed DOS bug in proto parser --- src/cparse.c | 29 +++++++++++++++++++++++++---- src/cvm.c | 4 ++-- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/cparse.c b/src/cparse.c index dc20fb5..02fce5b 100644 --- a/src/cparse.c +++ b/src/cparse.c @@ -1036,13 +1036,12 @@ static void defineVariable(CParseState *pstate, uint16_t global, bool forceLocal } static void _proto(CParseState *pstate) { - uint16_t var = parseVariable(pstate, "Expected identifer!", false); int entries = 0; while (!match(pstate, TOKEN_END) && !match(pstate, TOKEN_EOF) && !pstate->hadError) { if (match(pstate, TOKEN_FUNCTION)) { // define method - consume(pstate, TOKEN_IDENTIFIER, "Expected identifier!"); + consume(pstate, TOKEN_IDENTIFIER, "Expected identifier for method!"); uint16_t fieldIdent = identifierConstant(pstate, &pstate->previous); // OP_NEWOBJECT expects the key on the stack before the value @@ -1051,6 +1050,8 @@ static void _proto(CParseState *pstate) { function(pstate, FTYPE_METHOD); valuePopped(pstate, 1); + } else { + errorAtCurrent(pstate, "Illegal syntax!"); } entries++; @@ -1059,9 +1060,27 @@ static void _proto(CParseState *pstate) { writeu8(pstate, OP_NEWOBJECT); writeu16(pstate, entries); 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); } +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) { if (pstate->hadError) return; @@ -1541,7 +1560,9 @@ static void expressionStatement(CParseState *pstate) { } else if (match(pstate, TOKEN_LOCAL)) { // force declare a local 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 varDeclaration(pstate, true, 0); // force local a variable } else if (match(pstate, TOKEN_IF)) { @@ -1557,7 +1578,7 @@ static void expressionStatement(CParseState *pstate) { } else if (match(pstate, TOKEN_FUNCTION)) { functionDeclaration(pstate); } else if (match(pstate, TOKEN_PROTO)) { - _proto(pstate); + protoDeclaration(pstate); } else if (match(pstate, TOKEN_BREAK)) { breakStatement(pstate); } else if (match(pstate, TOKEN_CONTINUE)) { diff --git a/src/cvm.c b/src/cvm.c index b045f48..84dd60f 100644 --- a/src/cvm.c +++ b/src/cvm.c @@ -307,7 +307,7 @@ bool callCValue(CState *state, CValue func, int args, int nresults, int offset) #endif 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; } @@ -350,7 +350,7 @@ bool callCValue(CState *state, CValue func, int args, int nresults, int offset) break; } 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; }