Assemble ud-chain and use that for register allocation
This commit is contained in:
parent
62c5a0ff47
commit
5666568c1c
30
src/ast.c
30
src/ast.c
@ -30,4 +30,34 @@ int ast_expression_equal(AST *a, AST *b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... Ew
|
||||||
|
int ast_stmt_is_after(const AST *chunk, const AST *s1, const AST *s2) {
|
||||||
|
const AST *s = chunk->chunk.statementFirst;
|
||||||
|
|
||||||
|
while(s) {
|
||||||
|
if(s == s1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(s == s2) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(s->nodeKind == AST_STMT_IF) {
|
||||||
|
int i = ast_stmt_is_after(s->stmtIf.then, s1, s2);
|
||||||
|
if(i != -1) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
} else if(s->nodeKind == AST_STMT_LOOP) {
|
||||||
|
int i = ast_stmt_is_after(s->stmtLoop.body, s1, s2);
|
||||||
|
if(i != -1) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s = s->statement.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
@ -168,7 +168,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
ASTStmt;
|
ASTStmt;
|
||||||
|
|
||||||
ASTChunk *body;
|
union AST *body;
|
||||||
} ASTStmtLoop;
|
} ASTStmtLoop;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -254,4 +254,6 @@ typedef union AST {
|
|||||||
AST *ast_expression_optimize(AST*);
|
AST *ast_expression_optimize(AST*);
|
||||||
int ast_expression_equal(AST*, AST*);
|
int ast_expression_equal(AST*, AST*);
|
||||||
|
|
||||||
|
int ast_stmt_is_after(const AST *chunk, const AST *s1, const AST *s2);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
14
src/cg.c
14
src/cg.c
@ -99,6 +99,8 @@ static const char *xop(AST *e) {
|
|||||||
xv(e->exprUnOp.operand->exprBinOp.operands[1]->exprBinOp.operands[1]->exprVar.thing));
|
xv(e->exprUnOp.operand->exprBinOp.operands[1]->exprBinOp.operands[1]->exprVar.thing));
|
||||||
} else if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_REF && e->exprUnOp.operand->nodeKind == AST_EXPR_VAR && e->exprUnOp.operand->exprVar.thing->kind == VARTABLEENTRY_SYMBOL) {
|
} else if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_REF && e->exprUnOp.operand->nodeKind == AST_EXPR_VAR && e->exprUnOp.operand->exprVar.thing->kind == VARTABLEENTRY_SYMBOL) {
|
||||||
snprintf(ret, XOPBUFSZ, "%s", e->exprUnOp.operand->exprVar.thing->data.symbol.name);
|
snprintf(ret, XOPBUFSZ, "%s", e->exprUnOp.operand->exprVar.thing->data.symbol.name);
|
||||||
|
} else if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_DEREF && e->exprUnOp.operand->nodeKind == AST_EXPR_VAR && e->exprUnOp.operand->exprVar.thing->kind == VARTABLEENTRY_VAR) {
|
||||||
|
snprintf(ret, XOPBUFSZ, "[%s]", xv(e->exprUnOp.operand->exprVar.thing));
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -265,9 +267,15 @@ void cg_go(AST *a) {
|
|||||||
VarTableEntry *v2 = vars[v2i];
|
VarTableEntry *v2 = vars[v2i];
|
||||||
|
|
||||||
/* 1D intersection test */
|
/* 1D intersection test */
|
||||||
if((v1->data.var.start >= v2->data.var.start && v1->data.var.start <= v2->data.var.end)
|
// if((v1->data.var.start >= v2->data.var.start && v1->data.var.start <= v2->data.var.end)
|
||||||
|| (v1->data.var.end >= v2->data.var.start && v1->data.var.end <= v2->data.var.end)) {
|
// || (v1->data.var.end >= v2->data.var.start && v1->data.var.end <= v2->data.var.end)) {
|
||||||
|
if(
|
||||||
|
(ast_stmt_is_after(a, v1->data.var.usedefFirst->stmt, v2->data.var.usedefFirst->stmt) == 1
|
||||||
|
&& ast_stmt_is_after(a, v2->data.var.usedefLast->stmt, v1->data.var.usedefFirst->stmt) == 1)
|
||||||
|
||
|
||||||
|
(ast_stmt_is_after(a, v1->data.var.usedefLast->stmt, v2->data.var.usedefFirst->stmt) == 1
|
||||||
|
&& ast_stmt_is_after(a, v2->data.var.usedefLast->stmt, v1->data.var.usedefLast->stmt) == 1)
|
||||||
|
) {
|
||||||
VarTableEntry *min = v1 < v2 ? v1 : v2;
|
VarTableEntry *min = v1 < v2 ? v1 : v2;
|
||||||
VarTableEntry *max = v1 < v2 ? v2 : v1;
|
VarTableEntry *max = v1 < v2 ? v2 : v1;
|
||||||
|
|
||||||
|
22
src/optims.c
22
src/optims.c
@ -6,26 +6,8 @@
|
|||||||
// But CP is NECESSARY, otherwise it creates too many variables
|
// But CP is NECESSARY, otherwise it creates too many variables
|
||||||
// that are unable to be coalesced by the regallocator
|
// that are unable to be coalesced by the regallocator
|
||||||
|
|
||||||
static void recalc_lifespan(VarTableEntry *vte) {
|
|
||||||
assert(vte->kind == VARTABLEENTRY_VAR);
|
|
||||||
|
|
||||||
size_t start = 0xFFFFFFFF, end = 0;
|
|
||||||
|
|
||||||
UseDef *ud = vte->data.var.usedefFirst;
|
|
||||||
while(ud) {
|
|
||||||
if(ud->t < start) start = ud->t;
|
|
||||||
|
|
||||||
if(ud->t > end) end = ud->t;
|
|
||||||
|
|
||||||
ud = ud->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
vte->data.var.start = start;
|
|
||||||
vte->data.var.end = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
void optim_chunk(ASTChunk *chu) {
|
void optim_chunk(ASTChunk *chu) {
|
||||||
AST *s = chu->statementFirst, *sPrev = NULL;
|
/*AST *s = chu->statementFirst, *sPrev = NULL;
|
||||||
while(s) {
|
while(s) {
|
||||||
if(s->nodeKind == AST_STMT_ASSIGN && s->stmtAssign.what->nodeKind == AST_EXPR_VAR && s->stmtAssign.to->nodeKind == AST_EXPR_VAR) {
|
if(s->nodeKind == AST_STMT_ASSIGN && s->stmtAssign.what->nodeKind == AST_EXPR_VAR && s->stmtAssign.to->nodeKind == AST_EXPR_VAR) {
|
||||||
VarTableEntry *dst = ((AST*) s->stmtAssign.what)->exprVar.thing;
|
VarTableEntry *dst = ((AST*) s->stmtAssign.what)->exprVar.thing;
|
||||||
@ -89,5 +71,5 @@ void optim_chunk(ASTChunk *chu) {
|
|||||||
copypropfail:
|
copypropfail:
|
||||||
sPrev = s;
|
sPrev = s;
|
||||||
s = s->statement.next;
|
s = s->statement.next;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
192
src/parse.c
192
src/parse.c
@ -9,17 +9,26 @@
|
|||||||
#include<stdint.h>
|
#include<stdint.h>
|
||||||
#include<signal.h>
|
#include<signal.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
UseDef ud;
|
||||||
|
VarTableEntry *to;
|
||||||
|
} UseDefToAdd;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Token *tokens;
|
Token *tokens;
|
||||||
ssize_t i;
|
ssize_t i;
|
||||||
|
|
||||||
size_t t;
|
|
||||||
|
|
||||||
VarTable *scope;
|
VarTable *scope;
|
||||||
|
|
||||||
|
// Used to coalesce all scopes into one after parsing, to perform global register allocation
|
||||||
|
ASTChunk *topLevel;
|
||||||
|
|
||||||
|
// Used by pushstat to add statements
|
||||||
ASTChunk *currentChunk;
|
ASTChunk *currentChunk;
|
||||||
|
|
||||||
ASTChunk *topLevel;
|
// Used by pushstmt to assemble use-def chain
|
||||||
|
size_t udsToAddCount;
|
||||||
|
UseDefToAdd *udsToAdd;
|
||||||
} Parser;
|
} Parser;
|
||||||
|
|
||||||
static Token get(Parser *P) {
|
static Token get(Parser *P) {
|
||||||
@ -59,6 +68,23 @@ static int maybe(Parser *P, TokenKind t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void pushstat(Parser *P, void *a) {
|
static void pushstat(Parser *P, void *a) {
|
||||||
|
for(size_t i = 0; i < P->udsToAddCount; i++) {
|
||||||
|
VarTableEntry *to = P->udsToAdd[i].to;
|
||||||
|
|
||||||
|
UseDef *ud = malloc(sizeof(*ud));
|
||||||
|
memcpy(ud, &P->udsToAdd[i].ud, sizeof(*ud));
|
||||||
|
ud->stmt = a;
|
||||||
|
|
||||||
|
if(to->data.var.usedefFirst) {
|
||||||
|
to->data.var.usedefLast->next = ud;
|
||||||
|
to->data.var.usedefLast = ud;
|
||||||
|
} else {
|
||||||
|
to->data.var.usedefFirst = to->data.var.usedefLast = ud;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
P->udsToAddCount = 0;
|
||||||
|
|
||||||
if(P->currentChunk->statementFirst) {
|
if(P->currentChunk->statementFirst) {
|
||||||
P->currentChunk->statementLast->statement.next = a;
|
P->currentChunk->statementLast->statement.next = a;
|
||||||
P->currentChunk->statementLast = a;
|
P->currentChunk->statementLast = a;
|
||||||
@ -86,15 +112,31 @@ static ASTExprPrimitive *parse_prim(Parser *P) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AST *exprvar(Parser *P, VarTableEntry *v) {
|
static void newusedef(Parser *P, VarTableEntry *v, AST *expr) {
|
||||||
if(v->kind == VARTABLEENTRY_VAR) {
|
for(size_t i = 0; i < v->data.var.reachingDefs->defCount; i++) {
|
||||||
v->data.var.end = P->t;
|
P->udsToAdd = realloc(P->udsToAdd, sizeof(*P->udsToAdd) * (++P->udsToAddCount));
|
||||||
|
P->udsToAdd[P->udsToAddCount - 1] = (UseDefToAdd) {
|
||||||
|
.ud = {
|
||||||
|
.def = v->data.var.reachingDefs->defs[i],
|
||||||
|
.use = expr,
|
||||||
|
.stmt = NULL, // set by pushstmt
|
||||||
|
.next = NULL,
|
||||||
|
},
|
||||||
|
.to = v
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static AST *exprvar(Parser *P, VarTableEntry *v) {
|
||||||
AST *a = malloc(sizeof(ASTExprVar));
|
AST *a = malloc(sizeof(ASTExprVar));
|
||||||
a->nodeKind = AST_EXPR_VAR;
|
a->nodeKind = AST_EXPR_VAR;
|
||||||
a->exprVar.type = v->type;
|
a->exprVar.type = v->type;
|
||||||
a->exprVar.thing = v;
|
a->exprVar.thing = v;
|
||||||
|
|
||||||
|
if(v->kind == VARTABLEENTRY_VAR) {
|
||||||
|
newusedef(P, v, a);
|
||||||
|
}
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,28 +360,6 @@ AST *nct_parse_expression(Parser *P, int lOP) {
|
|||||||
stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Invalid combination of operator and operand types.");
|
stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Invalid combination of operator and operand types.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0) if(operand->nodeKind == AST_EXPR_PRIMITIVE) {
|
|
||||||
VarTableEntry *thing = malloc(sizeof(*thing));
|
|
||||||
thing->type = operand->expression.type;
|
|
||||||
thing->kind = VARTABLEENTRY_VAR;
|
|
||||||
thing->data.var.start = thing->data.var.end = P->t;
|
|
||||||
|
|
||||||
P->topLevel->vars = realloc(P->topLevel->vars, sizeof(*P->topLevel->vars) * (P->topLevel->varCount + 1));
|
|
||||||
P->topLevel->vars[P->topLevel->varCount++] = thing;
|
|
||||||
|
|
||||||
AST *decl = malloc(sizeof(ASTStmtDecl));
|
|
||||||
decl->nodeKind = AST_STMT_DECL;
|
|
||||||
decl->stmtDecl.thing = thing;
|
|
||||||
decl->stmtDecl.expression = operand;
|
|
||||||
pushstat(P, decl);
|
|
||||||
|
|
||||||
AST *operand2 = malloc(sizeof(ASTExprVar));
|
|
||||||
operand2->nodeKind = AST_EXPR_VAR;
|
|
||||||
operand2->expression.type = operand->expression.type;
|
|
||||||
operand2->exprVar.thing = thing;
|
|
||||||
operand = operand2;
|
|
||||||
}
|
|
||||||
|
|
||||||
astop->operands[1] = operand;
|
astop->operands[1] = operand;
|
||||||
|
|
||||||
if(!astop->type) {
|
if(!astop->type) {
|
||||||
@ -541,70 +561,73 @@ static AST *parse_declaration(Parser *P) {
|
|||||||
} else {
|
} else {
|
||||||
entry = calloc(sizeof(*entry), 1);
|
entry = calloc(sizeof(*entry), 1);
|
||||||
entry->type = type;
|
entry->type = type;
|
||||||
vartable_set(P->scope, name.content, entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTStmtDecl *ret = malloc(sizeof(*ret));
|
AST *ret = NULL;
|
||||||
ret->nodeKind = AST_STMT_DECL;
|
|
||||||
ret->thing = entry;
|
|
||||||
ret->next = NULL;
|
|
||||||
|
|
||||||
if(maybe(P, TOKEN_EQUALS)) {
|
if(maybe(P, TOKEN_EQUALS) || (peek(P, 0).type == TOKEN_SEMICOLON && !isExternal && !isLocal)) {
|
||||||
if(isLocal || isExternal) { /* Impossible, error. */
|
/*if(isExternal || isLocal) {
|
||||||
fputs("'local' and 'extern' keywords are to be used for symbol declaration only.\n", stderr);
|
fputs("'local' and 'extern' keywords are to be used for symbol declaration only.\n", stderr);
|
||||||
abort();
|
abort();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
entry->kind = VARTABLEENTRY_VAR;
|
entry->kind = VARTABLEENTRY_VAR;
|
||||||
entry->data.var.start = entry->data.var.end = P->t;
|
|
||||||
entry->data.var.priority = 1;
|
entry->data.var.priority = 1;
|
||||||
|
|
||||||
ret->expression = NULL;
|
ASTStmtAssign *assign = malloc(sizeof(*assign));
|
||||||
|
|
||||||
pushstat(P, ret);
|
|
||||||
|
|
||||||
AST *assign = malloc(sizeof(ASTStmtAssign));
|
|
||||||
assign->nodeKind = AST_STMT_ASSIGN;
|
assign->nodeKind = AST_STMT_ASSIGN;
|
||||||
assign->stmtAssign.what = exprvar(P, entry);
|
|
||||||
assign->stmtAssign.to = nct_parse_expression(P, 0);
|
|
||||||
|
|
||||||
ret = assign;
|
entry->data.var.reachingDefs = reachingdefs_push(NULL);
|
||||||
} else if(maybe(P, TOKEN_COLON)) {
|
reachingdefs_set(entry->data.var.reachingDefs, (AST*) assign);
|
||||||
if(isExternal) {
|
|
||||||
fputs("External symbols may not be defined.\n", stderr);
|
|
||||||
abort();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
entry->kind = VARTABLEENTRY_SYMBOL;
|
assign->what = exprvar(P, entry);
|
||||||
entry->data.symbol.isLocal = isLocal;
|
assign->to = peek(P, 0).type == TOKEN_SEMICOLON ? NULL : nct_parse_expression(P, 0);
|
||||||
entry->data.symbol.isExternal = isExternal;
|
|
||||||
entry->data.symbol.name = name.content;
|
|
||||||
|
|
||||||
ret->expression = nct_cast_expr(nct_parse_expression(P, 0), type);
|
ret = (AST*) assign;
|
||||||
|
|
||||||
if(ret->expression) {
|
|
||||||
//if(ret->expression->expression.constantType == EXPRESSION_NOT_CONSTANT) {
|
|
||||||
// stahp(1, 4142, "Symbol declaration may contain constant expressions only.");
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
} else if(isExternal) {
|
|
||||||
entry->kind = VARTABLEENTRY_SYMBOL;
|
|
||||||
entry->data.symbol.isLocal = isLocal;
|
|
||||||
entry->data.symbol.isExternal = isExternal;
|
|
||||||
entry->data.symbol.name = name.content;
|
|
||||||
} else {
|
} else {
|
||||||
entry->kind = VARTABLEENTRY_VAR;
|
ASTStmtDecl *decl = malloc(sizeof(*ret));
|
||||||
entry->data.var.start = entry->data.var.end = P->t;
|
decl->nodeKind = AST_STMT_DECL;
|
||||||
entry->data.var.priority = 1;
|
decl->thing = entry;
|
||||||
|
decl->next = NULL;
|
||||||
|
|
||||||
ret->expression = NULL;
|
if(maybe(P, TOKEN_COLON)) {
|
||||||
|
if(isExternal) {
|
||||||
|
fputs("External symbols may not be defined.\n", stderr);
|
||||||
|
abort();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry->kind = VARTABLEENTRY_SYMBOL;
|
||||||
|
entry->data.symbol.isLocal = isLocal;
|
||||||
|
entry->data.symbol.isExternal = isExternal;
|
||||||
|
entry->data.symbol.name = name.content;
|
||||||
|
|
||||||
|
decl->expression = nct_cast_expr(nct_parse_expression(P, 0), type);
|
||||||
|
|
||||||
|
if(decl->expression) {
|
||||||
|
//if(ret->expression->expression.constantType == EXPRESSION_NOT_CONSTANT) {
|
||||||
|
// stahp(1, 4142, "Symbol declaration may contain constant expressions only.");
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
} else if(isExternal) {
|
||||||
|
entry->kind = VARTABLEENTRY_SYMBOL;
|
||||||
|
entry->data.symbol.isLocal = isLocal;
|
||||||
|
entry->data.symbol.isExternal = isExternal;
|
||||||
|
entry->data.symbol.name = name.content;
|
||||||
|
} else {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (AST*) decl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vartable_set(P->scope, name.content, entry);
|
||||||
|
|
||||||
expect(P, TOKEN_SEMICOLON);
|
expect(P, TOKEN_SEMICOLON);
|
||||||
|
|
||||||
return (AST*) ret;
|
return ret;
|
||||||
backtrack:
|
backtrack:
|
||||||
P->i = oldIdx;
|
P->i = oldIdx;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -612,8 +635,6 @@ backtrack:
|
|||||||
|
|
||||||
ASTChunk *nct_parse_chunk(Parser*, int, int);
|
ASTChunk *nct_parse_chunk(Parser*, int, int);
|
||||||
void nct_parse_statement(Parser *P) {
|
void nct_parse_statement(Parser *P) {
|
||||||
P->t++;
|
|
||||||
|
|
||||||
if(maybe(P, TOKEN_IF)) {
|
if(maybe(P, TOKEN_IF)) {
|
||||||
expect(P, TOKEN_PAREN_L);
|
expect(P, TOKEN_PAREN_L);
|
||||||
AST *e = nct_parse_expression(P, 0);
|
AST *e = nct_parse_expression(P, 0);
|
||||||
@ -625,11 +646,11 @@ void nct_parse_statement(Parser *P) {
|
|||||||
|
|
||||||
ret->expression = e;
|
ret->expression = e;
|
||||||
|
|
||||||
|
pushstat(P, ret);
|
||||||
|
|
||||||
expect(P, TOKEN_SQUIGGLY_L);
|
expect(P, TOKEN_SQUIGGLY_L);
|
||||||
ret->then = (AST*) nct_parse_chunk(P, 0, 0);
|
ret->then = (AST*) nct_parse_chunk(P, 0, 0);
|
||||||
expect(P, TOKEN_SQUIGGLY_R);
|
expect(P, TOKEN_SQUIGGLY_R);
|
||||||
|
|
||||||
pushstat(P, ret);
|
|
||||||
return;
|
return;
|
||||||
} else if(maybe(P, TOKEN_LOOP)) {
|
} else if(maybe(P, TOKEN_LOOP)) {
|
||||||
ASTStmtLoop *ret = malloc(sizeof(*ret));
|
ASTStmtLoop *ret = malloc(sizeof(*ret));
|
||||||
@ -637,7 +658,7 @@ void nct_parse_statement(Parser *P) {
|
|||||||
ret->next = NULL;
|
ret->next = NULL;
|
||||||
|
|
||||||
expect(P, TOKEN_SQUIGGLY_L);
|
expect(P, TOKEN_SQUIGGLY_L);
|
||||||
ret->body = nct_parse_chunk(P, 0, 1);
|
ret->body = (AST*) nct_parse_chunk(P, 0, 1);
|
||||||
expect(P, TOKEN_SQUIGGLY_R);
|
expect(P, TOKEN_SQUIGGLY_R);
|
||||||
|
|
||||||
pushstat(P, ret);
|
pushstat(P, ret);
|
||||||
@ -730,6 +751,10 @@ void nct_parse_statement(Parser *P) {
|
|||||||
ret->what = e;
|
ret->what = e;
|
||||||
ret->to = nct_parse_expression(P, 0);//nct_cast_expr(nct_parse_expression(P, 0), ret->what->expression.type);
|
ret->to = nct_parse_expression(P, 0);//nct_cast_expr(nct_parse_expression(P, 0), ret->what->expression.type);
|
||||||
|
|
||||||
|
if(ret->what->nodeKind == AST_EXPR_VAR) {
|
||||||
|
reachingdefs_set(ret->what->exprVar.thing->data.var.reachingDefs, (AST*) ret);
|
||||||
|
}
|
||||||
|
|
||||||
expect(P, TOKEN_SEMICOLON);
|
expect(P, TOKEN_SEMICOLON);
|
||||||
|
|
||||||
pushstat(P, ret);
|
pushstat(P, ret);
|
||||||
@ -748,6 +773,9 @@ void nct_parse_statement(Parser *P) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASTChunk *nct_parse_chunk(Parser *P, int isTopLevel, int varPrioritize) {
|
ASTChunk *nct_parse_chunk(Parser *P, int isTopLevel, int varPrioritize) {
|
||||||
|
if(P->scope) {
|
||||||
|
}
|
||||||
|
|
||||||
AST *ret = malloc(sizeof(ASTChunk));
|
AST *ret = malloc(sizeof(ASTChunk));
|
||||||
ret->nodeKind = AST_CHUNK;
|
ret->nodeKind = AST_CHUNK;
|
||||||
ret->chunk.statementFirst = ret->chunk.statementLast = NULL;
|
ret->chunk.statementFirst = ret->chunk.statementLast = NULL;
|
||||||
@ -763,6 +791,8 @@ ASTChunk *nct_parse_chunk(Parser *P, int isTopLevel, int varPrioritize) {
|
|||||||
P->topLevel = &ret->chunk;
|
P->topLevel = &ret->chunk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vartable_new_reachingdefs_for_all_vars(P->scope);
|
||||||
|
|
||||||
/* Find all symbol names and struct types ahead of time. Searches for colons as those can only mean symbol declarations */
|
/* Find all symbol names and struct types ahead of time. Searches for colons as those can only mean symbol declarations */
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -790,7 +820,7 @@ ASTChunk *nct_parse_chunk(Parser *P, int isTopLevel, int varPrioritize) {
|
|||||||
} while(P->i >= 0 && P->tokens[P->i].type != TOKEN_SEMICOLON && P->tokens[P->i].type != TOKEN_SQUIGGLY_R && P->tokens[P->i].type != TOKEN_PAREN_R);
|
} while(P->i >= 0 && P->tokens[P->i].type != TOKEN_SEMICOLON && P->tokens[P->i].type != TOKEN_SQUIGGLY_R && P->tokens[P->i].type != TOKEN_PAREN_R);
|
||||||
P->i++;
|
P->i++;
|
||||||
|
|
||||||
ASTStmtDecl *d = &parse_declaration(P)->stmtDecl;
|
AST *d = parse_declaration(P);
|
||||||
if(!d) abort();
|
if(!d) abort();
|
||||||
|
|
||||||
free(d); /* We don't need it. */
|
free(d); /* We don't need it. */
|
||||||
@ -805,6 +835,8 @@ ASTChunk *nct_parse_chunk(Parser *P, int isTopLevel, int varPrioritize) {
|
|||||||
nct_parse_statement(P);
|
nct_parse_statement(P);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vartable_coalesce_reachingdefs_for_all_vars(P->scope);
|
||||||
|
|
||||||
size_t nonSymbols = 0;
|
size_t nonSymbols = 0;
|
||||||
for(size_t i = 0; i < P->scope->count; i++) {
|
for(size_t i = 0; i < P->scope->count; i++) {
|
||||||
if(P->scope->data[i]->kind == VARTABLEENTRY_VAR) {
|
if(P->scope->data[i]->kind == VARTABLEENTRY_VAR) {
|
||||||
@ -831,9 +863,7 @@ ASTChunk *nct_parse_chunk(Parser *P, int isTopLevel, int varPrioritize) {
|
|||||||
|
|
||||||
AST *nct_parse(Token *tokens) {
|
AST *nct_parse(Token *tokens) {
|
||||||
Parser P;
|
Parser P;
|
||||||
|
memset(&P, 0, sizeof(P));
|
||||||
P.tokens = tokens;
|
P.tokens = tokens;
|
||||||
P.t = 0;
|
|
||||||
P.i = 0;
|
|
||||||
P.scope = NULL;
|
|
||||||
return (AST*) nct_parse_chunk(&P, 1, 0);
|
return (AST*) nct_parse_chunk(&P, 1, 0);
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,30 @@
|
|||||||
#include<stdlib.h>
|
#include<stdlib.h>
|
||||||
#include<string.h>
|
#include<string.h>
|
||||||
|
|
||||||
|
struct ReachingDefs *reachingdefs_push(struct ReachingDefs *this) {
|
||||||
|
struct ReachingDefs *ret = calloc(1, sizeof(*ret));
|
||||||
|
ret->parent = this;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ReachingDefs *reachingdefs_coalesce(struct ReachingDefs *this) {
|
||||||
|
struct ReachingDefs *parent = this->parent;
|
||||||
|
if(parent) {
|
||||||
|
parent->defs = realloc(parent->defs, sizeof(*parent->defs) * (parent->defCount + this->defCount));
|
||||||
|
memcpy(&parent->defs[parent->defCount], this->defs, sizeof(*this->defs) * this->defCount);
|
||||||
|
parent->defCount += this->defCount;
|
||||||
|
}
|
||||||
|
free(this->defs);
|
||||||
|
free(this);
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reachingdefs_set(struct ReachingDefs *this, union AST *def) {
|
||||||
|
this->defCount = 1;
|
||||||
|
this->defs = realloc(this->defs, sizeof(*this->defs) * this->defCount);
|
||||||
|
this->defs[0] = def;
|
||||||
|
}
|
||||||
|
|
||||||
VarTable *vartable_new(VarTable *parent) {
|
VarTable *vartable_new(VarTable *parent) {
|
||||||
VarTable *ret = malloc(sizeof(*ret));
|
VarTable *ret = malloc(sizeof(*ret));
|
||||||
ret->parent = parent;
|
ret->parent = parent;
|
||||||
@ -39,5 +63,30 @@ VarTableEntry *vartable_set(VarTable *this, const char *name, VarTableEntry *e)
|
|||||||
this->names[this->count] = name;
|
this->names[this->count] = name;
|
||||||
this->data[this->count] = e;
|
this->data[this->count] = e;
|
||||||
this->count++;
|
this->count++;
|
||||||
|
if(e->kind == VARTABLEENTRY_VAR) e->data.var.name = name;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vartable_new_reachingdefs_for_all_vars(VarTable *this) {
|
||||||
|
for(size_t i = 0; i < this->count; i++) {
|
||||||
|
if(this->data[i]->kind == VARTABLEENTRY_VAR) {
|
||||||
|
this->data[i]->data.var.reachingDefs = reachingdefs_push(this->data[i]->data.var.reachingDefs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this->parent) {
|
||||||
|
vartable_new_reachingdefs_for_all_vars(this->parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void vartable_coalesce_reachingdefs_for_all_vars(VarTable *this) {
|
||||||
|
for(size_t i = 0; i < this->count; i++) {
|
||||||
|
if(this->data[i]->kind == VARTABLEENTRY_VAR) {
|
||||||
|
this->data[i]->data.var.reachingDefs = reachingdefs_coalesce(this->data[i]->data.var.reachingDefs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this->parent) {
|
||||||
|
vartable_coalesce_reachingdefs_for_all_vars(this->parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,13 +7,25 @@ typedef enum {
|
|||||||
VARTABLEENTRY_SYMBOL, VARTABLEENTRY_TYPE, VARTABLEENTRY_VAR
|
VARTABLEENTRY_SYMBOL, VARTABLEENTRY_TYPE, VARTABLEENTRY_VAR
|
||||||
} VarTableEntryKind;
|
} VarTableEntryKind;
|
||||||
|
|
||||||
|
union AST;
|
||||||
typedef struct UseDef {
|
typedef struct UseDef {
|
||||||
union AST *use; //expr
|
union AST *def; // assign stmt
|
||||||
union AST *def; //assign stmt
|
union AST *use; // corresponding AST_EXPR_VAR
|
||||||
size_t t;
|
union AST *stmt; // whole using stmt
|
||||||
struct UseDef *next;
|
struct UseDef *next;
|
||||||
} UseDef;
|
} UseDef;
|
||||||
|
|
||||||
|
// Stack, necessary for "possible reaching defs" such as from if statements
|
||||||
|
typedef struct ReachingDefs {
|
||||||
|
size_t defCount;
|
||||||
|
union AST **defs;
|
||||||
|
|
||||||
|
struct ReachingDefs *parent;
|
||||||
|
} ReachingDefs;
|
||||||
|
struct ReachingDefs *reachingdefs_push(struct ReachingDefs*);
|
||||||
|
struct ReachingDefs *reachingdefs_coalesce(struct ReachingDefs*);
|
||||||
|
void reachingdefs_set(struct ReachingDefs*, union AST*);
|
||||||
|
|
||||||
typedef struct VarTableEntry {
|
typedef struct VarTableEntry {
|
||||||
Type *type;
|
Type *type;
|
||||||
|
|
||||||
@ -26,18 +38,28 @@ typedef struct VarTableEntry {
|
|||||||
const char *name;
|
const char *name;
|
||||||
} symbol;
|
} symbol;
|
||||||
struct {
|
struct {
|
||||||
uint16_t color, degree;
|
// For debugging
|
||||||
size_t start, end;
|
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
// Register allocation
|
||||||
|
|
||||||
|
// vars in loops have higher priority
|
||||||
|
// a more advanced approach would be to use weights for different colors (e.g. vars for mul "should" be in eax)
|
||||||
uint8_t priority;
|
uint8_t priority;
|
||||||
|
uint16_t color, degree;
|
||||||
|
|
||||||
|
// Used during parsing
|
||||||
|
|
||||||
|
ReachingDefs *reachingDefs;
|
||||||
|
|
||||||
|
// Optimizations
|
||||||
|
|
||||||
UseDef *usedefFirst;
|
UseDef *usedefFirst;
|
||||||
UseDef *usedefLast;
|
UseDef *usedefLast;
|
||||||
} var;
|
} var;
|
||||||
};
|
};
|
||||||
struct VarTableEntry *offset;
|
|
||||||
} data;
|
} data;
|
||||||
|
|
||||||
void *userdata;
|
|
||||||
} VarTableEntry;
|
} VarTableEntry;
|
||||||
|
|
||||||
typedef struct VarTable {
|
typedef struct VarTable {
|
||||||
@ -53,4 +75,7 @@ VarTableEntry *vartable_get(VarTable*, const char*);
|
|||||||
VarTableEntry *vartable_find(VarTable*, const char*);
|
VarTableEntry *vartable_find(VarTable*, const char*);
|
||||||
VarTableEntry *vartable_set(VarTable*, const char*, VarTableEntry*);
|
VarTableEntry *vartable_set(VarTable*, const char*, VarTableEntry*);
|
||||||
|
|
||||||
|
void vartable_new_reachingdefs_for_all_vars(VarTable*);
|
||||||
|
void vartable_coalesce_reachingdefs_for_all_vars(VarTable*);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
145
tests/mandelbrot.b
Normal file
145
tests/mandelbrot.b
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
A mandelbrot set fractal viewer in brainf*** written by Erik Bosman
|
||||||
|
+++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[
|
||||||
|
>>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+
|
||||||
|
<<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
>+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+[>>>>>>[>>>>>>>[-]>>]<<<<<<<<<[<<<<<<<<<]>>
|
||||||
|
>>>>>[-]+<<<<<<++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<+++++++[-[->>>
|
||||||
|
>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[[-]>>>>>>[>>>>>
|
||||||
|
>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>
|
||||||
|
[>>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<
|
||||||
|
<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>+++++++++++++++[[
|
||||||
|
>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[
|
||||||
|
>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[
|
||||||
|
-<<+>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<
|
||||||
|
<<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<
|
||||||
|
[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>
|
||||||
|
>>>>[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+
|
||||||
|
<<<<<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>
|
||||||
|
>>>>>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<
|
||||||
|
+>>>>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<
|
||||||
|
<]<+<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
|
||||||
|
>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<
|
||||||
|
<<<]>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<
|
||||||
|
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->
|
||||||
|
>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<
|
||||||
|
<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++++++++++++++++
|
||||||
|
+++++++>>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>[<<<<<<<+<[-<+>>>>+<<[-]]>[-<<[->+>>>-
|
||||||
|
<<<<]>>>]>>>>>>>>>>>>>[>>[-]>[-]>[-]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>>>>>>[>>>>>
|
||||||
|
[-<<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>[-<<<<<<<<
|
||||||
|
<+>>>>>>>>>]>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>>]+>[-
|
||||||
|
]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>>>>>>>]<<<
|
||||||
|
<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+>>]<
|
||||||
|
<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[->>>>
|
||||||
|
>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-]<->>>
|
||||||
|
[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-<
|
||||||
|
<<<<+>>>>>]<<<<<[->>>>>+<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+>>>>>>>>
|
||||||
|
]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+
|
||||||
|
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
|
||||||
|
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
|
||||||
|
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
|
||||||
|
[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||||
|
]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>
|
||||||
|
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>++++++++
|
||||||
|
+++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-<<<<<<<+
|
||||||
|
>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[
|
||||||
|
-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>>]>[-<<<<<<[->>>>>+<++<<<<]>>>>>[-<
|
||||||
|
<<<<+>>>>>]<->+>]<[->+<]<<<<<[->>>>>+<<<<<]>>>>>>[-]<<<<<<+>>>>[-<<<<->>>>]+<<<<
|
||||||
|
[->>>>->>>>>[>>[-<<->>]+<<[->>->[-<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]
|
||||||
|
+>>>>>>[>>>>>>>>>]>+<]]+>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<<<<<<<<<<[<<<<<
|
||||||
|
<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<
|
||||||
|
[<<<<<<<<<]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<
|
||||||
|
<<<+<[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<
|
||||||
|
<<<<<+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<
|
||||||
|
<<<<<<<<<<]>>>>[-]<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+<]>>>>>>>>]<<<
|
||||||
|
<<<<<+<[>[->>>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>[->>>>+<<<<]>]<[->>>>-<<<<<<<
|
||||||
|
<<<<<<<+>>>>>>>>>>]<]>>[->>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>>+<<<<
|
||||||
|
]<<<<<<<<<<<]>>>>>>+<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>>>>>>>>>]<<<<<<<<<
|
||||||
|
[>[->>>>>+<<<<[->>>>-<<<<<<<<<<<<<<+>>>>>>>>>>>[->>>+<<<]<]>[->>>-<<<<<<<<<<<<<<
|
||||||
|
+>>>>>>>>>>>]<<]>[->>>>+<<<[->>>-<<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>>+<<<]<<<<<<<
|
||||||
|
<<<<<]]>[-]>>[-]>[-]>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<
|
||||||
|
<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[
|
||||||
|
[>>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+
|
||||||
|
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>
|
||||||
|
[-<<+>>]<<[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<
|
||||||
|
<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[
|
||||||
|
>[-]<->>>[-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[
|
||||||
|
>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>]>
|
||||||
|
>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>[-]>>>>+++++++++++++++[[>>>>>>>>>]<<<<<<<<<-<<<<<
|
||||||
|
<<<<[<<<<<<<<<]>>>>>>>>>-]+[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<
|
||||||
|
<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-
|
||||||
|
<<<+>>>]<<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>
|
||||||
|
>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>>>
|
||||||
|
[-<<<->>>]<<<[->>>+<<<]>>>>>>>>]<<<<<<<<+<[>[->+>[-<-<<<<<<<<<<+>>>>>>>>>>>>[-<<
|
||||||
|
+>>]<]>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<<<]>>[-<+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>>]<]>
|
||||||
|
[-<<+>>]<<<<<<<<<<<<<]]>>>>[-<<<<+>>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>
|
||||||
|
>>>>>>]<<<<<<<<+<[>[->+>>[-<<-<<<<<<<<<<+>>>>>>>>>>>[-<+>]>]<[-<-<<<<<<<<<<+>>>>
|
||||||
|
>>>>>>>]<<]>>>[-<<+>[-<-<<<<<<<<<<+>>>>>>>>>>>]>]<[-<+>]<<<<<<<<<<<<]>>>>>+<<<<<
|
||||||
|
]>>>>>>>>>[>>>[-]>[-]>[-]>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>>>[-<<<<<
|
||||||
|
<+>>>>>>]<<<<<<[->>>>>>+<<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>+>[-<-<<<<+>>>>
|
||||||
|
>]>>[-<<<<<<<[->>>>>+<++<<<<]>>>>>[-<<<<<+>>>>>]<->+>>]<<[->>+<<]<<<<<[->>>>>+<<
|
||||||
|
<<<]+>>>>[-<<<<->>>>]+<<<<[->>>>->>>>>[>>>[-<<<->>>]+<<<[->>>-<[-<<+>>]<<[->>+<<
|
||||||
|
<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>[-<<->>]+<<[->>->[-<<<+>>>]<
|
||||||
|
<<[->>>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<
|
||||||
|
<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-<<<+>>>]<<<[->>>+>>>>>>[>+>[-<->]<[->+
|
||||||
|
<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>[->>>+<<<]>]<[->>>-
|
||||||
|
<<<<<<<<<<<<<+>>>>>>>>>>]<]>>[->>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>]>]<[->>>+<<<
|
||||||
|
]<<<<<<<<<<<]>>>>>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]]>>>>[-<<<<+>
|
||||||
|
>>>]<<<<[->>>>+>>>>>[>+>>[-<<->>]<<[->>+<<]>>>>>>>>]<<<<<<<<+<[>[->>>>+<<<[->>>-
|
||||||
|
<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[
|
||||||
|
->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<<<<<]]>>>>[-]<<<<]>>>>[-<<<<+>>
|
||||||
|
>>]<<<<[->>>>+>[-]>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>[>>>>>>
|
||||||
|
>>>]<<<<<<<<<[>[->>>>+<<<[->>>-<<<<<<<<<<<<<+>>>>>>>>>>>[->>+<<]<]>[->>-<<<<<<<<
|
||||||
|
<<<<<+>>>>>>>>>>>]<<]>[->>>+<<[->>-<<<<<<<<<<<<<+>>>>>>>>>>>]<]>[->>+<<]<<<<<<<<
|
||||||
|
<<<<]]>>>>>>>>>[>>[-]>[-]>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>[-]>>>>>[>>>>>[-<<<<+
|
||||||
|
>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<+>>>>>
|
||||||
|
]<<<<<[->>>>>+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>
|
||||||
|
>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>
|
||||||
|
>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[-<<+
|
||||||
|
>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>
|
||||||
|
[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-
|
||||||
|
]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>>>>>>
|
||||||
|
[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<
|
||||||
|
<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>
|
||||||
|
>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<<+>>>
|
||||||
|
>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+
|
||||||
|
<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>>>>>>
|
||||||
|
>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>
|
||||||
|
>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<<<<<]
|
||||||
|
>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<<<<<<
|
||||||
|
]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[->>>+<
|
||||||
|
<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>
|
||||||
|
>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>->>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>]<<+>>>>[-<<<<
|
||||||
|
->>>>]+<<<<[->>>>-<<<<<<.>>]>>>>[-<<<<<<<.>>>>>>>]<<<[-]>[-]>[-]>[-]>[-]>[-]>>>[
|
||||||
|
>[-]>[-]>[-]>[-]>[-]>[-]>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-]>>>>]<<<<<<<<<
|
||||||
|
[<<<<<<<<<]>+++++++++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+>>>>>>>>>+<<<<<<<<
|
||||||
|
<<<<<<[<<<<<<<<<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+[-]>>[>>>>>>>>>]<<<<<
|
||||||
|
<<<<[>>>>>>>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<[<<<<<<<<<]>>>>>>>[-]+>>>]<<<<
|
||||||
|
<<<<<<]]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+>>[>+>>>>[-<<<<->>>>]<<<<[->>>
|
||||||
|
>+<<<<]>>>>>>>>]<<+<<<<<<<[>>>>>[->>+<<]<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<
|
||||||
|
<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<<<<<[->>>>>>+<<<<<<]<
|
||||||
|
+<<<<<<<<<]>>>>>>>-<<<<[-]+<<<]+>>>>>>>[-<<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>->>[>>
|
||||||
|
>>>[->>+<<]>>>>]<<<<<<<<<[>[-]<->>>>>>>[-<<<<<<<+>[<->-<<<+>>>]<[->+<]>>>>>>>]<<
|
||||||
|
<<<<[->>>>>>+<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>+<<<
|
||||||
|
<<[<<<<<<<<<]>>>>>>>>>[>>>>>[-<<<<<->>>>>]+<<<<<[->>>>>->>[-<<<<<<<+>>>>>>>]<<<<
|
||||||
|
<<<[->>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>[-<
|
||||||
|
<<<<<<->>>>>>>]+<<<<<<<[->>>>>>>-<<[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<<<<<<<<<[<<<
|
||||||
|
<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<
|
||||||
|
<<[<<<<<<<<<]>>>>[-]<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>-<<<<<[<<<<<<<
|
||||||
|
<<]]>>>]<<<<.>>>>>>>>>>[>>>>>>[-]>>>]<<<<<<<<<[<<<<<<<<<]>++++++++++[-[->>>>>>>>
|
||||||
|
>+<<<<<<<<<]>>>>>>>>>]>>>>>+>>>>>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-<<<<<<
|
||||||
|
<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+[-]>[>>>>>>>>>]<<<<<<<<<[>>>>>>>>[-<<<<<<<+>>>>>>
|
||||||
|
>]<<<<<<<[->>>>>>>+<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+>>]<<<<<<<<<<]]>>>>>>>>[-<<<<<
|
||||||
|
<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+>[>+>>>>>[-<<<<<->>>>>]<<<<<[->>>>>+<<<<<]>>>>>>
|
||||||
|
>>]<+<<<<<<<<[>>>>>>[->>+<<]<<<<<<<<<<<<<<<]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[-]<-
|
||||||
|
>>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<
|
||||||
|
<<<]>>>>>>>>-<<<<<[-]+<<<]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>->[>>>
|
||||||
|
>>>[->>+<<]>>>]<<<<<<<<<[>[-]<->>>>>>>>[-<<<<<<<<+>[<->-<<+>>]<[->+<]>>>>>>>>]<<
|
||||||
|
<<<<<[->>>>>>>+<<<<<<<]<+<<<<<<<<<]>+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>
|
||||||
|
+>>>>>>>>>>>>>>>>>>>>>>>>>>>+<<<<<<[<<<<<<<<<]>>>>>>>>>[>>>>>>[-<<<<<<->>>>>>]+<
|
||||||
|
<<<<<[->>>>>>->>[-<<<<<<<<+>>>>>>>>]<<<<<<<<[->>>>>>>>+<<<<<<<<<<<<<<<<<[<<<<<<<
|
||||||
|
<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>>>>>[-<<<<<<<<->>>>>>>>]+<<<<<<<<[->>>>>>>>
|
||||||
|
-<<[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>
|
||||||
|
>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<<<<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>[-]<<<++++
|
||||||
|
+[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>->>>>>>>>>>>>>>>>>>>>>>>>>>>-<<<<<<[<<<<
|
||||||
|
<<<<<]]>>>]
|
Loading…
Reference in New Issue
Block a user