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) { } 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; a->exprPrim.val += this->stackGrowth;
} }

View File

@ -102,11 +102,11 @@ int main(int argc_, char **argv_) {
ast_linearize(chunk); ast_linearize(chunk);
dumben_pre(chunk); arch_normalize_pre(chunk);
dumben_go(chunk); arch_normalize(chunk);
while(!cg_go(chunk)) { while(!cg_go(chunk)) {
dumben_go(chunk); arch_normalize(chunk);
} }
return 0; 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); intmax_t ntc_get_int_default(const char *name, intmax_t def);
union AST; union AST;
void arch_init();
bool arch_verify_target(); bool arch_verify_target();
int arch_ptr_size(); int arch_ptr_size();
void dumben_pre(union AST *tlc); void arch_normalize_pre(union AST *tlc);
void dumben_go(union AST *tlc); void arch_normalize(union AST *tlc);
int cg_go(union AST *tlc); int cg_go(union AST *tlc);
#endif #endif

View File

@ -364,11 +364,11 @@ void cg_chunk(CGState *cg, AST *a) {
ast_linearize(s->stmtDecl.expression->exprFunc.chunk); 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)) { 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"reporting.h"
#include"utils.h" #include"utils.h"
// This is the dumbing down pass. // This is the normalization pass:
// // Complex expressions are to be "broken down" into simpler ones until
// Complex expressions are to be "broken down" into simpler ones until the AST // the AST can be trivially translated to the target architecture.
// 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.
// This file along with CG is strictly for IA-32 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; 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 */ /* Split away complex expression into a new local variable */
static AST *varify(AST *tlc, AST *chunk, AST *stmtPrev, AST *stmt, AST *e) { 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 // 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!!! * 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 * IF YOU DO THIS, stmtPrev WILL FUCK UP AND STATEMENTS WILL BE LOST
*/ */
struct DumbenState { struct NormState {
AST *targetTLC; AST *targetTLC;
int effective; int effective;
}; };
static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *tlc, void *ud) { static void normalize_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *tlc, void *ud) {
struct DumbenState *this = ud; struct NormState *this = ud;
if(this->targetTLC != tlc) return; 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)) { 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); mark_a(tmp);
ASTExprVar *ev[2] = {calloc(1, sizeof(**ev)), calloc(1, sizeof(**ev))}; 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; AST *n = *nptr;
if(n == ud) { 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) { static void denoop_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, AST *tlc, void *ud) {
struct DenoopState *state = ud; struct DenoopState *state = ud;
// if(state->targetTLC != tlc) return; if(state->targetTLC != tlc) return;
AST *n = *nptr; 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; n->exprCast.what = n->exprCast.what->exprCast.what;
*success = true; *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)` // 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.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]; *nptr = n->exprBinOp.operands[0];
*success = true; *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` // Turn `x + 0` into `x`
// Artificially change type of casted expression to keep types valid for subsequent passes // 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; *nptr = n->exprCast.what;
*success = true; *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 // Constant propagation of + operator
AST *prim = n->exprBinOp.operands[0]; AST *prim = n->exprBinOp.operands[0];
prim->expression.type = n->exprBinOp.type; prim->expression.type = n->exprBinOp.type;
prim->exprPrim.val = n->exprBinOp.operands[0]->exprPrim.val + n->exprBinOp.operands[1]->exprPrim.val; 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; *nptr = prim;
*success = true; *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 // Constant propagation of - operator
AST *prim = n->exprBinOp.operands[0]; AST *prim = n->exprBinOp.operands[0];
prim->expression.type = n->exprBinOp.type; prim->expression.type = n->exprBinOp.type;
prim->exprPrim.val = n->exprBinOp.operands[0]->exprPrim.val - n->exprBinOp.operands[1]->exprPrim.val; 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; *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, 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); generic_visitor(&tlc, NULL, NULL, tlc, tlc, tlc, decompose_symbol_record_field_access, NULL);
for(size_t t = 0; t < tlc->chunk.varCount;) { for(size_t t = 0; t < tlc->chunk.varCount;) {
@ -783,16 +784,16 @@ void dumben_pre(AST *tlc) {
ast_commutativity_pass(tlc); ast_commutativity_pass(tlc);
} }
void dumben_go(AST* tlc) { void arch_normalize(AST* tlc) {
size_t i = 0; size_t i = 0;
while(1) { while(1) {
if(i == 20000) { if(i == 20000) {
stahp(0, 0, "TOO MANY DUMBS. TOO MANY DUMBS."); 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; int successful = state.effective;
@ -801,7 +802,7 @@ void dumben_go(AST* tlc) {
} }
if(ntc_get_int("pdbg")) { if(ntc_get_int("pdbg")) {
fprintf(stderr, "### DUMBED DOWN %lu ###\n", i++); fprintf(stderr, "### NORM %lu ###\n", i++);
char *astdump = ast_dump(tlc); char *astdump = ast_dump(tlc);
fputs(astdump, stderr); fputs(astdump, stderr);
free(astdump); free(astdump);