Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ast/ast/ast_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ struct Type {
struct TypeParam* type_param;
struct ArrayType* array_type;
struct PointerType* pointer_type;

// '#', stands for anything,
// always has highest native width of the architecture,
// e.g. x86: 8 bytes, avr: 2 bytes
bool is_anytype;
};

struct TypeParam {
Expand Down
2 changes: 1 addition & 1 deletion ast/test/test_str_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ void test_ast_str_expr() {

char* s = str_expr(&e);

assert(strcmp(s, "-45*-45") == 0);
assert(strcmp(s, "-45 * -45") == 0);

free_un_op_term(u2);
free(s);
Expand Down
1 change: 1 addition & 0 deletions ast/util/copy_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ struct Type* copy_type(struct Type* t) {
res->type_param = NULL;
res->array_type = NULL;
res->pointer_type = NULL;
res->is_anytype = t->is_anytype;

if (t->basic_type != NULL) { res->basic_type = copy_basic_type(t->basic_type); }
if (t->type_param != NULL) { res->type_param = copy_type_param(t->type_param); }
Expand Down
4 changes: 4 additions & 0 deletions ast/util/equals_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ bool eq_type(struct Type* a, struct Type* b) {

if (a->pointer_type != NULL) { return eq_pointertype(a->pointer_type, b->pointer_type); }

if (a->is_anytype && b->is_anytype) {
return true;
}

return false;
}

Expand Down
21 changes: 18 additions & 3 deletions ast/util/str_ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,10 @@ char* str_type(struct Type* t) {

if (t->pointer_type != NULL) { return str_pointer_type(t->pointer_type); }

if (t->is_anytype) {
return strdup("#");
}

error("str_type");
return NULL;
}
Expand Down Expand Up @@ -494,15 +498,15 @@ char* str_expr(struct Expr* e) {
return NULL;
}

uint16_t l = strlen(strTerm1) + strlen(strO) + strlen(strTerm2) + 1;
uint16_t l = strlen(strTerm1) + strlen(strO) + strlen(strTerm2) + 3;

char* res = malloc(sizeof(char) * l);

if (!res) {
return NULL;
}

sprintf(res, "%s%s%s", strTerm1, strO, strTerm2);
sprintf(res, "%s %s %s", strTerm1, strO, strTerm2);

free(strTerm1);

Expand All @@ -512,6 +516,7 @@ char* str_expr(struct Expr* e) {
return res;
}

// @returns NULL on error
char* str_op(enum OP o) {

char* res = malloc(sizeof(char) * 16);
Expand All @@ -533,8 +538,18 @@ char* str_op(enum OP o) {
case OP_OR: str = "|"; break;
case OP_XOR: str = "^"; break;

// relational
case OP_EQ: str = "=="; break;
case OP_NEQ: str = "!="; break;
case OP_GE: str = ">="; break;
case OP_GT: str = ">"; break;
case OP_LE: str = "<="; break;
case OP_LT: str = "<"; break;

//should not happen
default: str = "fix str_op"; break;
default:
free(res);
return NULL;
}

sprintf(res, "%s", str);
Expand Down
6 changes: 6 additions & 0 deletions compiler/main/typechecker/tc_ifstmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ bool tc_ifstmt(struct IfStmt* i, struct TCCtx* tcctx) {

error_snippet(tcctx, msg, TC_ERR_CONDITION_REQUIRES_BOOL);

char* s2 = str_type(type);

fprintf(stderr, "actual type: %s\n\n", s2);

free(s2);

free(msg);

return false;
Expand Down
3 changes: 2 additions & 1 deletion compiler/main/typechecker/tc_retstmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

//Typechecker Includes
#include "_tc.h"
#include "typechecker/type_contains/tc_type_contains.h"
#include "typechecker/util/tc_errors.h"
#include "typechecker/util/tc_utils.h"
#include "tcctx.h"
Expand All @@ -31,7 +32,7 @@ bool tc_retstmt(struct RetStmt* r, struct TCCtx* tcctx) {

if (is_integer_type(returnType) && is_integer_type(returnedType)) { return true; }

if (!eq_type(returnType, returnedType)) {
if (!tc_type_contains(returnType, returnedType)) {

char* s1 = str_type(returnType);
char* s2 = str_type(returnedType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ bool tc_pointer_type_contains(struct PointerType* expect, struct Type* actual) {
struct PointerType* apt = actual->pointer_type;

// pointers of same underlying type can be assigned to each other
return eq_type(expect->element_type, apt->element_type);
return tc_type_contains(expect->element_type, apt->element_type);
}
4 changes: 4 additions & 0 deletions compiler/main/typechecker/type_contains/tc_type_contains.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@

bool tc_type_contains(struct Type* expect, struct Type* actual) {

if (expect->is_anytype || actual->is_anytype) {
return true;
}

if (expect->pointer_type != NULL) {

return tc_pointer_type_contains(expect->pointer_type, actual);
Expand Down
24 changes: 18 additions & 6 deletions compiler/main/typeinference/typeinfer_expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static struct Type* infer_type_expr_primitive(struct ST* st, struct Expr2Types*

static struct Type* infer_type_expr_both_tparam(struct ST* st, struct TypeParam* tp1, enum OP op, struct TypeParam* tp2);

static struct Type* infer_type_expr_ptr_arithmetic(struct ST* st, struct Type* t1, struct Type* t2);
static struct Type* infer_type_expr_ptr_arithmetic(struct ST* st, struct Type* t1, struct Type* t2, enum OP op);

static void typeinfer_err_fatal(char* opt_str) {
fprintf(stderr, "%s\n", opt_str);
Expand All @@ -44,10 +44,10 @@ struct Type* infer_type_expr(struct ST* st, struct Expr* expr) {
}

if (type1->pointer_type) {
return infer_type_expr_ptr_arithmetic(st, type1, type2);
return infer_type_expr_ptr_arithmetic(st, type1, type2, op);
}
if (type2->pointer_type) {
return infer_type_expr_ptr_arithmetic(st, type2, type1);
return infer_type_expr_ptr_arithmetic(st, type2, type1, op);
}

struct BasicType* btw1 = type1->basic_type;
Expand Down Expand Up @@ -82,7 +82,7 @@ struct Type* infer_type_expr(struct ST* st, struct Expr* expr) {
return infer_type_expr_primitive(st, &e2t);
}

static struct Type* infer_type_expr_ptr_arithmetic(struct ST* st, struct Type* t1, struct Type* t2) {
static struct Type* infer_type_expr_ptr_arithmetic(struct ST* st, struct Type* t1, struct Type* t2, enum OP op) {

struct PointerType* pt = t1->pointer_type;

Expand All @@ -91,10 +91,22 @@ static struct Type* infer_type_expr_ptr_arithmetic(struct ST* st, struct Type* t
return NULL;
}

if (t2->pointer_type) {
if (op == OP_EQ || op == OP_NEQ || op == OP_GE || op == OP_GT || op == OP_LE || op == OP_LT) {
return typeFromStrPrimitive(st, "bool");
}
}

if (t2->basic_type && t2->basic_type->simple_type) {
struct SimpleType* st = t2->basic_type->simple_type;
struct SimpleType* stype = t2->basic_type->simple_type;

if (stype->primitive_type && stype->primitive_type->is_int_type) {

if (op == OP_EQ || op == OP_NEQ || op == OP_GE || op == OP_GT || op == OP_LE || op == OP_LT) {

return typeFromStrPrimitive(st, "bool");
}

if (st->primitive_type && st->primitive_type->is_int_type) {
return t1;
}
}
Expand Down
4 changes: 2 additions & 2 deletions docs/html/grammar.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ <h2>Method</h2>

<h2>Types</h2>

<a id="type">Type</a> ::= <a href="#basictype">BasicType</a> | <a href="#typeparam">TypeParam</a> | <a href="#arraytype">ArrayType</a> | <a href="#pointertype">PointerType</a>
<a id="type">Type</a> ::= <a href="#basictype">BasicType</a> | <a href="#typeparam">TypeParam</a> | <a href="#arraytype">ArrayType</a> | <a href="#pointertype">PointerType</a> | #
<br><br>

<a id="basictype">BasicType</a> ::= <a href="#simpletype">SimpleType</a> | '(' <a href="#subrtype">SubrType</a> ')'
Expand All @@ -78,7 +78,7 @@ <h2>Types</h2>
<a id="subrtype">SubrType</a> ::= '(' <a href="#type">Type</a>* ')' arrow <a href="#type">Type</a>
<br><br>

<a id="structtype">StructType</a> ::= uppercase alphanumeric* | "#"
<a id="structtype">StructType</a> ::= uppercase alphanumeric*
<br><br>

<a id="typeparam">TypeParam</a> ::= "?T" digit
Expand Down
13 changes: 13 additions & 0 deletions examples/stdlib/base/allocator/alloc_0_bytes/alloc_0_bytes.dg
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

fn main () -> int {

local *uint8 ptr;

ptr = malloc(0);

if ptr != 0 {
return 1;
}

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
20 changes: 20 additions & 0 deletions examples/stdlib/base/allocator/loop_test/loop_test.dg
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@

fn main () -> int {

// test that the allocations do not exhaus memory

for i in 0 .. 10000 {

*uint64 p = malloc(3000);

if p == 0 {
return 1;
}

if free(p) != 0 {
return 1;
}
}

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
19 changes: 19 additions & 0 deletions examples/stdlib/base/allocator/no_overlap/no_overlap.dg
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

fn main () -> int {

*uint64 ptr1 = malloc(30);
*uint64 ptr2 = malloc(30);

if ((ptr1 + 30) > ptr2 && (ptr1 <= ptr2)){
return 1;
}

if ((ptr2 + 30) > ptr1 && (ptr2 <= ptr1)){
return 1;
}

free(ptr1);
free(ptr2);

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
35 changes: 35 additions & 0 deletions examples/stdlib/base/allocator/realloc_test/realloc_test.dg
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

fn main () -> int {

*uint8 p1 = malloc(4096);

if p1 == 0 {
return 1;
}

*p1 = 9;

*uint8 p2 = realloc(p1, 8192);

if p2 == 0 {
return 2;
}

if *p2 != 9 {
return 3;
}

if p1 == p2 {
// it should not re-use that block, it is too small
return 4;
}

*uint8 p3 = realloc(p2, 4096);

if p3 != p2 {
// it should re-use the block, it is big enough
return 5;
}

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0
Empty file.
34 changes: 34 additions & 0 deletions examples/stdlib/base/allocator/use_allocator/use_allocator.dg
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

fn main () -> int {

local *uint8 ptr;

ptr = malloc(329);

if ptr == 0 {
return 2;
}

free(ptr);

ptr = malloc(8349);

if ptr == 0 {
return 3;
}

local *uint8 p;
p = ptr;

p += 100;
*p = 84;
p += 10;
*p = 92;
p -= 10;

uint8 res = *p;

free(ptr);

return res;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
84
Empty file.
2 changes: 0 additions & 2 deletions parser/main/astnodes/types/SimpleType.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ struct SimpleType* makeSimpleType(struct TokenList* tokens) {
break;

case TYPEID:
case ANYTYPE:

res->struct_type = makeStructType(copy);
break;

Expand Down
5 changes: 5 additions & 0 deletions parser/main/astnodes/types/Type.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ struct Type* makeType2(struct TokenList* tokens) {
res->type_param = NULL;
res->array_type = NULL;
res->pointer_type = NULL;
res->is_anytype = false;

struct Token* head = list_head(copy);

Expand All @@ -89,6 +90,10 @@ struct Type* makeType2(struct TokenList* tokens) {
res->type_param = makeTypeParam(copy);
if (res->type_param != NULL) { goto end; }
break;
case ANYTYPE:
list_consume(copy, 1);
res->is_anytype = true;
goto end;
default:
res->basic_type = makeBasicType2(copy);
if (res->basic_type != NULL) { goto end; }
Expand Down
Loading