mirror of
https://github.com/CPunch/Cosmo.git
synced 2024-12-04 14:36:01 +00:00
Compare commits
6 Commits
e7b2d7d833
...
e0455902b0
Author | SHA1 | Date | |
---|---|---|---|
e0455902b0 | |||
43d79a456e | |||
105a3d70c3 | |||
93f3ae1106 | |||
4816e64612 | |||
0df56bd42a |
24
main.c
24
main.c
@ -50,13 +50,23 @@ static bool interpret(CState *state, const char *script, const char *mod)
|
|||||||
|
|
||||||
// cosmoV_compileString pushes the result onto the stack (COBJ_ERROR or COBJ_CLOSURE)
|
// cosmoV_compileString pushes the result onto the stack (COBJ_ERROR or COBJ_CLOSURE)
|
||||||
if (cosmoV_compileString(state, script, mod)) {
|
if (cosmoV_compileString(state, script, mod)) {
|
||||||
// 0 args being passed, 0 results expected
|
if (!cosmoV_pcall(state, 0, 1)) {
|
||||||
if (!cosmoV_pcall(state, 0, 0)) {
|
cosmoV_printBacktrace(state, cosmoV_readError(*cosmoV_pop(state)));
|
||||||
cosmoV_printError(state, cosmoV_readError(*cosmoV_pop(state)));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the result is nil, we don't print it
|
||||||
|
if (IS_NIL(*cosmoV_getTop(state, 0))) {
|
||||||
|
cosmoV_pop(state);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, we print the result
|
||||||
|
cosmoV_printValue(*cosmoV_getTop(state, 0));
|
||||||
|
printf("\n");
|
||||||
|
cosmoV_pop(state);
|
||||||
} else {
|
} else {
|
||||||
cosmoV_printError(state, cosmoV_readError(*cosmoV_pop(state)));
|
cosmoV_printBacktrace(state, cosmoV_readError(*cosmoV_pop(state)));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +168,7 @@ void compileScript(CState *state, const char *in, const char *out)
|
|||||||
CObjFunction *func = cosmoV_readClosure(*cosmoV_getTop(state, 0))->function;
|
CObjFunction *func = cosmoV_readClosure(*cosmoV_getTop(state, 0))->function;
|
||||||
cosmoD_dump(state, func, fileWriter, (void *)fout);
|
cosmoD_dump(state, func, fileWriter, (void *)fout);
|
||||||
} else {
|
} else {
|
||||||
cosmoV_printError(state, cosmoV_readError(*cosmoV_pop(state)));
|
cosmoV_printBacktrace(state, cosmoV_readError(*cosmoV_pop(state)));
|
||||||
}
|
}
|
||||||
|
|
||||||
free(script);
|
free(script);
|
||||||
@ -171,13 +181,13 @@ void loadScript(CState *state, const char *in)
|
|||||||
{
|
{
|
||||||
FILE *file = fopen(in, "rb");
|
FILE *file = fopen(in, "rb");
|
||||||
if (!cosmoV_undump(state, fileReader, file)) {
|
if (!cosmoV_undump(state, fileReader, file)) {
|
||||||
cosmoV_printError(state, cosmoV_readError(*cosmoV_pop(state)));
|
cosmoV_printBacktrace(state, cosmoV_readError(*cosmoV_pop(state)));
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
printf("[!] loaded %s!\n", in);
|
printf("[!] loaded %s!\n", in);
|
||||||
if (!cosmoV_pcall(state, 0, 0))
|
if (!cosmoV_pcall(state, 0, 0))
|
||||||
cosmoV_printError(state, cosmoV_readError(*cosmoV_pop(state)));
|
cosmoV_printBacktrace(state, cosmoV_readError(*cosmoV_pop(state)));
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ int cosmoB_print(CState *state, int nargs, CValue *args)
|
|||||||
CObjString *str = cosmoV_toString(state, args[i]);
|
CObjString *str = cosmoV_toString(state, args[i]);
|
||||||
printf("%s", cosmoO_readCString(str));
|
printf("%s", cosmoO_readCString(str));
|
||||||
} else { // else, thats pretty expensive for primitives, just print the raw value
|
} else { // else, thats pretty expensive for primitives, just print the raw value
|
||||||
printValue(args[i]);
|
cosmoV_printValue(args[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -62,7 +62,7 @@ static int constInstruction(const char *name, CChunk *chunk, int offset)
|
|||||||
printf("%-16s [%05d] - ", name, index);
|
printf("%-16s [%05d] - ", name, index);
|
||||||
CValue val = chunk->constants.values[index];
|
CValue val = chunk->constants.values[index];
|
||||||
|
|
||||||
printValue(val);
|
cosmoV_printValue(val);
|
||||||
|
|
||||||
return offset + 1 + (sizeof(uint16_t) / sizeof(INSTRUCTION)); // consume opcode + uint
|
return offset + 1 + (sizeof(uint16_t) / sizeof(INSTRUCTION)); // consume opcode + uint
|
||||||
}
|
}
|
||||||
@ -128,7 +128,7 @@ int disasmInstr(CChunk *chunk, int offset, int indent)
|
|||||||
CObjFunction *cobjFunc = (CObjFunction *)cosmoV_readRef(val);
|
CObjFunction *cobjFunc = (CObjFunction *)cosmoV_readRef(val);
|
||||||
offset += 3; // we consumed the opcode + u16
|
offset += 3; // we consumed the opcode + u16
|
||||||
|
|
||||||
printValue(val);
|
cosmoV_printValue(val);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
// list the upvalues/locals that are captured
|
// list the upvalues/locals that are captured
|
||||||
|
@ -715,13 +715,13 @@ void printObject(CObj *o)
|
|||||||
case COBJ_ERROR: {
|
case COBJ_ERROR: {
|
||||||
CObjError *err = (CObjError *)o;
|
CObjError *err = (CObjError *)o;
|
||||||
printf("%p -> ", (void *)o);
|
printf("%p -> ", (void *)o);
|
||||||
printValue(err->err);
|
cosmoV_printValue(err->err);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_METHOD: {
|
case COBJ_METHOD: {
|
||||||
CObjMethod *method = (CObjMethod *)o;
|
CObjMethod *method = (CObjMethod *)o;
|
||||||
printf("%p -> ", (void *)method);
|
printf("%p -> ", (void *)method);
|
||||||
printValue(method->func);
|
cosmoV_printValue(method->func);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COBJ_CLOSURE: {
|
case COBJ_CLOSURE: {
|
||||||
@ -733,7 +733,7 @@ void printObject(CObj *o)
|
|||||||
case COBJ_UPVALUE: {
|
case COBJ_UPVALUE: {
|
||||||
CObjUpval *upval = (CObjUpval *)o;
|
CObjUpval *upval = (CObjUpval *)o;
|
||||||
printf("%p -> ", (void *)upval->val);
|
printf("%p -> ", (void *)upval->val);
|
||||||
printValue(*upval->val);
|
cosmoV_printValue(*upval->val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -55,7 +55,7 @@ struct CObjError
|
|||||||
CCallFrame *frames;
|
CCallFrame *frames;
|
||||||
int frameCount;
|
int frameCount;
|
||||||
int line; // reserved for parser errors
|
int line; // reserved for parser errors
|
||||||
bool parserError; // if true, cosmoV_printError will format the error to the lexer
|
bool parserError; // if true, cosmoV_printBacktrace will format the error to the lexer
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CObjObject
|
struct CObjObject
|
||||||
|
44
src/cparse.c
44
src/cparse.c
@ -102,7 +102,6 @@ static int expressionPrecedence(CParseState *pstate, int needed, Precedence prec
|
|||||||
// returns # of pushed values onto the stack
|
// returns # of pushed values onto the stack
|
||||||
static int expression(CParseState *pstate, int needed, bool forceNeeded);
|
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 parseFunction(CParseState *pstate, FunctionType type);
|
static void parseFunction(CParseState *pstate, FunctionType type);
|
||||||
static void expressionStatement(CParseState *pstate);
|
static void expressionStatement(CParseState *pstate);
|
||||||
static ParseRule *getRule(CTokenType type);
|
static ParseRule *getRule(CTokenType type);
|
||||||
@ -1099,18 +1098,19 @@ static ParseRule *getRule(CTokenType type)
|
|||||||
// returns true if it got past the first token (aka prefix wasn't null)
|
// returns true if it got past the first token (aka prefix wasn't null)
|
||||||
static bool parsePrecedence(CParseState *pstate, Precedence prec)
|
static bool parsePrecedence(CParseState *pstate, Precedence prec)
|
||||||
{
|
{
|
||||||
|
bool canAssign;
|
||||||
|
ParseFunc prefix, infix;
|
||||||
|
|
||||||
advance(pstate);
|
advance(pstate);
|
||||||
|
if ((prefix = getRule(pstate->previous.type)->prefix) == NULL)
|
||||||
ParseFunc prefix = getRule(pstate->previous.type)->prefix;
|
|
||||||
|
|
||||||
if (prefix == NULL)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool canAssign = prec <= PREC_ASSIGNMENT;
|
canAssign = prec <= PREC_ASSIGNMENT;
|
||||||
prefix(pstate, canAssign, prec);
|
prefix(pstate, canAssign, prec);
|
||||||
|
|
||||||
while (prec <= getRule(pstate->current.type)->level) {
|
while (prec <= getRule(pstate->current.type)->level) {
|
||||||
ParseFunc infix = getRule(pstate->current.type)->infix;
|
if ((infix = getRule(pstate->current.type)->infix) == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
advance(pstate);
|
advance(pstate);
|
||||||
infix(pstate, canAssign, prec);
|
infix(pstate, canAssign, prec);
|
||||||
}
|
}
|
||||||
@ -1264,7 +1264,7 @@ static void endScope(CParseState *pstate)
|
|||||||
static void block(CParseState *pstate)
|
static void block(CParseState *pstate)
|
||||||
{
|
{
|
||||||
while (!check(pstate, TOKEN_END) && !check(pstate, TOKEN_EOF) && !check(pstate, TOKEN_ERROR)) {
|
while (!check(pstate, TOKEN_END) && !check(pstate, TOKEN_EOF) && !check(pstate, TOKEN_ERROR)) {
|
||||||
declaration(pstate);
|
statement(pstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
consume(pstate, TOKEN_END, "'end' expected to end block.'");
|
consume(pstate, TOKEN_END, "'end' expected to end block.'");
|
||||||
@ -1321,7 +1321,7 @@ static void ifStatement(CParseState *pstate)
|
|||||||
while (!check(pstate, TOKEN_END) && !check(pstate, TOKEN_ELSE) &&
|
while (!check(pstate, TOKEN_END) && !check(pstate, TOKEN_ELSE) &&
|
||||||
!check(pstate, TOKEN_ELSEIF) && !check(pstate, TOKEN_EOF) &&
|
!check(pstate, TOKEN_ELSEIF) && !check(pstate, TOKEN_EOF) &&
|
||||||
!check(pstate, TOKEN_ERROR)) {
|
!check(pstate, TOKEN_ERROR)) {
|
||||||
declaration(pstate);
|
statement(pstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
endScope(pstate);
|
endScope(pstate);
|
||||||
@ -1471,10 +1471,10 @@ static void functionDeclaration(CParseState *pstate)
|
|||||||
|
|
||||||
static void returnStatement(CParseState *pstate)
|
static void returnStatement(CParseState *pstate)
|
||||||
{
|
{
|
||||||
if (pstate->compiler->type != FTYPE_FUNCTION && pstate->compiler->type != FTYPE_METHOD) {
|
// if (pstate->compiler->type != FTYPE_FUNCTION && pstate->compiler->type != FTYPE_METHOD) {
|
||||||
error(pstate, "Expected 'return' in function!");
|
// error(pstate, "Expected 'return' in function!");
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
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);
|
||||||
@ -1589,7 +1589,7 @@ static void forLoop(CParseState *pstate)
|
|||||||
|
|
||||||
// parse initializer
|
// parse initializer
|
||||||
if (!match(pstate, TOKEN_EOS)) {
|
if (!match(pstate, TOKEN_EOS)) {
|
||||||
expressionStatement(pstate);
|
statement(pstate);
|
||||||
consume(pstate, TOKEN_EOS, "Expected ';' after initializer");
|
consume(pstate, TOKEN_EOS, "Expected ';' after initializer");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1705,7 +1705,7 @@ static int expression(CParseState *pstate, int needed, bool forceNeeded)
|
|||||||
forceNeeded); // anything above assignments are an expression
|
forceNeeded); // anything above assignments are an expression
|
||||||
}
|
}
|
||||||
|
|
||||||
static void expressionStatement(CParseState *pstate)
|
static void statement(CParseState *pstate)
|
||||||
{
|
{
|
||||||
int savedPushed = pstate->compiler->pushedValues;
|
int savedPushed = pstate->compiler->pushedValues;
|
||||||
|
|
||||||
@ -1760,16 +1760,6 @@ static void expressionStatement(CParseState *pstate)
|
|||||||
alignStack(pstate, savedPushed);
|
alignStack(pstate, savedPushed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void statement(CParseState *pstate)
|
|
||||||
{
|
|
||||||
expressionStatement(pstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void declaration(CParseState *pstate)
|
|
||||||
{
|
|
||||||
statement(pstate);
|
|
||||||
}
|
|
||||||
|
|
||||||
static CObjFunction *endCompiler(CParseState *pstate)
|
static CObjFunction *endCompiler(CParseState *pstate)
|
||||||
{
|
{
|
||||||
popLocals(pstate, pstate->compiler->scopeDepth + 1); // remove the locals from other scopes
|
popLocals(pstate, pstate->compiler->scopeDepth + 1); // remove the locals from other scopes
|
||||||
@ -1794,7 +1784,7 @@ CObjFunction *cosmoP_compileString(CState *state, const char *source, const char
|
|||||||
advance(&parser);
|
advance(&parser);
|
||||||
|
|
||||||
while (!match(&parser, TOKEN_EOF)) {
|
while (!match(&parser, TOKEN_EOF)) {
|
||||||
declaration(&parser);
|
statement(&parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
consume(&parser, TOKEN_EOF, "End of file expected!");
|
consume(&parser, TOKEN_EOF, "End of file expected!");
|
||||||
|
@ -203,7 +203,7 @@ void cosmoV_printStack(CState *state)
|
|||||||
printf("==== [[ stack dump ]] ====\n");
|
printf("==== [[ stack dump ]] ====\n");
|
||||||
for (CValue *top = state->top - 1; top >= state->stack; top--) {
|
for (CValue *top = state->top - 1; top >= state->stack; top--) {
|
||||||
printf("%d: ", (int)(top - state->stack));
|
printf("%d: ", (int)(top - state->stack));
|
||||||
printValue(*top);
|
cosmoV_printValue(*top);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,8 @@ static uint32_t getObjectHash(CObj *obj)
|
|||||||
switch (obj->type) {
|
switch (obj->type) {
|
||||||
case COBJ_STRING:
|
case COBJ_STRING:
|
||||||
return ((CObjString *)obj)->hash;
|
return ((CObjString *)obj)->hash;
|
||||||
|
case COBJ_CFUNCTION:
|
||||||
|
return (uint32_t)((CObjCFunction *)obj)->cfunc;
|
||||||
default:
|
default:
|
||||||
return (uint32_t)obj; // just "hash" the pointer
|
return (uint32_t)obj; // just "hash" the pointer
|
||||||
}
|
}
|
||||||
@ -286,9 +288,9 @@ void cosmoT_printTable(CTable *tbl, const char *name)
|
|||||||
for (int i = 0; i < cap; i++) {
|
for (int i = 0; i < cap; i++) {
|
||||||
CTableEntry *entry = &tbl->table[i];
|
CTableEntry *entry = &tbl->table[i];
|
||||||
if (!(IS_NIL(entry->key))) {
|
if (!(IS_NIL(entry->key))) {
|
||||||
printValue(entry->key);
|
cosmoV_printValue(entry->key);
|
||||||
printf(" - ");
|
printf(" - ");
|
||||||
printValue(entry->val);
|
cosmoV_printValue(entry->val);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ const char *cosmoV_typeStr(CValue val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void printValue(CValue val)
|
void cosmoV_printValue(CValue val)
|
||||||
{
|
{
|
||||||
switch (GET_TYPE(val)) {
|
switch (GET_TYPE(val)) {
|
||||||
case COSMO_TNUMBER:
|
case COSMO_TNUMBER:
|
||||||
|
@ -119,7 +119,7 @@ void initValArray(CState *state, CValueArray *val, size_t startCapacity);
|
|||||||
void cleanValArray(CState *state, CValueArray *array); // cleans array
|
void cleanValArray(CState *state, CValueArray *array); // cleans array
|
||||||
void appendValArray(CState *state, CValueArray *array, CValue val);
|
void appendValArray(CState *state, CValueArray *array, CValue val);
|
||||||
|
|
||||||
void printValue(CValue val);
|
void cosmoV_printValue(CValue val);
|
||||||
COSMO_API bool cosmoV_equal(CState *state, CValue valA, CValue valB);
|
COSMO_API bool cosmoV_equal(CState *state, CValue valA, CValue valB);
|
||||||
COSMO_API CObjString *cosmoV_toString(CState *state, CValue val);
|
COSMO_API CObjString *cosmoV_toString(CState *state, CValue val);
|
||||||
COSMO_API cosmo_Number cosmoV_toNumber(CState *state, CValue val);
|
COSMO_API cosmo_Number cosmoV_toNumber(CState *state, CValue val);
|
||||||
|
@ -78,7 +78,7 @@ bool cosmoV_compileString(CState *state, const char *src, const char *name)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cosmoV_printError(CState *state, CObjError *err)
|
void cosmoV_printBacktrace(CState *state, CObjError *err)
|
||||||
{
|
{
|
||||||
// print stack trace
|
// print stack trace
|
||||||
for (int i = 0; i < err->frameCount; i++) {
|
for (int i = 0; i < err->frameCount; i++) {
|
||||||
@ -129,7 +129,7 @@ void cosmoV_throw(CState *state)
|
|||||||
} else {
|
} else {
|
||||||
cosmoV_pushValue(state, val);
|
cosmoV_pushValue(state, val);
|
||||||
fprintf(stderr, "Unhandled panic! ");
|
fprintf(stderr, "Unhandled panic! ");
|
||||||
cosmoV_printError(state, error);
|
cosmoV_printBacktrace(state, error);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,7 +340,7 @@ void callCValue(CState *state, CValue func, int args, int nresults, int offset)
|
|||||||
#ifdef VM_DEBUG
|
#ifdef VM_DEBUG
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printIndent(state->frameCount - 1);
|
printIndent(state->frameCount - 1);
|
||||||
printValue(func);
|
cosmoV_printValue(func);
|
||||||
printf("(%d args)\n", args);
|
printf("(%d args)\n", args);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ COSMO_API CObjObject *cosmoV_makeObject(CState *state, int pairs);
|
|||||||
COSMO_API void cosmoV_makeTable(CState *state, int pairs);
|
COSMO_API void cosmoV_makeTable(CState *state, int pairs);
|
||||||
COSMO_API void cosmoV_concat(CState *state, int vals);
|
COSMO_API void cosmoV_concat(CState *state, int vals);
|
||||||
COSMO_API void cosmoV_pushFString(CState *state, const char *format, ...);
|
COSMO_API void cosmoV_pushFString(CState *state, const char *format, ...);
|
||||||
COSMO_API void cosmoV_printError(CState *state, CObjError *err);
|
COSMO_API void cosmoV_printBacktrace(CState *state, CObjError *err);
|
||||||
COSMO_API void cosmoV_throw(CState *state);
|
COSMO_API void cosmoV_throw(CState *state);
|
||||||
COSMO_API void cosmoV_error(CState *state, const char *format, ...);
|
COSMO_API void cosmoV_error(CState *state, const char *format, ...);
|
||||||
COSMO_API void cosmoV_insert(CState *state, int indx, CValue val);
|
COSMO_API void cosmoV_insert(CState *state, int indx, CValue val);
|
||||||
|
Loading…
Reference in New Issue
Block a user