custom exceptions!!!

This commit is contained in:
2026-06-21 16:15:40 +10:00
parent 0be8796098
commit 7bb67d7bd5
6 changed files with 89 additions and 11 deletions

View File

@@ -20,6 +20,7 @@ struct CometStruct {
char** fieldNames;
CometType* fieldTypes;
char* name;
CometStruct* parent;
};
// an instance of a struct

View File

@@ -147,6 +147,7 @@ struct CometASTNode {
CometASTNode* tryBlock;
CometASTNode* exceptBlock;
CometASTNode* exceptionType;
CometASTNode* exceptionVarName;
} AST_TRY_STATEMENT;
struct AST_THROW_STATEMENT {
CometASTNode* newStmt;

View File

@@ -111,6 +111,31 @@ char* typeToString(CometType type) {
return buffer;
}
case COMET_STRUCT: {
/*size_t buffSize = 256;
char* buffer = malloc(buffSize);
if (!buffer)
return NULL;
CometType* fieldTypes = type.structType->fieldTypes;
uint32_t fieldCount = type.structType->fieldCount;
int written = 0;
int remaining = buffSize - written;
written += snprintf(buffer + written, remaining, "%s - { ", type.structType->name);
for (uint32_t i = 0; i < fieldCount; i++) {
if (i < fieldCount - 1) {
written += snprintf(buffer + written, remaining, "%s, ", typeToString(fieldTypes[i]));
} else {
written += snprintf(buffer + written, remaining, "%s }", typeToString(fieldTypes[i]));
}
}*/
return type.structType->name;
}
default: return "unkown";
}
}
@@ -637,7 +662,7 @@ ResultType(CometType, ErrorMessage) getType(CometCompiler* c, CometASTNode* type
// get base type
CometType* baseType = malloc(sizeof(CometType));
List(CometTypeMapEntry) typeMap = c->typeMap;
char* baseTypeName = type.baseType->data.AST_IDENTIFIER.ident;
@@ -1243,7 +1268,7 @@ ResultType(CometType, ErrorMessage) resolveType(CometCompiler* c, CometASTNode*
ResultType(CometType, ErrorMessage) siblingResolved = resolveType(c, siblingElem);
if (siblingResolved.error) return siblingResolved;
if (!typesAreEqual(firstType, siblingResolved.as.success)) {
if (!typesAreEqual(siblingResolved.as.success, firstType)) {
Estr helpMsg = CREATE_ESTR("You're trying to mix the types ");
APPEND_ESTR(helpMsg, typeToString(firstType))
APPEND_ESTR(helpMsg, " and ")
@@ -1571,7 +1596,7 @@ ResultType(CometOperand, ErrorMessage) visitAssignStatement(CometCompiler* c, Co
if (exprResult.error)
return exprResult;
if (!typesAreEqual(varType.as.success, exprType.as.success) && !canImplicitCastType(varType.as.success, exprType.as.success)) {
if (!typesAreEqual(exprType.as.success, varType.as.success) && !canImplicitCastType(varType.as.success, exprType.as.success)) {
CometType castOut = buildCast(c, exprType.as.success, varType.as.success);
@@ -2536,6 +2561,7 @@ ResultType(CometOperand, ErrorMessage) visitConstructorDefStatement(CometCompile
argTypes[argTypeIdx+1] = argType.as.success;
}
argTypes[0] = structType;
buildFunction(c, constructorName, constDef.args.count + 1, structType, argTypes, false, true, false, -1); // add 1 arg for self
@@ -2708,6 +2734,7 @@ ResultType(CometOperand, ErrorMessage) visitStructDefStatement(CometCompiler* c,
char* structName = structDef.ident->data.AST_IDENTIFIER.ident;
structType->name = structName;
structType->parent = NULL;
@@ -2750,6 +2777,8 @@ ResultType(CometOperand, ErrorMessage) visitStructDefStatement(CometCompiler* c,
// add parent field count
parentFieldCount = parentStruct->fieldCount;
parentMethodCount = parentStruct->numMethods;
structType->parent = parentStruct;
}
// fill in fieldDefs
@@ -3157,7 +3186,29 @@ ResultType(CometOperand, ErrorMessage) visitTryStatement(CometCompiler* c, Comet
if (exceptionType.error)
return Error(CometOperand, ErrorMessage, exceptionType.as.error);
uint32_t idx = defineVar(c->env, "e", RECORD_LOCAL, NO_OPERAND, exceptionType.as.success, false);
CometASTNode* exceptionVarNameNode = node->data.AST_TRY_STATEMENT.exceptionVarName;
char* exceptionVarName = exceptionVarNameNode->data.AST_IDENTIFIER.ident;
Record* existingVar = lookup(c->env, exceptionVarName);
if (existingVar) {
Estr buffer = CREATE_ESTR("Redefinition of \"");
APPEND_ESTR(buffer, exceptionVarName);
APPEND_ESTR(buffer, "\"")
ErrorMessage errMsg = createError(
c->inputFilePath,
c->sourceCode,
"VariableRedefinition",
buffer.str,
NULL,
exceptionVarNameNode->lineNum,
exceptionVarNameNode->startCol,
exceptionVarNameNode->endCol
);
return Error(CometOperand, ErrorMessage, errMsg);
}
uint32_t idx = defineVar(c->env, exceptionVarName, RECORD_LOCAL, NO_OPERAND, exceptionType.as.success, false);
buildStore(c, idx);
ResultType(CometOperand, ErrorMessage) exceptBody = compile(c, node->data.AST_TRY_STATEMENT.exceptBlock);

View File

@@ -12,6 +12,15 @@ bool typesAreEqual(CometType a, CometType b) {
}
if (a.typeKind == COMET_STRUCT) {
if (a.structType->parent != NULL) {
CometType parentType = {
.typeKind = COMET_STRUCT,
.structType = a.structType->parent
};
return typesAreEqual(parentType, b);
}
return a.structType == b.structType;
}

View File

@@ -1630,9 +1630,11 @@ ResultType(astNodePtr, ErrorMessage) parseStructDefStatement(CometParser* parser
if (expectParentName.error)
return Error(astNodePtr, ErrorMessage, expectParentName.as.error);
parentName = AST_NODE(AST_IDENTIFIER, parser->currentToken->lineNum, parser->currentToken->value.literal);
parentName->startCol = parser->currentToken->startCol;
parentName->endCol = parser->currentToken->endCol;
ResultType(astNodePtr, ErrorMessage) parentNameResult = parseType(parser);
if (parentNameResult.error)
return parentNameResult;
parentName = parentNameResult.as.success;
}
List(astNodePtr) fieldDefs = newList(astNodePtr);
@@ -1801,11 +1803,19 @@ ResultType(astNodePtr, ErrorMessage) parseTryStatement(CometParser* parser) {
if (exceptionType.error)
return exceptionType;
ResultType(int, ErrorMessage) expectVarName = expectPeek(parser, CT_IDENT);
if (expectVarName.error)
return Error(astNodePtr, ErrorMessage, expectVarName.as.error);
ResultType(astNodePtr, ErrorMessage) exceptionVarName = parseIdentifier(parser);
if (exceptionVarName.error)
return exceptionVarName;
ResultType(astNodePtr, ErrorMessage) exceptBlock = parseOptionalBlockStatement(parser);
if (tryBlock.error)
return tryBlock;
CometASTNode* stmt = AST_NODE(AST_TRY_STATEMENT, lineNumber, tryBlock.as.success, exceptBlock.as.success, exceptionType.as.success);
CometASTNode* stmt = AST_NODE(AST_TRY_STATEMENT, lineNumber, tryBlock.as.success, exceptBlock.as.success, exceptionType.as.success, exceptionVarName.as.success);
stmt->startCol = startCol;
stmt->endCol = parser->currentToken->endCol;

View File

@@ -10,11 +10,17 @@ struct Exception {
}
}
struct EpicFail : Exception {
init() {
super(self, "EpicFail", "you did an epic fail")
}
}
func main() -> int {
try {
throw new Exception("Exception", "If you see this, we threw an exception!!")
} except Exception {
io.println("error: %s", e.message)
throw new EpicFail()
} except Exception e {
io.println("%s: %s", e.type, e.message)
}
return 0