Fucking add else statement
This commit is contained in:
parent
5755e243a9
commit
5196026ed1
@ -50,8 +50,7 @@ loop {
|
|||||||
}
|
}
|
||||||
codePtr = codePtr + 1;
|
codePtr = codePtr + 1;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
if(data[dataPtr] != 0) {
|
|
||||||
stckPtr = stckPtr + 1;
|
stckPtr = stckPtr + 1;
|
||||||
stck[stckPtr] = codePtr;
|
stck[stckPtr] = codePtr;
|
||||||
}
|
}
|
||||||
@ -62,8 +61,7 @@ loop {
|
|||||||
if(code[codePtr] == 93) {
|
if(code[codePtr] == 93) {
|
||||||
if(data[dataPtr] == 0) {
|
if(data[dataPtr] == 0) {
|
||||||
stckPtr = stckPtr - 1;
|
stckPtr = stckPtr - 1;
|
||||||
}
|
} else {
|
||||||
if(data[dataPtr] != 0) {
|
|
||||||
codePtr = stck[stckPtr];
|
codePtr = stck[stckPtr];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,6 @@ u16 x: 5;
|
|||||||
|
|
||||||
if(x != 0) {
|
if(x != 0) {
|
||||||
x = 2;
|
x = 2;
|
||||||
|
} else {
|
||||||
|
x = 5;
|
||||||
}
|
}
|
||||||
|
131
src/ast.c
131
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) {
|
} else if(n->nodeKind == AST_STMT_IF) {
|
||||||
generic_visitor(&n->stmtIf.expression, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
|
generic_visitor(&n->stmtIf.expression, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
|
||||||
generic_visitor(&n->stmtIf.then, 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) {
|
} else if(n->nodeKind == AST_STMT_LOOP) {
|
||||||
generic_visitor(&n->stmtLoop.body, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
|
generic_visitor(&n->stmtLoop.body, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
|
||||||
} else if(n->nodeKind == AST_STMT_BREAK) {
|
} 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)) {
|
if(i == 1 || (i == 0 && s1 != NULL)) {
|
||||||
return i;
|
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;
|
s = s->statement.next;
|
||||||
@ -656,7 +666,14 @@ static char *ast_dumps(AST *tlc, AST *s) {
|
|||||||
} else if(s->nodeKind == AST_STMT_IF) {
|
} else if(s->nodeKind == AST_STMT_IF) {
|
||||||
char *cond = ast_dumpe(tlc, s->stmtIf.expression);
|
char *cond = ast_dumpe(tlc, s->stmtIf.expression);
|
||||||
char *inner = ast_dumpc(tlc, s->stmtIf.then);
|
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(cond);
|
||||||
free(inner);
|
free(inner);
|
||||||
return c;
|
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);
|
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
|
#define LOOPSTACKSIZE 64
|
||||||
struct LinearizeState {
|
struct LinearizeState {
|
||||||
size_t currentDepth;
|
size_t currentDepth;
|
||||||
@ -1113,38 +1145,69 @@ static void ast_linearize_visitor_pre(AST **aptr, AST *stmt, AST *stmtPrev, AST
|
|||||||
AST *a = *aptr;
|
AST *a = *aptr;
|
||||||
|
|
||||||
if(a->nodeKind == AST_STMT_IF) {
|
if(a->nodeKind == AST_STMT_IF) {
|
||||||
ASTExprUnaryOp *notcond = calloc(1, sizeof(*notcond));
|
if(a->stmtIf.elss == NULL) {
|
||||||
notcond->nodeKind = AST_EXPR_UNARY_OP;
|
ASTExprUnaryOp *notcond = calloc(1, sizeof(*notcond));
|
||||||
notcond->operator = UNOP_NOT;
|
notcond->nodeKind = AST_EXPR_UNARY_OP;
|
||||||
notcond->operand = a->stmtIf.expression;
|
notcond->operator = UNOP_NOT;
|
||||||
notcond->type = a->stmtIf.expression->expression.type;
|
notcond->operand = a->stmtIf.expression;
|
||||||
|
notcond->type = a->stmtIf.expression->expression.type;
|
||||||
|
|
||||||
ASTStmtJump *jump = calloc(1, sizeof(ASTStmtJump));
|
ASTStmtJump *jump = calloc(1, sizeof(ASTStmtJump));
|
||||||
jump->nodeKind = AST_STMT_JUMP;
|
jump->nodeKind = AST_STMT_JUMP;
|
||||||
jump->condition = (AST*) notcond;
|
jump->condition = (AST*) notcond;
|
||||||
jump->label = malp("$Lin%lu", nextLabelIdx++);
|
jump->label = malp("$Lin%lu", nextLabelIdx++);
|
||||||
|
|
||||||
ASTStmtLabel *label = calloc(1, sizeof(ASTStmtLabel));
|
ASTStmtLabel *label = calloc(1, sizeof(ASTStmtLabel));
|
||||||
label->nodeKind = AST_STMT_LABEL;
|
label->nodeKind = AST_STMT_LABEL;
|
||||||
label->name = strdup(jump->label);
|
label->name = strdup(jump->label);
|
||||||
|
|
||||||
if(stmtPrev) {
|
if(stmtPrev) {
|
||||||
stmtPrev->statement.next = (AST*) jump;
|
stmtPrev->statement.next = (AST*) jump;
|
||||||
} else {
|
} else {
|
||||||
chunk->chunk.statementFirst = (AST*) jump;
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast_patch_in_chunk(chunk, (AST*) jump, a->stmtIf.then, (AST*) label);
|
||||||
|
|
||||||
|
label->next = a->statement.next;
|
||||||
} else {
|
} 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) {
|
} else if(a->nodeKind == AST_STMT_LOOP) {
|
||||||
size_t startIdx = nextLabelIdx++;
|
size_t startIdx = nextLabelIdx++;
|
||||||
size_t endIdx = nextLabelIdx++;
|
size_t endIdx = nextLabelIdx++;
|
||||||
@ -1167,17 +1230,9 @@ static void ast_linearize_visitor_pre(AST **aptr, AST *stmt, AST *stmtPrev, AST
|
|||||||
} else {
|
} else {
|
||||||
chunk->chunk.statementFirst = (AST*) startLabel;
|
chunk->chunk.statementFirst = (AST*) startLabel;
|
||||||
}
|
}
|
||||||
if(a->stmtLoop.body->chunk.statementFirst) {
|
|
||||||
startLabel->next = a->stmtLoop.body->chunk.statementFirst;
|
ast_patch_in_chunk(chunk, (AST*) startLabel, a->stmtLoop.body, (AST*) jump);
|
||||||
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;
|
|
||||||
}
|
|
||||||
jump->next = (AST*) endLabel;
|
jump->next = (AST*) endLabel;
|
||||||
endLabel->next = a->statement.next;
|
endLabel->next = a->statement.next;
|
||||||
|
|
||||||
|
@ -225,6 +225,7 @@ typedef struct {
|
|||||||
union AST *expression;
|
union AST *expression;
|
||||||
|
|
||||||
union AST *then;
|
union AST *then;
|
||||||
|
union AST *elss;
|
||||||
} ASTStmtIf;
|
} ASTStmtIf;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -49,6 +49,7 @@ char *TOKEN_NAMES[] = {
|
|||||||
"'.'",
|
"'.'",
|
||||||
"'as'",
|
"'as'",
|
||||||
"'use'",
|
"'use'",
|
||||||
|
"'else'",
|
||||||
};
|
};
|
||||||
|
|
||||||
static int isAlpha(int c) {
|
static int isAlpha(int c) {
|
||||||
@ -296,6 +297,10 @@ Token nct_tokenize(FILE *f) {
|
|||||||
free(content);
|
free(content);
|
||||||
tok.type = TOKEN_USE;
|
tok.type = TOKEN_USE;
|
||||||
return tok;
|
return tok;
|
||||||
|
} else if(!strcmp(content, "else")) {
|
||||||
|
free(content);
|
||||||
|
tok.type = TOKEN_ELSE;
|
||||||
|
return tok;
|
||||||
}
|
}
|
||||||
|
|
||||||
tok.type = TOKEN_IDENTIFIER;
|
tok.type = TOKEN_IDENTIFIER;
|
||||||
|
@ -49,6 +49,7 @@ typedef enum {
|
|||||||
TOKEN_DOT,
|
TOKEN_DOT,
|
||||||
TOKEN_AS,
|
TOKEN_AS,
|
||||||
TOKEN_USE,
|
TOKEN_USE,
|
||||||
|
TOKEN_ELSE,
|
||||||
} TokenKind;
|
} TokenKind;
|
||||||
|
|
||||||
typedef struct Token {
|
typedef struct Token {
|
||||||
|
@ -1095,6 +1095,13 @@ static void nct_parse_statement(Parser *P) {
|
|||||||
expect(P, TOKEN_SQUIGGLY_L);
|
expect(P, TOKEN_SQUIGGLY_L);
|
||||||
ret->then = (AST*) nct_parse_chunk(P, 0, 0, NULL, NULL);
|
ret->then = (AST*) nct_parse_chunk(P, 0, 0, NULL, NULL);
|
||||||
expect(P, TOKEN_SQUIGGLY_R);
|
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;
|
return;
|
||||||
} else if(maybe(P, TOKEN_LOOP)) {
|
} else if(maybe(P, TOKEN_LOOP)) {
|
||||||
ASTStmtLoop *ret = alloc_node(P, sizeof(*ret));
|
ASTStmtLoop *ret = alloc_node(P, sizeof(*ret));
|
||||||
|
Loading…
Reference in New Issue
Block a user