Fucking add else statement

This commit is contained in:
Mid 2025-08-14 18:22:31 +03:00
parent 5755e243a9
commit 5196026ed1
7 changed files with 115 additions and 46 deletions

View File

@ -50,8 +50,7 @@ loop {
}
codePtr = codePtr + 1;
}
}
if(data[dataPtr] != 0) {
} else {
stckPtr = stckPtr + 1;
stck[stckPtr] = codePtr;
}
@ -62,8 +61,7 @@ loop {
if(code[codePtr] == 93) {
if(data[dataPtr] == 0) {
stckPtr = stckPtr - 1;
}
if(data[dataPtr] != 0) {
} else {
codePtr = stck[stckPtr];
}
}
@ -72,4 +70,4 @@ loop {
}
codePtr = codePtr + 1;
}
}

View File

@ -2,4 +2,6 @@ u16 x: 5;
if(x != 0) {
x = 2;
} else {
x = 5;
}

137
src/ast.c
View File

@ -34,6 +34,9 @@ void generic_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *tlc, v
} else if(n->nodeKind == AST_STMT_IF) {
generic_visitor(&n->stmtIf.expression, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
generic_visitor(&n->stmtIf.then, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
if(n->stmtIf.elss) {
generic_visitor(&n->stmtIf.elss, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
}
} else if(n->nodeKind == AST_STMT_LOOP) {
generic_visitor(&n->stmtLoop.body, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
} else if(n->nodeKind == AST_STMT_BREAK) {
@ -143,6 +146,13 @@ int ast_stmt_is_after(const AST *chunk, const AST *s1, const AST *s2) {
if(i == 1 || (i == 0 && s1 != NULL)) {
return i;
}
if(s->stmtIf.elss) {
i = ast_stmt_is_after(s->stmtIf.elss, s1, s2);
if(i == 1 || (i == 0 && s1 != NULL)) {
return i;
}
}
}
s = s->statement.next;
@ -656,7 +666,14 @@ static char *ast_dumps(AST *tlc, AST *s) {
} else if(s->nodeKind == AST_STMT_IF) {
char *cond = ast_dumpe(tlc, s->stmtIf.expression);
char *inner = ast_dumpc(tlc, s->stmtIf.then);
char *c = malp("if(%s) {\n%s}", cond, inner);
char *elss = s->stmtIf.elss ? ast_dumpc(tlc, s->stmtIf.elss) : NULL;
char *c;
if(elss) {
c = malp("if(%s) {\n%s} else {\n%s}", cond, inner, elss);
free(elss);
} else {
c = malp("if(%s) {\n%s}", cond, inner);
}
free(cond);
free(inner);
return c;
@ -1098,6 +1115,21 @@ void ast_segmented_dereference(AST *tlc) {
generic_visitor(&tlc, NULL, NULL, tlc, tlc, tlc, ast_segmented_dereference_visitor, NULL);
}
static void ast_patch_in_chunk(AST *chunkOuter, AST *stmtBefore, AST *chunkInner, AST *stmtAfter) {
if(chunkInner->chunk.statementFirst) {
stmtBefore->statement.next = chunkInner->chunk.statementFirst;
for(AST *z = chunkInner->chunk.statementFirst; z; z = z->statement.next) {
if(!z->statement.next) {
z->statement.next = stmtAfter;
break;
}
}
} else {
stmtBefore->statement.next = stmtAfter;
}
}
#define LOOPSTACKSIZE 64
struct LinearizeState {
size_t currentDepth;
@ -1113,38 +1145,69 @@ static void ast_linearize_visitor_pre(AST **aptr, AST *stmt, AST *stmtPrev, AST
AST *a = *aptr;
if(a->nodeKind == AST_STMT_IF) {
ASTExprUnaryOp *notcond = calloc(1, sizeof(*notcond));
notcond->nodeKind = AST_EXPR_UNARY_OP;
notcond->operator = UNOP_NOT;
notcond->operand = a->stmtIf.expression;
notcond->type = a->stmtIf.expression->expression.type;
ASTStmtJump *jump = calloc(1, sizeof(ASTStmtJump));
jump->nodeKind = AST_STMT_JUMP;
jump->condition = (AST*) notcond;
jump->label = malp("$Lin%lu", nextLabelIdx++);
ASTStmtLabel *label = calloc(1, sizeof(ASTStmtLabel));
label->nodeKind = AST_STMT_LABEL;
label->name = strdup(jump->label);
if(stmtPrev) {
stmtPrev->statement.next = (AST*) jump;
} else {
chunk->chunk.statementFirst = (AST*) jump;
}
if(a->stmtIf.then->chunk.statementFirst) {
jump->next = a->stmtIf.then->chunk.statementFirst;
for(AST *z = a->stmtIf.then->chunk.statementFirst; z; z = z->statement.next) {
if(!z->statement.next) {
z->statement.next = (AST*) label;
break;
}
if(a->stmtIf.elss == NULL) {
ASTExprUnaryOp *notcond = calloc(1, sizeof(*notcond));
notcond->nodeKind = AST_EXPR_UNARY_OP;
notcond->operator = UNOP_NOT;
notcond->operand = a->stmtIf.expression;
notcond->type = a->stmtIf.expression->expression.type;
ASTStmtJump *jump = calloc(1, sizeof(ASTStmtJump));
jump->nodeKind = AST_STMT_JUMP;
jump->condition = (AST*) notcond;
jump->label = malp("$Lin%lu", nextLabelIdx++);
ASTStmtLabel *label = calloc(1, sizeof(ASTStmtLabel));
label->nodeKind = AST_STMT_LABEL;
label->name = strdup(jump->label);
if(stmtPrev) {
stmtPrev->statement.next = (AST*) jump;
} else {
chunk->chunk.statementFirst = (AST*) jump;
}
ast_patch_in_chunk(chunk, (AST*) jump, a->stmtIf.then, (AST*) label);
label->next = a->statement.next;
} else {
jump->next = (AST*) label;
ASTExprUnaryOp *notcond = calloc(1, sizeof(*notcond));
notcond->nodeKind = AST_EXPR_UNARY_OP;
notcond->operator = UNOP_NOT;
notcond->operand = a->stmtIf.expression;
notcond->type = a->stmtIf.expression->expression.type;
ASTStmtJump *jump2Else = calloc(1, sizeof(ASTStmtJump));
jump2Else->nodeKind = AST_STMT_JUMP;
jump2Else->condition = (AST*) notcond;
jump2Else->label = malp("$Lin%lu", nextLabelIdx++);
ASTStmtJump *jump2End = calloc(1, sizeof(ASTStmtJump));
jump2End->nodeKind = AST_STMT_JUMP;
jump2End->label = malp("$Lin%lu", nextLabelIdx++);
ASTStmtLabel *labelElse = calloc(1, sizeof(ASTStmtLabel));
labelElse->nodeKind = AST_STMT_LABEL;
labelElse->name = strdup(jump2Else->label);
ASTStmtLabel *labelEnd = calloc(1, sizeof(ASTStmtLabel));
labelEnd->nodeKind = AST_STMT_LABEL;
labelEnd->name = strdup(jump2End->label);
if(stmtPrev) {
stmtPrev->statement.next = (AST*) jump2Else;
} else {
chunk->chunk.statementFirst = (AST*) jump2Else;
}
ast_patch_in_chunk(chunk, (AST*) jump2Else, a->stmtIf.then, (AST*) jump2End);
jump2End->next = (AST*) labelElse;
ast_patch_in_chunk(chunk, (AST*) labelElse, a->stmtIf.elss, (AST*) labelEnd);
labelEnd->next = a->statement.next;
}
label->next = a->statement.next;
} else if(a->nodeKind == AST_STMT_LOOP) {
size_t startIdx = nextLabelIdx++;
size_t endIdx = nextLabelIdx++;
@ -1167,17 +1230,9 @@ static void ast_linearize_visitor_pre(AST **aptr, AST *stmt, AST *stmtPrev, AST
} else {
chunk->chunk.statementFirst = (AST*) startLabel;
}
if(a->stmtLoop.body->chunk.statementFirst) {
startLabel->next = a->stmtLoop.body->chunk.statementFirst;
for(AST *z = a->stmtLoop.body->chunk.statementFirst; z; z = z->statement.next) {
if(!z->statement.next) {
z->statement.next = (AST*) jump;
break;
}
}
} else {
startLabel->next = (AST*) jump;
}
ast_patch_in_chunk(chunk, (AST*) startLabel, a->stmtLoop.body, (AST*) jump);
jump->next = (AST*) endLabel;
endLabel->next = a->statement.next;

View File

@ -225,6 +225,7 @@ typedef struct {
union AST *expression;
union AST *then;
union AST *elss;
} ASTStmtIf;
typedef struct {

View File

@ -49,6 +49,7 @@ char *TOKEN_NAMES[] = {
"'.'",
"'as'",
"'use'",
"'else'",
};
static int isAlpha(int c) {
@ -296,6 +297,10 @@ Token nct_tokenize(FILE *f) {
free(content);
tok.type = TOKEN_USE;
return tok;
} else if(!strcmp(content, "else")) {
free(content);
tok.type = TOKEN_ELSE;
return tok;
}
tok.type = TOKEN_IDENTIFIER;

View File

@ -49,6 +49,7 @@ typedef enum {
TOKEN_DOT,
TOKEN_AS,
TOKEN_USE,
TOKEN_ELSE,
} TokenKind;
typedef struct Token {

View File

@ -1095,6 +1095,13 @@ static void nct_parse_statement(Parser *P) {
expect(P, TOKEN_SQUIGGLY_L);
ret->then = (AST*) nct_parse_chunk(P, 0, 0, NULL, NULL);
expect(P, TOKEN_SQUIGGLY_R);
if(maybe(P, TOKEN_ELSE)) {
expect(P, TOKEN_SQUIGGLY_L);
ret->elss = (AST*) nct_parse_chunk(P, 0, 0, NULL, NULL);
expect(P, TOKEN_SQUIGGLY_R);
}
return;
} else if(maybe(P, TOKEN_LOOP)) {
ASTStmtLoop *ret = alloc_node(P, sizeof(*ret));