Compare commits
No commits in common. "012d18cdf8e53e80321c1999f54a7e126d45a65e" and "5455e1cebb7323b4e2f9e32fe6627676c7c24561" have entirely different histories.
012d18cdf8
...
5455e1cebb
@ -1,4 +0,0 @@
|
||||
record Alloc {
|
||||
u8* userdata;
|
||||
u8*(u8* userdata, u8* ptr, u32 sz)* realloc;
|
||||
}
|
5
examples/Allocator.nct
Normal file
5
examples/Allocator.nct
Normal file
@ -0,0 +1,5 @@
|
||||
record Allocator {
|
||||
u8* userdata;
|
||||
u8*(u8* userdata, u8* original, u32 size) realloc;
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* ListDLU: Dynamic, Linear growth, unmanaged
|
||||
*/
|
||||
|
||||
use Alloc;
|
||||
|
||||
record ListDLU[T, S; growth] {
|
||||
S capacity;
|
||||
S size;
|
||||
T[?]* data;
|
||||
}
|
||||
|
||||
ListDLU_remove: [T, S; growth]u0(ListDLU[T, S; growth]* this, S index) -> {
|
||||
T* data0 = &((*((*this).data))[index]);
|
||||
T* data1 = data0 + @sizeof T;
|
||||
S sz = (*this).size;
|
||||
(*this).size = (*this).size - 1;
|
||||
loop {
|
||||
if(index == sz) {
|
||||
break;
|
||||
}
|
||||
|
||||
*data0 = *data1;
|
||||
|
||||
data0 = data0 + @sizeof T;
|
||||
data1 = data1 + @sizeof T;
|
||||
index = index + 1;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
ListDLU_add: [T, S; growth]u0(ListDLU[T, S; growth]* this, Alloc *alloc, T value) -> {
|
||||
if((*this).size == (*this).capacity) {
|
||||
u32 newcap = (*this).capacity + growth;
|
||||
(*this).capacity = newcap;
|
||||
(*this).data = ((*alloc).realloc)((*alloc).userdata, (*this).data, newcap * @sizeof T);
|
||||
}
|
||||
|
||||
(*((*this).data))[(*this).size] = value;
|
||||
(*this).size = (*this).size + 1;
|
||||
|
||||
return;
|
||||
};
|
@ -1,29 +0,0 @@
|
||||
use ListDLU;
|
||||
|
||||
@section(".text");
|
||||
|
||||
@instantiate ListDLU_remove[u32, u32; 9];
|
||||
@instantiate ListDLU_add[u32, u32; 9];
|
||||
|
||||
extern u8*(u8* ptr, u32 sz) realloc;
|
||||
libc_realloc: u8*(u8* userdata, u8* ptr, u32 sz) -> {
|
||||
return realloc(ptr, sz);
|
||||
};
|
||||
|
||||
main: u0() -> {
|
||||
Alloc libc;
|
||||
libc.realloc = &libc_realloc;
|
||||
|
||||
ListDLU[u32, u32; 9] list;
|
||||
list.capacity = 0;
|
||||
list.size = 0;
|
||||
list.data = 0;
|
||||
ListDLU_add[u32, u32; 9](&list, &libc, 1234);
|
||||
ListDLU_add[u32, u32; 9](&list, &libc, 4321);
|
||||
ListDLU_add[u32, u32; 9](&list, &libc, 7777);
|
||||
ListDLU_add[u32, u32; 9](&list, &libc, 6969);
|
||||
ListDLU_remove[u32, u32; 9](&list, 1);
|
||||
return;
|
||||
};
|
||||
|
||||
@section(".bss");
|
11
src/ast.c
11
src/ast.c
@ -57,7 +57,7 @@ void generic_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *tlc, v
|
||||
} else if(n->nodeKind == AST_EXPR_CALL) {
|
||||
generic_visitor(&n->exprCall.what, stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
|
||||
|
||||
for(size_t i = 0; i < n->exprCall.what->expression.type->pointer.of->function.argCount; i++) {
|
||||
for(size_t i = 0; i < n->exprCall.what->expression.type->function.argCount; i++) {
|
||||
generic_visitor(&n->exprCall.args[i], stmt, stmtPrev, chu, tlc, ud, preHandler, postHandler);
|
||||
}
|
||||
} else if(n->nodeKind == AST_EXPR_CAST) {
|
||||
@ -421,7 +421,7 @@ static void ast_usedef_pass(struct UsedefPassState *state, AST *tlc, AST *a, AST
|
||||
} else if(a->nodeKind == AST_EXPR_CALL) {
|
||||
ast_usedef_pass(state, tlc, a->exprCall.what, wholestmt);
|
||||
|
||||
for(size_t p = 0; p < a->exprCall.what->expression.type->pointer.of->function.argCount; p++) {
|
||||
for(size_t p = 0; p < a->exprCall.what->expression.type->function.argCount; p++) {
|
||||
ast_usedef_pass(state, tlc, a->exprCall.args[p], wholestmt);
|
||||
}
|
||||
} else if(a->nodeKind == AST_EXPR_PRIMITIVE) {
|
||||
@ -698,7 +698,7 @@ static char *ast_dumpe(AST *tlc, AST *e) {
|
||||
char *w = ast_dumpe(tlc, e->exprCall.what);
|
||||
char *out = malp("%s(", w);
|
||||
free(w);
|
||||
size_t argCount = e->exprCall.what->expression.type->pointer.of->function.argCount;
|
||||
size_t argCount = e->exprCall.what->expression.type->function.argCount;
|
||||
for(size_t i = 0; i < argCount; i++) {
|
||||
char *a = ast_dumpe(tlc, e->exprCall.args[i]);
|
||||
char *out2 = malp(i == argCount - 1 ? "%s%s)" : "%s%s, ", out, a);
|
||||
@ -964,7 +964,6 @@ static void spill2stack_visitor(AST **aptr, AST *stmt, AST *stmtPrev, AST *chunk
|
||||
offset->nodeKind = AST_EXPR_PRIMITIVE;
|
||||
offset->type = rsp->type;
|
||||
offset->val = -this->stackGrowth; // This will be affected by the other part of this pass, so we must reverse
|
||||
offset->stackGrowth = true;
|
||||
|
||||
ASTExprBinaryOp *bop = calloc(1, sizeof(*bop));
|
||||
bop->nodeKind = AST_EXPR_BINARY_OP;
|
||||
@ -982,10 +981,10 @@ static void spill2stack_visitor(AST **aptr, AST *stmt, AST *stmtPrev, AST *chunk
|
||||
*aptr = (AST*) deref;
|
||||
}
|
||||
|
||||
} else if(a->nodeKind == AST_EXPR_PRIMITIVE && a->exprPrim.stackGrowth) {
|
||||
} else if(a->nodeKind == AST_EXPR_BINARY_OP && a->exprBinOp.operands[0]->nodeKind == AST_EXPR_STACK_POINTER && a->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) {
|
||||
|
||||
// Guaranteed to not require more dumbification
|
||||
a->exprPrim.val += this->stackGrowth;
|
||||
a->exprBinOp.operands[1]->exprPrim.val += this->stackGrowth;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -123,9 +123,6 @@ typedef struct {
|
||||
ASTExpr;
|
||||
|
||||
int val;
|
||||
|
||||
// If true, increase this literal during stack growths
|
||||
bool stackGrowth;
|
||||
} ASTExprPrimitive;
|
||||
|
||||
typedef struct {
|
||||
|
21
src/parse.c
21
src/parse.c
@ -406,24 +406,13 @@ AST *nct_parse_expression(Parser *P, int lOP) {
|
||||
|
||||
while(peek(P, 0).type == TOKEN_PAREN_L || peek(P, 0).type == TOKEN_SQUAREN_L) {
|
||||
if(maybe(P, TOKEN_PAREN_L)) {
|
||||
if(ret->expression.type->type == TYPE_TYPE_FUNCTION) {
|
||||
ASTExprUnaryOp *ref = alloc_node(P, sizeof(*ref));
|
||||
ref->nodeKind = AST_EXPR_UNARY_OP;
|
||||
ref->type = type_pointer_wrap(ret->expression.type);
|
||||
ref->operator = UNOP_REF;
|
||||
ref->operand = ret;
|
||||
ret = (AST*) ref;
|
||||
if(ret->expression.type->type != TYPE_TYPE_FUNCTION) {
|
||||
stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Only function types may be called.");
|
||||
}
|
||||
|
||||
if(ret->expression.type->type != TYPE_TYPE_POINTER || ret->expression.type->pointer.of->type != TYPE_TYPE_FUNCTION) {
|
||||
stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Only function types or function pointers may be called.");
|
||||
}
|
||||
|
||||
Type *ftype = ret->expression.type->pointer.of;
|
||||
|
||||
ASTExprCall *call = alloc_node(P, sizeof(*call));
|
||||
call->nodeKind = AST_EXPR_CALL;
|
||||
call->type = ftype->function.ret;
|
||||
call->type = ret->expression.type->function.ret;
|
||||
call->what = ret;
|
||||
call->args = NULL;
|
||||
|
||||
@ -432,7 +421,7 @@ AST *nct_parse_expression(Parser *P, int lOP) {
|
||||
if(!maybe(P, TOKEN_PAREN_R)) {
|
||||
while(peek(P, 0).type != TOKEN_PAREN_R && peek(P, 0).type != TOKEN_COMMA) {
|
||||
call->args = realloc(call->args, (argCount + 1) * sizeof(AST*));
|
||||
call->args[argCount] = ast_cast_expr(nct_parse_expression(P, 0), ftype->function.args[argCount]);
|
||||
call->args[argCount] = ast_cast_expr(nct_parse_expression(P, 0), ret->expression.type->function.args[argCount]);
|
||||
|
||||
argCount++;
|
||||
|
||||
@ -442,7 +431,7 @@ AST *nct_parse_expression(Parser *P, int lOP) {
|
||||
}
|
||||
}
|
||||
|
||||
if(argCount != ftype->function.argCount) {
|
||||
if(argCount != call->what->expression.type->function.argCount) {
|
||||
stahp(P->tokens[P->i].row, P->tokens[P->i].column, "Mismatched number of arguments");
|
||||
}
|
||||
|
||||
|
38
src/x86/cg.c
38
src/x86/cg.c
@ -131,14 +131,12 @@ static AST *is_field_access(AST *e) {
|
||||
|
||||
static const char *xop_sz(AST *tlc, AST *e, int sz) {
|
||||
#define XOPBUFS 16
|
||||
#define XOPBUFSZ 32
|
||||
#define XOPBUFSZ 24
|
||||
static char bufs[XOPBUFS][XOPBUFSZ];
|
||||
static int bufidx = 0;
|
||||
|
||||
char *ret = bufs[bufidx];
|
||||
|
||||
int pr = 0;
|
||||
|
||||
if(e->nodeKind == AST_EXPR_UNARY_OP && e->exprUnOp.operator == UNOP_DEREF) {
|
||||
AST *p = e->exprUnOp.operand;
|
||||
|
||||
@ -147,12 +145,12 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) {
|
||||
}
|
||||
|
||||
if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprVar.thing->kind == SCOPEITEM_VAR && p->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) {
|
||||
pr = snprintf(ret, XOPBUFSZ, "%s [%s + %s]",
|
||||
snprintf(ret, XOPBUFSZ, "%s [%s + %s]",
|
||||
spec(sz),
|
||||
xv_sz(p->exprBinOp.operands[0]->exprVar.thing, 0),
|
||||
xv_sz(p->exprBinOp.operands[1]->exprVar.thing, 0));
|
||||
} else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF && p->exprBinOp.operands[0]->exprUnOp.operand->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL && p->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) {
|
||||
pr = snprintf(ret, XOPBUFSZ, "%s [%s + %s]",
|
||||
snprintf(ret, XOPBUFSZ, "%s [%s + %s]",
|
||||
spec(sz),
|
||||
p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name,
|
||||
xv_sz(p->exprBinOp.operands[1]->exprVar.thing, 0));
|
||||
@ -162,7 +160,7 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) {
|
||||
if(e->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP) {
|
||||
assert(e->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF);
|
||||
|
||||
pr = snprintf(ret, XOPBUFSZ, "%s [%s + %i]",
|
||||
snprintf(ret, XOPBUFSZ, "%s [%s + %i]",
|
||||
spec(sz),
|
||||
e->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name,
|
||||
e->exprBinOp.operands[1]->exprPrim.val);
|
||||
@ -171,45 +169,43 @@ static const char *xop_sz(AST *tlc, AST *e, int sz) {
|
||||
|
||||
ScopeItem *vte = e->exprBinOp.operands[0]->exprVar.thing;
|
||||
|
||||
pr = snprintf(ret, XOPBUFSZ, "%s [%s + %i]",
|
||||
snprintf(ret, XOPBUFSZ, "%s [%s + %i]",
|
||||
spec(sz),
|
||||
REG_CLASSES[vte->data.var.registerClass].rsN[vte->data.var.color],
|
||||
e->exprBinOp.operands[1]->exprPrim.val);
|
||||
}
|
||||
} else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_UNARY_OP && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operands[0]->exprUnOp.operator == UNOP_REF && p->exprBinOp.operands[0]->exprUnOp.operand->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->kind == SCOPEITEM_SYMBOL && p->exprBinOp.operands[1]->exprBinOp.operator == BINOP_MUL && p->exprBinOp.operands[1]->exprBinOp.operands[1]->nodeKind == AST_EXPR_VAR && p->exprBinOp.operands[1]->exprBinOp.operands[0]->nodeKind == AST_EXPR_PRIMITIVE && p->exprBinOp.operands[1]->exprBinOp.operands[1]->exprVar.thing->kind == SCOPEITEM_VAR) {
|
||||
pr = snprintf(ret, XOPBUFSZ, "%s [%s + %i * %s]",
|
||||
snprintf(ret, XOPBUFSZ, "%s [%s + %i * %s]",
|
||||
spec(sz),
|
||||
p->exprBinOp.operands[0]->exprUnOp.operand->exprVar.thing->data.symbol.name,
|
||||
p->exprBinOp.operands[1]->exprBinOp.operands[0]->exprPrim.val,
|
||||
xv_sz(p->exprBinOp.operands[1]->exprBinOp.operands[1]->exprVar.thing, 0));
|
||||
} else if(p->nodeKind == AST_EXPR_VAR && p->exprVar.thing->kind == SCOPEITEM_VAR) {
|
||||
pr = snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), xv_sz(p->exprVar.thing, 0));
|
||||
snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), xv_sz(p->exprVar.thing, 0));
|
||||
} else if(p->nodeKind == AST_EXPR_BINARY_OP && p->exprBinOp.operator == BINOP_ADD && p->exprBinOp.operands[0]->nodeKind == AST_EXPR_STACK_POINTER && p->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) {
|
||||
pr = snprintf(ret, XOPBUFSZ, "[esp + %i]", p->exprBinOp.operands[1]->exprPrim.val);
|
||||
snprintf(ret, XOPBUFSZ, "[esp + %i]", p->exprBinOp.operands[1]->exprPrim.val);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} else if(e->nodeKind == AST_EXPR_STACK_POINTER) {
|
||||
pr = snprintf(ret, XOPBUFSZ, "esp");
|
||||
snprintf(ret, XOPBUFSZ, "esp");
|
||||
} else if(e->nodeKind == AST_EXPR_VAR) {
|
||||
ScopeItem *v = e->exprVar.thing;
|
||||
|
||||
if(v->kind == SCOPEITEM_VAR) {
|
||||
return xv_sz(v, sz);
|
||||
} else if(v->kind == SCOPEITEM_SYMBOL) {
|
||||
pr = snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), v->data.symbol.name);
|
||||
snprintf(ret, XOPBUFSZ, "%s [%s]", spec(sz), v->data.symbol.name);
|
||||
} else abort();
|
||||
} else if(e->nodeKind == AST_EXPR_PRIMITIVE) {
|
||||
pr = snprintf(ret, XOPBUFSZ, "%s %i", spec(type_size(e->exprPrim.type)), e->exprPrim.val);
|
||||
snprintf(ret, XOPBUFSZ, "%s %i", spec(type_size(e->exprPrim.type)), e->exprPrim.val);
|
||||
} 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 == SCOPEITEM_SYMBOL) {
|
||||
pr = 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 {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(pr < XOPBUFSZ && "XOPBUF OVERFLOW");
|
||||
|
||||
bufidx = (bufidx + 1) % XOPBUFS;
|
||||
|
||||
return ret;
|
||||
@ -326,7 +322,7 @@ void cg_chunk(CGState *cg, AST *a) {
|
||||
puts("push ecx");
|
||||
puts("push edx");
|
||||
|
||||
int argCount = e->exprCall.what->expression.type->pointer.of->function.argCount;
|
||||
int argCount = e->exprCall.what->expression.type->function.argCount;
|
||||
|
||||
size_t argSize = 0;
|
||||
|
||||
@ -336,11 +332,9 @@ void cg_chunk(CGState *cg, AST *a) {
|
||||
argSize += (type_size(e->exprCall.args[i]->expression.type) + 3) & ~3;
|
||||
}
|
||||
|
||||
if(e->exprCall.what->nodeKind == AST_EXPR_VAR && e->exprCall.what->exprVar.thing->kind == SCOPEITEM_SYMBOL) {
|
||||
assert(e->exprCall.what->nodeKind == AST_EXPR_VAR && e->exprCall.what->exprVar.thing->kind == SCOPEITEM_SYMBOL);
|
||||
|
||||
printf("call %s\n", e->exprCall.what->exprVar.thing->data.symbol.name);
|
||||
} else {
|
||||
printf("call %s\n", xop(cg->tlc, e->exprCall.what));
|
||||
}
|
||||
|
||||
if(argSize) printf("add esp, %lu\n", argSize);
|
||||
|
||||
@ -568,7 +562,6 @@ static void callee_saved_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chun
|
||||
offset->nodeKind = AST_EXPR_PRIMITIVE;
|
||||
offset->type = primitive_parse("u32");
|
||||
offset->val = this->calleeOffsets[i];
|
||||
offset->stackGrowth = true;
|
||||
|
||||
ASTExprBinaryOp *sum = calloc(1, sizeof(*sum));
|
||||
sum->nodeKind = AST_EXPR_BINARY_OP;
|
||||
@ -619,7 +612,6 @@ static void callee_saved_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chun
|
||||
offset->nodeKind = AST_EXPR_PRIMITIVE;
|
||||
offset->type = primitive_parse("u32");
|
||||
offset->val = this->calleeOffsets[i];
|
||||
offset->stackGrowth = true;
|
||||
|
||||
ASTExprBinaryOp *sum = calloc(1, sizeof(*sum));
|
||||
sum->nodeKind = AST_EXPR_BINARY_OP;
|
||||
|
@ -215,15 +215,12 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST *
|
||||
} else if(s->stmtAssign.what && s->stmtAssign.what->nodeKind == AST_EXPR_VAR && s->stmtAssign.what->exprVar.thing->kind == SCOPEITEM_VAR && s->stmtAssign.to->nodeKind == AST_EXPR_CALL) {
|
||||
ASTExprCall *call = &s->stmtAssign.to->exprCall;
|
||||
|
||||
int argCount = call->what->expression.type->pointer.of->function.argCount;
|
||||
int argCount = call->what->expression.type->function.argCount;
|
||||
|
||||
for(int i = 0; i < argCount; i++) {
|
||||
if(is_xop(call->args[i]) == XOP_NOT_XOP) {
|
||||
call->args[i] = xopify(tlc, chu, stmtPrev, s, call->args[i]);
|
||||
this->effective = 1;
|
||||
|
||||
// Xopify one argument at a time otherwise stmtPrev becomes incorrect
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if(s->stmtAssign.to && s->stmtAssign.to->nodeKind == AST_EXPR_UNARY_OP && s->stmtAssign.to->exprUnOp.operator == UNOP_NEGATE && !ast_expression_equal(s->stmtAssign.what, s->stmtAssign.to->exprUnOp.operand)) {
|
||||
@ -376,7 +373,6 @@ static void pre_dumb_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, A
|
||||
offset->nodeKind = AST_EXPR_PRIMITIVE;
|
||||
offset->type = primitive_parse("u32");
|
||||
offset->val = 4 + i * 4;
|
||||
offset->stackGrowth = true;
|
||||
|
||||
ASTExprBinaryOp *sum = calloc(1, sizeof(*sum));
|
||||
sum->nodeKind = AST_EXPR_BINARY_OP;
|
||||
|
Loading…
Reference in New Issue
Block a user