Rename dumbification to normalization

This commit is contained in:
Mid 2025-10-10 17:18:10 +03:00
parent fc8d65f893
commit 2d56f124a9
5 changed files with 37 additions and 35 deletions

View File

@ -57,7 +57,7 @@ static void spill2stack_visitor(AST **aptr, AST *stmt, AST *stmtPrev, AST *chunk
} else if(a->nodeKind == AST_EXPR_PRIMITIVE && a->exprPrim.stackGrowth) {
// Guaranteed to not require more dumbification
// Guaranteed to not require more normalization
a->exprPrim.val += this->stackGrowth;
}

View File

@ -102,11 +102,11 @@ int main(int argc_, char **argv_) {
ast_linearize(chunk);
dumben_pre(chunk);
arch_normalize_pre(chunk);
dumben_go(chunk);
arch_normalize(chunk);
while(!cg_go(chunk)) {
dumben_go(chunk);
arch_normalize(chunk);
}
return 0;

View File

@ -13,10 +13,11 @@ intmax_t ntc_get_int(const char *name);
intmax_t ntc_get_int_default(const char *name, intmax_t def);
union AST;
void arch_init();
bool arch_verify_target();
int arch_ptr_size();
void dumben_pre(union AST *tlc);
void dumben_go(union AST *tlc);
void arch_normalize_pre(union AST *tlc);
void arch_normalize(union AST *tlc);
int cg_go(union AST *tlc);
#endif

View File

@ -364,11 +364,11 @@ void cg_chunk(CGState *cg, AST *a) {
ast_linearize(s->stmtDecl.expression->exprFunc.chunk);
dumben_pre(s->stmtDecl.expression->exprFunc.chunk);
arch_normalize_pre(s->stmtDecl.expression->exprFunc.chunk);
dumben_go(s->stmtDecl.expression->exprFunc.chunk);
arch_normalize(s->stmtDecl.expression->exprFunc.chunk);
while(!cg_go(s->stmtDecl.expression->exprFunc.chunk)) {
dumben_go(s->stmtDecl.expression->exprFunc.chunk);
arch_normalize(s->stmtDecl.expression->exprFunc.chunk);
}
}

View File

@ -6,22 +6,20 @@
#include"reporting.h"
#include"utils.h"
// This is the dumbing down pass.
//
// Complex expressions are to be "broken down" into simpler ones until the AST
// can be trivially translated to the target architecture.
//
// This file along with CG is strictly for IA-32 and will fail for other
// architectures.
// This is the normalization pass:
// Complex expressions are to be "broken down" into simpler ones until
// the AST can be trivially translated to the target architecture.
// This file along with CG is strictly for IA-32 & IA-16 and will fail
// for other architectures.
static ScopeItem *create_dumbtemp(AST *tlc, Type *itstype) {
static ScopeItem *create_temp(AST *tlc, Type *itstype) {
static size_t vidx = 0;
return ast_tlc_new_var(tlc, malp("$dumb%lu", vidx++), itstype);
return ast_tlc_new_var(tlc, malp("nrm%lu", vidx++), itstype);
}
/* Split away complex expression into a new local variable */
static AST *varify(AST *tlc, AST *chunk, AST *stmtPrev, AST *stmt, AST *e) {
ScopeItem *vte = create_dumbtemp(tlc, e->expression.type);
ScopeItem *vte = create_temp(tlc, e->expression.type);
// Alter AST
@ -101,12 +99,12 @@ static void mark_d(ScopeItem *si) {
* RULE ONE OF DUMBING: NEVER xopify NOR varify MORE THAN ONCE IN A SINGLE CALL TO VISITOR!!!
* IF YOU DO THIS, stmtPrev WILL FUCK UP AND STATEMENTS WILL BE LOST
*/
struct DumbenState {
struct NormState {
AST *targetTLC;
int effective;
};
static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *tlc, void *ud) {
struct DumbenState *this = ud;
static void normalize_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *tlc, void *ud) {
struct NormState *this = ud;
if(this->targetTLC != tlc) return;
@ -286,7 +284,7 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *
if(s->stmtAssign.to->nodeKind == AST_EXPR_CALL && (s->stmtAssign.what->nodeKind != AST_EXPR_VAR || s->stmtAssign.what->exprVar.thing->kind != SCOPEITEM_VAR || !s->stmtAssign.what->exprVar.thing->data.var.precolored)) {
ScopeItem *tmp = create_dumbtemp(tlc, s->stmtAssign.what->expression.type);
ScopeItem *tmp = create_temp(tlc, s->stmtAssign.what->expression.type);
mark_a(tmp);
ASTExprVar *ev[2] = {calloc(1, sizeof(**ev)), calloc(1, sizeof(**ev))};
@ -474,7 +472,7 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *
}
}
static void pre_dumb_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, AST *tlc, void *ud) {
static void pre_norm_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, AST *tlc, void *ud) {
AST *n = *nptr;
if(n == ud) {
@ -592,7 +590,7 @@ struct DenoopState {
static void denoop_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, AST *tlc, void *ud) {
struct DenoopState *state = ud;
// if(state->targetTLC != tlc) return;
if(state->targetTLC != tlc) return;
AST *n = *nptr;
@ -621,15 +619,16 @@ static void denoop_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, AST
n->exprCast.what = n->exprCast.what->exprCast.what;
*success = true;
} else if(n->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operands[0]->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operator == BINOP_ADD && n->exprBinOp.operands[0]->exprBinOp.operator == BINOP_ADD && n->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE && n->exprBinOp.operands[0]->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) {
} else if(n->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operands[0]->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operator == BINOP_ADD && n->exprBinOp.operands[0]->exprBinOp.operator == BINOP_ADD && n->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE && n->exprBinOp.operands[0]->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE && !(n->exprBinOp.operands[0]->exprBinOp.operands[1]->exprPrim.stackGrowth && n->exprBinOp.operands[1]->exprPrim.stackGrowth)) {
// Turn `(x + a) + b` into `x + (a + b)`
n->exprBinOp.operands[0]->exprBinOp.operands[1]->exprPrim.val += n->exprBinOp.operands[1]->exprPrim.val;
n->exprBinOp.operands[0]->exprBinOp.operands[1]->exprPrim.stackGrowth = n->exprBinOp.operands[0]->exprBinOp.operands[1]->exprPrim.stackGrowth || n->exprBinOp.operands[1]->exprPrim.stackGrowth;
*nptr = n->exprBinOp.operands[0];
*success = true;
} else if(n->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operator == BINOP_ADD && n->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE && n->exprBinOp.operands[1]->exprPrim.val == 0) {
} else if(n->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operator == BINOP_ADD && n->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE && n->exprBinOp.operands[1]->exprPrim.val == 0 && !n->exprBinOp.operands[1]->exprPrim.stackGrowth) {
// Turn `x + 0` into `x`
// Artificially change type of casted expression to keep types valid for subsequent passes
@ -661,22 +660,24 @@ static void denoop_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, AST
*nptr = n->exprCast.what;
*success = true;
} else if(n->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operator == BINOP_ADD && n->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && n->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) {
} else if(n->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operator == BINOP_ADD && n->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && n->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE && !(n->exprBinOp.operands[0]->exprPrim.stackGrowth && n->exprBinOp.operands[1]->exprPrim.stackGrowth)) {
// Constant propagation of + operator
AST *prim = n->exprBinOp.operands[0];
prim->expression.type = n->exprBinOp.type;
prim->exprPrim.val = n->exprBinOp.operands[0]->exprPrim.val + n->exprBinOp.operands[1]->exprPrim.val;
prim->exprPrim.stackGrowth = n->exprBinOp.operands[0]->exprPrim.stackGrowth || n->exprBinOp.operands[1]->exprPrim.stackGrowth;
*nptr = prim;
*success = true;
} else if(n->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operator == BINOP_SUB && n->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && n->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) {
} else if(n->nodeKind == AST_EXPR_BINARY_OP && n->exprBinOp.operator == BINOP_SUB && n->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && n->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE && !(n->exprBinOp.operands[0]->exprPrim.stackGrowth && n->exprBinOp.operands[1]->exprPrim.stackGrowth)) {
// Constant propagation of - operator
AST *prim = n->exprBinOp.operands[0];
prim->expression.type = n->exprBinOp.type;
prim->exprPrim.val = n->exprBinOp.operands[0]->exprPrim.val - n->exprBinOp.operands[1]->exprPrim.val;
prim->exprPrim.stackGrowth = n->exprBinOp.operands[0]->exprPrim.stackGrowth || n->exprBinOp.operands[1]->exprPrim.stackGrowth;
*nptr = prim;
@ -765,9 +766,9 @@ static void convention_correctness_visitor(AST **nptr, AST *stmt, AST *stmtPrev,
}
}
void dumben_pre(AST *tlc) {
void arch_normalize_pre(AST *tlc) {
generic_visitor(&tlc, NULL, NULL, tlc, tlc, tlc, convention_correctness_visitor, NULL);
generic_visitor(&tlc, NULL, NULL, tlc, tlc, tlc, pre_dumb_visitor, NULL);
generic_visitor(&tlc, NULL, NULL, tlc, tlc, tlc, pre_norm_visitor, NULL);
generic_visitor(&tlc, NULL, NULL, tlc, tlc, tlc, decompose_symbol_record_field_access, NULL);
for(size_t t = 0; t < tlc->chunk.varCount;) {
@ -783,16 +784,16 @@ void dumben_pre(AST *tlc) {
ast_commutativity_pass(tlc);
}
void dumben_go(AST* tlc) {
void arch_normalize(AST* tlc) {
size_t i = 0;
while(1) {
if(i == 20000) {
stahp(0, 0, "TOO MANY DUMBS. TOO MANY DUMBS.");
}
struct DumbenState state = {.targetTLC = tlc};
struct NormState state = {.targetTLC = tlc};
generic_visitor(&tlc, NULL, NULL, tlc, tlc, &state, dumben_visitor, NULL);
generic_visitor(&tlc, NULL, NULL, tlc, tlc, &state, normalize_visitor, NULL);
int successful = state.effective;
@ -801,7 +802,7 @@ void dumben_go(AST* tlc) {
}
if(ntc_get_int("pdbg")) {
fprintf(stderr, "### DUMBED DOWN %lu ###\n", i++);
fprintf(stderr, "### NORM %lu ###\n", i++);
char *astdump = ast_dump(tlc);
fputs(astdump, stderr);
free(astdump);