Fucking add else statement
This commit is contained in:
parent
5755e243a9
commit
5196026ed1
@ -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];
|
||||
}
|
||||
}
|
||||
|
@ -2,4 +2,6 @@ u16 x: 5;
|
||||
|
||||
if(x != 0) {
|
||||
x = 2;
|
||||
} else {
|
||||
x = 5;
|
||||
}
|
||||
|
101
src/ast.c
101
src/ast.c
@ -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,6 +1145,7 @@ static void ast_linearize_visitor_pre(AST **aptr, AST *stmt, AST *stmtPrev, AST
|
||||
AST *a = *aptr;
|
||||
|
||||
if(a->nodeKind == AST_STMT_IF) {
|
||||
if(a->stmtIf.elss == NULL) {
|
||||
ASTExprUnaryOp *notcond = calloc(1, sizeof(*notcond));
|
||||
notcond->nodeKind = AST_EXPR_UNARY_OP;
|
||||
notcond->operator = UNOP_NOT;
|
||||
@ -1133,18 +1166,48 @@ static void ast_linearize_visitor_pre(AST **aptr, AST *stmt, AST *stmtPrev, AST
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
jump->next = (AST*) label;
|
||||
}
|
||||
|
||||
ast_patch_in_chunk(chunk, (AST*) jump, a->stmtIf.then, (AST*) label);
|
||||
|
||||
label->next = a->statement.next;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
} 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;
|
||||
|
||||
|
@ -225,6 +225,7 @@ typedef struct {
|
||||
union AST *expression;
|
||||
|
||||
union AST *then;
|
||||
union AST *elss;
|
||||
} ASTStmtIf;
|
||||
|
||||
typedef struct {
|
||||
|
@ -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;
|
||||
|
@ -49,6 +49,7 @@ typedef enum {
|
||||
TOKEN_DOT,
|
||||
TOKEN_AS,
|
||||
TOKEN_USE,
|
||||
TOKEN_ELSE,
|
||||
} TokenKind;
|
||||
|
||||
typedef struct Token {
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user