better stack trace

This commit is contained in:
2026-05-31 21:27:22 +10:00
parent 2f54859ddc
commit dc7c81e08b
6 changed files with 64 additions and 80 deletions

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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);

View File

@@ -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
}

View File

@@ -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

View File

@@ -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;