better stack trace
This commit is contained in:
@@ -515,8 +515,7 @@ ResultType(CometOperand, charptr) visitFuncDefStatement(CometCompiler* c, CometA
|
||||
return bodyResult;
|
||||
|
||||
// return back to the parent scope
|
||||
c->env = c->env->parent;
|
||||
free(funcEnv);
|
||||
c->env = destroyEnv(c->env);
|
||||
|
||||
return Success(CometOperand, charptr, NO_OPERAND);
|
||||
}
|
||||
@@ -641,7 +640,6 @@ ResultType(CometOperand, charptr) visitForStatement(CometCompiler* c, CometASTNo
|
||||
|
||||
// create env for for loop
|
||||
CometEnvironment* forLoopEnv = newEnvironment("", c->env);
|
||||
CometEnvironment* previousEnv = c->env;
|
||||
c->env = forLoopEnv;
|
||||
|
||||
// define iterator variable
|
||||
@@ -696,8 +694,7 @@ ResultType(CometOperand, charptr) visitForStatement(CometCompiler* c, CometASTNo
|
||||
resolveLabel(c, endLabel);
|
||||
|
||||
// exit the for loop's env
|
||||
c->env = previousEnv;
|
||||
free(forLoopEnv);
|
||||
c->env = destroyEnv(forLoopEnv);
|
||||
|
||||
|
||||
|
||||
@@ -759,9 +756,8 @@ ResultType(CometOperand, charptr) visitConstructorDefStatement(CometCompiler* c,
|
||||
buildReturn(c);
|
||||
|
||||
// return back to the parent scope
|
||||
c->env = c->env->parent;
|
||||
free(funcEnv);
|
||||
|
||||
c->env = destroyEnv(funcEnv);
|
||||
|
||||
return Success(CometOperand, charptr, NO_OPERAND);
|
||||
}
|
||||
ResultType(CometOperand, charptr) visitStructDefStatement(CometCompiler* c, CometASTNode* node) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "environment.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
CometEnvironment* newEnvironment(char* name, CometEnvironment* parent) {
|
||||
@@ -46,6 +47,15 @@ uint32_t defineVar(CometEnvironment* env, char* name, RecordType recordType, Com
|
||||
return record->recordIdx;
|
||||
}
|
||||
|
||||
CometEnvironment* destroyEnv(CometEnvironment* env) {
|
||||
CometEnvironment* parent = env->parent;
|
||||
|
||||
parent->recordIdx -= env->recordIdx;
|
||||
free(env);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
Record* lookup(CometEnvironment* env, char* name) {
|
||||
// search for the record and if it doesn't exist check for it in the parent scope
|
||||
Record* record;
|
||||
|
||||
@@ -34,4 +34,5 @@ struct CometEnvironment {
|
||||
|
||||
CometEnvironment* newEnvironment(char* name, CometEnvironment* parent);
|
||||
uint32_t defineVar(CometEnvironment* env, char* name, RecordType recordType, CometOperand value, CometType type, bool isMutable);
|
||||
Record* lookup(CometEnvironment* env, char* name);
|
||||
Record* lookup(CometEnvironment* env, char* name);
|
||||
CometEnvironment* destroyEnv(CometEnvironment* env);
|
||||
16
test.comet
16
test.comet
@@ -1,12 +1,20 @@
|
||||
struct Foo {
|
||||
int x
|
||||
struct Bar {
|
||||
int y
|
||||
|
||||
init(int x) {
|
||||
init(int y) {
|
||||
self.y = y
|
||||
}
|
||||
}
|
||||
|
||||
struct Foo {
|
||||
Bar x
|
||||
|
||||
init(Bar x) {
|
||||
self.x = x
|
||||
}
|
||||
}
|
||||
|
||||
func main() -> int {
|
||||
Foo x = new Foo(4)
|
||||
Foo x = new Foo(new Bar(123))
|
||||
return x.x
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
#ifndef OPERAND_H
|
||||
#define OPERAND_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
COMET_VOID,
|
||||
COMET_SMALL,
|
||||
COMET_INT,
|
||||
COMET_BIG,
|
||||
COMET_FLOAT,
|
||||
COMET_DOUBLE,
|
||||
COMET_BOOL
|
||||
} CometValueTypeKind;
|
||||
|
||||
typedef struct {
|
||||
uint32_t pos;
|
||||
bool resolved;
|
||||
} CometLabel;
|
||||
|
||||
typedef enum {
|
||||
CO_NONE,
|
||||
CO_IMMEDIATE,
|
||||
CO_STACK,
|
||||
CO_SYMBOL,
|
||||
CO_LABEL
|
||||
} CometOperandKind;
|
||||
|
||||
typedef struct {
|
||||
CometValueTypeKind typeKind;
|
||||
union {
|
||||
int8_t smallVal;
|
||||
int32_t intVal;
|
||||
int64_t bigVal;
|
||||
float floatVal;
|
||||
double doubleVal;
|
||||
bool boolVal;
|
||||
};
|
||||
} CometImmediate;
|
||||
|
||||
typedef struct {
|
||||
CometOperandKind type;
|
||||
union {
|
||||
uint32_t stackIdx;
|
||||
CometImmediate imm;
|
||||
uint32_t symbolIdx;
|
||||
CometLabel* label;
|
||||
};
|
||||
} CometOperand;
|
||||
|
||||
#endif
|
||||
52
vm_src/vm.c
52
vm_src/vm.c
@@ -1,8 +1,9 @@
|
||||
#include "vm.h"
|
||||
#include "args.h"
|
||||
#include "operand.h"
|
||||
#include "../include/operand.h"
|
||||
#include "serialized.h"
|
||||
#include <assert.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
@@ -62,9 +63,43 @@ void push(CometVM* vm, int64_t value) {
|
||||
*vm->currentSp += 1;
|
||||
}
|
||||
|
||||
char* stackAsString(int64_t* stack, uint32_t sp) {
|
||||
Estr stackString = CREATE_ESTR("[");
|
||||
|
||||
for (size_t i = 0; i < sp; i++) {
|
||||
|
||||
char* buffer = malloc(64);
|
||||
|
||||
sprintf(buffer, "0x%" PRIx64 "%s", stack[i], i < sp ? ", " : "");
|
||||
APPEND_ESTR(stackString, buffer);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
APPEND_ESTR(stackString, "]");
|
||||
|
||||
return stackString.str;
|
||||
}
|
||||
|
||||
char* stackTrace(CometVM* vm) {
|
||||
Estr stackTrace = CREATE_ESTR("\nCall Stack:\n");
|
||||
|
||||
for (size_t i = 0; i < vm->callIdx+1; i++) {
|
||||
Frame* call = vm->callStack[i];
|
||||
|
||||
char* funcBuffer = malloc(128);
|
||||
sprintf(funcBuffer, " 0x%04lx %s (sp: 0x%x) %s\n", call->ip, call->funcName, call->sp, stackAsString(call->stack, call->sp));
|
||||
|
||||
APPEND_ESTR(stackTrace, funcBuffer);
|
||||
}
|
||||
|
||||
return stackTrace.str;
|
||||
}
|
||||
|
||||
int64_t getTop(CometVM* vm) {
|
||||
if ((*vm->currentSp) <= 0) {
|
||||
fprintf(stderr, "Attempted to pop top of stack while stack was empty, this is a compiler bug! Please report this at https://chookspace.com/Comet/Comet/issues with your code.\n");
|
||||
fprintf(stderr, "%s\n", stackTrace(vm));
|
||||
assert(false);
|
||||
}
|
||||
|
||||
@@ -504,21 +539,6 @@ ResultType(voidPtr, charptr) vmClock(CometVM* vm) {
|
||||
return Success(voidPtr, charptr, NULL);
|
||||
}
|
||||
|
||||
char* stackTrace(CometVM* vm) {
|
||||
Estr stackTrace = CREATE_ESTR("\nStack Trace:\n");
|
||||
|
||||
for (size_t i = 0; i < vm->callIdx; i++) {
|
||||
Frame* call = vm->callStack[i];
|
||||
|
||||
char* funcBuffer = malloc(128);
|
||||
sprintf(funcBuffer, " 0x%04lx %s (sp: 0x%x)\n", call->ip, call->funcName, call->sp);
|
||||
|
||||
APPEND_ESTR(stackTrace, funcBuffer);
|
||||
}
|
||||
|
||||
return stackTrace.str;
|
||||
}
|
||||
|
||||
ResultType(int, charptr) startVM(CometVM* vm) {
|
||||
vm->running = true;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user