Add return statement

This commit is contained in:
Mid 2024-11-28 21:40:03 +02:00
parent 8caadf9af1
commit 390c4c954d
8 changed files with 109 additions and 7 deletions

View File

@ -309,6 +309,10 @@ static void ast_usedef_pass(AST *tlc, AST *a, AST *wholestmt) {
} else if(a->nodeKind == AST_STMT_EXT_SECTION) {
} else if(a->nodeKind == AST_STMT_DECL) {
assert(a->stmtDecl.thing->kind != VARTABLEENTRY_VAR || a->stmtDecl.expression);
} else if(a->nodeKind == AST_STMT_RETURN) {
if(a->stmtReturn.val) {
ast_usedef_pass(tlc, a->stmtReturn.val, wholestmt);
}
} else {
abort();
}
@ -447,6 +451,32 @@ static char *ast_dumpe(AST *e) {
return r;
} else if(e->nodeKind == AST_EXPR_STACK_POINTER) {
return malp("@stack");
} else if(e->nodeKind == AST_EXPR_FUNC) {
char *out = NULL;
{
char *rettype = type_to_string(e->expression.type->function.ret);
out = malp("%s(", rettype);
free(rettype);
}
for(int i = 0; i < e->expression.type->function.argCount; i++) {
char *argtype = type_to_string(e->expression.type->function.args[i]);
char *out2 = malp(i == e->expression.type->function.argCount - 1 ? "%s%s" : "%s%s, ", out, argtype);
free(out);
free(argtype);
out = out2;
}
{
char *choonk = ast_dump(e->exprFunc.chunk);
char *out2 = malp("%s) {\n%s}", out, choonk);
free(out);
free(choonk);
out = out2;
}
return out;
}
return malp("@unimp:%s", AST_KIND_STR[e->nodeKind]);
@ -495,6 +525,15 @@ static char *ast_dumps(AST *s) {
}
return malp("%s; /* loop guard */\n", name);
} else if(s->nodeKind == AST_STMT_RETURN) {
if(s->stmtReturn.val) {
char *e = ast_dumpe(s->stmtReturn.val);
char *c = malp("return %s;\n", e);
free(e);
return c;
} else {
return malp("return;\n");
}
}
return malp("@unimp:%s\n", AST_KIND_STR[s->nodeKind]);

View File

@ -44,7 +44,8 @@
K(AST_EXPR_ARRAY) \
K(AST_EXPR_FUNC) \
K(AST_STMT_EXT_ORG) \
K(AST_STMT_EXT_SECTION)
K(AST_STMT_EXT_SECTION) \
K(AST_STMT_RETURN)
typedef enum ENUMPAK { AST_KINDS(GEN_ENUM) } ASTKind;
extern const char *AST_KIND_STR[];
@ -256,6 +257,12 @@ typedef struct {
Token name;
} ASTStmtExtSection;
typedef struct {
ASTStmt;
union AST *val;
} ASTStmtReturn;
typedef union AST {
ASTKind nodeKind;
@ -268,6 +275,7 @@ typedef union AST {
ASTStmtContinue stmtContinue;
ASTStmtExpr stmtExpr;
ASTStmtAssign stmtAssign;
ASTStmtReturn stmtReturn;
ASTExpr expression;
ASTExprPrimitive exprPrim;
ASTExprBinaryOp exprBinOp;

View File

@ -343,7 +343,17 @@ void cg_chunk(CGState *cg, AST *a) {
printf(".L%lu:\n", lbl);
}
} else if(s->nodeKind == AST_STMT_RETURN) {
if(s->stmtReturn.val) {
assert(s->stmtReturn.val->nodeKind == AST_EXPR_VAR);
assert(s->stmtReturn.val->exprVar.thing->kind == VARTABLEENTRY_VAR);
assert(s->stmtReturn.val->exprVar.thing->data.var.color == COLOR_EAX);
}
printf("ret\n");
} else abort();
s = s->statement.next;
}

View File

@ -38,6 +38,7 @@ char *TOKEN_NAMES[] = {
"'!='",
"'!'",
"'continue'",
"'return'",
};
static int isAlpha(int c) {
@ -243,6 +244,10 @@ Token nct_tokenize(FILE *f) {
free(content);
tok.type = TOKEN_CONTINUE;
return tok;
} else if(!strcmp(content, "return")) {
free(content);
tok.type = TOKEN_RETURN;
return tok;
}
tok.type = TOKEN_IDENTIFIER;

View File

@ -38,6 +38,7 @@ typedef enum {
TOKEN_EXCLAMATION_EQUALS,
TOKEN_EXCLAMATION,
TOKEN_CONTINUE,
TOKEN_RETURN
} TokenKind;
typedef struct {

View File

@ -652,7 +652,8 @@ static AST *parse_declaration(Parser *P) {
Type *type = nct_parse_typename(P);
if(!type) goto backtrack;
if(!type && (peek(P, 0).type != TOKEN_IDENTIFIER || peek(P, 1).type != TOKEN_COLON)) goto backtrack;
if(peek(P, 0).type != TOKEN_IDENTIFIER) goto backtrack;
Token name = expect(P, TOKEN_IDENTIFIER);
@ -708,7 +709,13 @@ static AST *parse_declaration(Parser *P) {
entry->data.symbol.isExternal = isExternal;
entry->data.symbol.name = name.content;
decl->expression = nct_cast_expr(nct_parse_expression(P, 0), type);
decl->expression = nct_parse_expression(P, 0);
if(type) {
decl->expression = nct_cast_expr(decl->expression, type);
} else {
entry->type = decl->expression->expression.type;
}
if(decl->expression) {
//if(ret->expression->expression.constantType == EXPRESSION_NOT_CONSTANT) {
@ -810,6 +817,38 @@ void nct_parse_statement(Parser *P) {
pushstat(P, ret);
return;
} else if(maybe(P, TOKEN_RETURN)) {
ASTStmtReturn *ret = malloc(sizeof(*ret));
ret->nodeKind = AST_STMT_RETURN;
ret->next = NULL;
if(!maybe(P, TOKEN_SEMICOLON)) {
AST *expr = nct_parse_expression(P, 0);
VarTableEntry *tempo = calloc(1, sizeof(*tempo));
tempo->kind = VARTABLEENTRY_VAR;
tempo->type = expr->expression.type;
tempo->data.var.name = "$temp";
tempo->data.var.color = COLOR_EAX;
P->topLevel->vars = realloc(P->topLevel->vars, sizeof(*P->topLevel->vars) * (++P->topLevel->varCount));
P->topLevel->vars[P->topLevel->varCount - 1] = tempo;
ASTStmtAssign *assign = malloc(sizeof(*assign));
assign->nodeKind = AST_STMT_ASSIGN;
assign->what = exprvar(P, tempo);
assign->to = expr;
ret->val = exprvar(P, tempo);
pushstat(P, assign);
expect(P, TOKEN_SEMICOLON);
}
pushstat(P, ret);
return;
} else if(peek(P, 0).type == TOKEN_IDENTIFIER) {
if(!strcmp(peek(P, 0).content, "@align")) {

View File

@ -2,6 +2,6 @@
/* Oh and arguments aren't supported yet either */
/* But functions work :) */
u0() foo: u0() {
u8 a = 5;
foo: u0() {
return 15;
};

View File

@ -19,4 +19,4 @@ loop {}
u8[19] string: "Hello from Nectar!\0";
@align(510);
u16 bootsig: 16rAA55;
u16 bootsig: 16rAA55;