Call pointers only

This commit is contained in:
Mid 2025-07-29 17:48:31 +03:00
parent 5455e1cebb
commit fb4849d382
4 changed files with 26 additions and 13 deletions

View File

@ -57,7 +57,7 @@ void generic_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *tlc, v
} else if(n->nodeKind == AST_EXPR_CALL) {
generic_visitor(&n->exprCall.what, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
for(size_t i = 0; i < n->exprCall.what->expression.type->function.argCount; i++) {
for(size_t i = 0; i < n->exprCall.what->expression.type->pointer.of->function.argCount; i++) {
generic_visitor(&n->exprCall.args[i], stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
}
} else if(n->nodeKind == AST_EXPR_CAST) {
@ -421,7 +421,7 @@ static void ast_usedef_pass(struct UsedefPassState *state, AST *tlc, AST *a, AST
} else if(a->nodeKind == AST_EXPR_CALL) {
ast_usedef_pass(state, tlc, a->exprCall.what, wholestmt);
for(size_t p = 0; p < a->exprCall.what->expression.type->function.argCount; p++) {
for(size_t p = 0; p < a->exprCall.what->expression.type->pointer.of->function.argCount; p++) {
ast_usedef_pass(state, tlc, a->exprCall.args[p], wholestmt);
}
} else if(a->nodeKind == AST_EXPR_PRIMITIVE) {
@ -698,7 +698,7 @@ static char *ast_dumpe(AST *tlc, AST *e) {
char *w = ast_dumpe(tlc, e->exprCall.what);
char *out = malp("%s(", w);
free(w);
size_t argCount = e->exprCall.what->expression.type->function.argCount;
size_t argCount = e->exprCall.what->expression.type->pointer.of->function.argCount;
for(size_t i = 0; i < argCount; i++) {
char *a = ast_dumpe(tlc, e->exprCall.args[i]);
char *out2 = malp(i == argCount - 1 ? "%s%s)" : "%s%s, ", out, a);

View File

@ -406,13 +406,24 @@ AST *nct_parse_expression(Parser *P, int lOP) {
while(peek(P, 0).type == TOKEN_PAREN_L || peek(P, 0).type == TOKEN_SQUAREN_L) {
if(maybe(P, TOKEN_PAREN_L)) {
if(ret->expression.type->type != TYPE_TYPE_FUNCTION) {
stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Only function types may be called.");
if(ret->expression.type->type == TYPE_TYPE_FUNCTION) {
ASTExprUnaryOp *ref = alloc_node(P, sizeof(*ref));
ref->nodeKind = AST_EXPR_UNARY_OP;
ref->type = type_pointer_wrap(ret->expression.type);
ref->operator = UNOP_REF;
ref->operand = ret;
ret = (AST*) ref;
}
if(ret->expression.type->type != TYPE_TYPE_POINTER || ret->expression.type->pointer.of->type != TYPE_TYPE_FUNCTION) {
stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Only function types or function pointers may be called.");
}
Type *ftype = ret->expression.type->pointer.of;
ASTExprCall *call = alloc_node(P, sizeof(*call));
call->nodeKind = AST_EXPR_CALL;
call->type = ret->expression.type->function.ret;
call->type = ftype->function.ret;
call->what = ret;
call->args = NULL;
@ -421,7 +432,7 @@ AST *nct_parse_expression(Parser *P, int lOP) {
if(!maybe(P, TOKEN_PAREN_R)) {
while(peek(P, 0).type != TOKEN_PAREN_R && peek(P, 0).type != TOKEN_COMMA) {
call->args = realloc(call->args, (argCount + 1) * sizeof(AST*));
call->args[argCount] = ast_cast_expr(nct_parse_expression(P, 0), ret->expression.type->function.args[argCount]);
call->args[argCount] = ast_cast_expr(nct_parse_expression(P, 0), ftype->function.args[argCount]);
argCount++;
@ -431,7 +442,7 @@ AST *nct_parse_expression(Parser *P, int lOP) {
}
}
if(argCount != call->what->expression.type->function.argCount) {
if(argCount != ftype->function.argCount) {
stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Mismatched number of arguments");
}

View File

@ -322,7 +322,7 @@ void cg_chunk(CGState *cg, AST *a) {
puts("push ecx");
puts("push edx");
int argCount = e->exprCall.what->expression.type->function.argCount;
int argCount = e->exprCall.what->expression.type->pointer.of->function.argCount;
size_t argSize = 0;
@ -332,9 +332,11 @@ void cg_chunk(CGState *cg, AST *a) {
argSize += (type_size(e->exprCall.args[i]->expression.type) + 3) & ~3;
}
assert(e->exprCall.what->nodeKind == AST_EXPR_VAR && e->exprCall.what->exprVar.thing->kind == SCOPEITEM_SYMBOL);
if(e->exprCall.what->nodeKind == AST_EXPR_VAR && e->exprCall.what->exprVar.thing->kind == SCOPEITEM_SYMBOL) {
printf("call %s\n", e->exprCall.what->exprVar.thing->data.symbol.name);
} else {
printf("call %s\n", xop(cg->tlc, e->exprCall.what));
}
if(argSize) printf("add esp, %lu\n", argSize);

View File

@ -215,7 +215,7 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *
} else if(s->stmtAssign.what && s->stmtAssign.what->nodeKind == AST_EXPR_VAR && s->stmtAssign.what->exprVar.thing->kind == SCOPEITEM_VAR && s->stmtAssign.to->nodeKind == AST_EXPR_CALL) {
ASTExprCall *call = &s->stmtAssign.to->exprCall;
int argCount = call->what->expression.type->function.argCount;
int argCount = call->what->expression.type->pointer.of->function.argCount;
for(int i = 0; i < argCount; i++) {
if(is_xop(call->args[i]) == XOP_NOT_XOP) {