Codegen basic arrays with size attached
This commit is contained in:
78
ccodegen.cpp
78
ccodegen.cpp
@@ -20,7 +20,7 @@ gen_indent(){
|
|||||||
function void
|
function void
|
||||||
gen_simple_decl_prefix(Ast_Resolved_Type *ast){
|
gen_simple_decl_prefix(Ast_Resolved_Type *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
case TYPE_POINTER:{gen_simple_decl_prefix(ast->base); gen("*");} break;
|
case TYPE_POINTER: gen_simple_decl_prefix(ast->base); gen("*"); break;
|
||||||
case TYPE_ARRAY: gen_simple_decl_prefix(ast->base); break;
|
case TYPE_ARRAY: gen_simple_decl_prefix(ast->base); break;
|
||||||
case TYPE_LAMBDA:break;
|
case TYPE_LAMBDA:break;
|
||||||
case TYPE_ENUM:
|
case TYPE_ENUM:
|
||||||
@@ -37,7 +37,12 @@ function void
|
|||||||
gen_simple_decl_postfix(Ast_Resolved_Type *ast){
|
gen_simple_decl_postfix(Ast_Resolved_Type *ast){
|
||||||
switch(ast->kind){
|
switch(ast->kind){
|
||||||
case TYPE_POINTER: gen_simple_decl_postfix(ast->base); break;
|
case TYPE_POINTER: gen_simple_decl_postfix(ast->base); break;
|
||||||
case TYPE_ARRAY: gen("[%d]", (int)ast->arr.size); gen_simple_decl_postfix(ast->arr.base); break;
|
case TYPE_ARRAY:
|
||||||
|
gen("[");
|
||||||
|
if(ast->arr.size != ARRAY_SIZE_INFERRED)
|
||||||
|
gen("%d", (int)ast->arr.size);
|
||||||
|
gen("]");
|
||||||
|
gen_simple_decl_postfix(ast->arr.base); break;
|
||||||
case TYPE_LAMBDA:break;
|
case TYPE_LAMBDA:break;
|
||||||
case TYPE_ENUM: case TYPE_STRUCT:break;
|
case TYPE_ENUM: case TYPE_STRUCT:break;
|
||||||
default: name(ast);
|
default: name(ast);
|
||||||
@@ -59,14 +64,13 @@ gen_simple_decl(Ast_Resolved_Type *ast, Intern_String name){
|
|||||||
gen_simple_decl_prefix(ast);
|
gen_simple_decl_prefix(ast);
|
||||||
if(name.len) {
|
if(name.len) {
|
||||||
gen("%s", name.str);
|
gen("%s", name.str);
|
||||||
gen_simple_decl_postfix(ast);
|
|
||||||
}
|
}
|
||||||
|
gen_simple_decl_postfix(ast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function void
|
function void
|
||||||
gen_value(Value a){
|
gen_value(Value a){
|
||||||
// gen("%s", docname(a.type));
|
|
||||||
switch(a.type->kind){
|
switch(a.type->kind){
|
||||||
CASE_INT: {
|
CASE_INT: {
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
@@ -94,13 +98,30 @@ gen_expr(Ast_Expr *ast){
|
|||||||
}
|
}
|
||||||
|
|
||||||
CASE(INDEX, Index){
|
CASE(INDEX, Index){
|
||||||
gen("(");
|
Sym *sym = resolved_get(node);
|
||||||
gen_expr(node->expr);
|
if(is_array(sym->type)){
|
||||||
|
gen("(");
|
||||||
|
gen("(");
|
||||||
|
|
||||||
gen("[");
|
gen("(");
|
||||||
gen_expr(node->index);
|
gen_simple_decl(sym->type->arr.base, {});
|
||||||
gen("]");
|
gen("*)");
|
||||||
gen(")");
|
gen_expr(node->expr);
|
||||||
|
gen(".data)");
|
||||||
|
|
||||||
|
|
||||||
|
gen("[");
|
||||||
|
gen_expr(node->index);
|
||||||
|
gen("]");
|
||||||
|
gen(")");
|
||||||
|
} else{
|
||||||
|
gen("(");
|
||||||
|
gen_expr(node->expr);
|
||||||
|
gen("[");
|
||||||
|
gen_expr(node->index);
|
||||||
|
gen("]");
|
||||||
|
gen(")");
|
||||||
|
}
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,11 +144,11 @@ gen_expr(Ast_Expr *ast){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
gen("(");
|
if(!token_is_assign(node->op)) gen("(");
|
||||||
gen_expr(node->left);
|
gen_expr(node->left);
|
||||||
gen("%s", name(node->op));
|
gen("%s", name(node->op));
|
||||||
gen_expr(node->right);
|
gen_expr(node->right);
|
||||||
gen(")");
|
if(!token_is_assign(node->op)) gen(")");
|
||||||
}
|
}
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
@@ -153,7 +174,10 @@ gen_expr(Ast_Expr *ast){
|
|||||||
|
|
||||||
CASE(CALL, Call){
|
CASE(CALL, Call){
|
||||||
// @todo: Reach into map instead of direct lookup
|
// @todo: Reach into map instead of direct lookup
|
||||||
if(is_struct(node->type) || is_array(node->type)){ // @todo: Should this be type_type maybe???
|
if(is_struct(node->type) || is_array(node->type)){
|
||||||
|
if(is_array(node->type)){
|
||||||
|
gen("(Slice){%d, ", node->exprs.len);
|
||||||
|
}
|
||||||
gen("(");
|
gen("(");
|
||||||
gen_simple_decl(node->type, {});
|
gen_simple_decl(node->type, {});
|
||||||
gen(")");
|
gen(")");
|
||||||
@@ -177,6 +201,9 @@ gen_expr(Ast_Expr *ast){
|
|||||||
if(!node->exprs.is_last(&it)) gen(", ");
|
if(!node->exprs.is_last(&it)) gen(", ");
|
||||||
}
|
}
|
||||||
gen("}");
|
gen("}");
|
||||||
|
if(is_array(node->type)){
|
||||||
|
gen("}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
gen_expr(node->name);
|
gen_expr(node->name);
|
||||||
@@ -240,10 +267,21 @@ gen_ast(Ast *ast){
|
|||||||
|
|
||||||
CASE(VAR, Var){
|
CASE(VAR, Var){
|
||||||
Sym *sym = resolved_get(node);
|
Sym *sym = resolved_get(node);
|
||||||
gen_simple_decl(sym->type, node->name);
|
|
||||||
|
if(is_array(sym->type)){
|
||||||
|
gen("Slice %s", node->name.str);
|
||||||
|
} else{
|
||||||
|
gen_simple_decl(sym->type, node->name);
|
||||||
|
}
|
||||||
|
|
||||||
if(node->expr){
|
if(node->expr){
|
||||||
gen(" = ");
|
gen(" = ");
|
||||||
gen_expr(node->expr);
|
gen_expr(node->expr);
|
||||||
|
} else if(is_array(sym->type)){
|
||||||
|
gen(" = (Slice){%d, (", sym->type->arr.size);
|
||||||
|
gen_simple_decl(sym->type, {});
|
||||||
|
gen("){}");
|
||||||
|
gen("}");
|
||||||
}
|
}
|
||||||
gen(";");
|
gen(";");
|
||||||
BREAK();
|
BREAK();
|
||||||
@@ -498,3 +536,15 @@ compile_file(String filename){
|
|||||||
String result = compile_string(filecontent, filename);
|
String result = compile_string(filecontent, filename);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct Custom_Data{
|
||||||
|
S32 thing;
|
||||||
|
}Custom_Data;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct Slice{
|
||||||
|
S64 len;
|
||||||
|
void *data;
|
||||||
|
}Slice;
|
||||||
|
|
||||||
|
Slice thing = (Slice){2, (Custom_Data []){(Custom_Data ){1}, (Custom_Data ){2}}};
|
||||||
@@ -409,7 +409,7 @@ function Ast_Array *
|
|||||||
ast_array(Token *pos, Ast_Expr *expr){
|
ast_array(Token *pos, Ast_Expr *expr){
|
||||||
AST_NEW(Array, ARRAY, pos, AST_EXPR);
|
AST_NEW(Array, ARRAY, pos, AST_EXPR);
|
||||||
result->expr = expr;
|
result->expr = expr;
|
||||||
result->expr->parent = result;
|
if(result->expr) result->expr->parent = result;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,4 +84,6 @@ Custom_Data :: struct
|
|||||||
thing: S32
|
thing: S32
|
||||||
|
|
||||||
array_test :: ()
|
array_test :: ()
|
||||||
pass
|
thing := []Custom_Data(Custom_Data(1), Custom_Data(2))
|
||||||
|
reference := thing
|
||||||
|
length := reference.len
|
||||||
18
program.c
18
program.c
@@ -58,23 +58,23 @@ Bool is_numeric(U8 c){
|
|||||||
}
|
}
|
||||||
void entry(){
|
void entry(){
|
||||||
String string_to_lex = LIT("Identifier 2425525 Not_Number");
|
String string_to_lex = LIT("Identifier 2425525 Not_Number");
|
||||||
Token token_array[32];
|
Slice token_array = (Slice){32, (Token [32]){}};
|
||||||
S64 token_count = 0;
|
S64 token_count = 0;
|
||||||
Token t;
|
Token t;
|
||||||
for(S64 i = 0;(i<string_to_lex.len);(i+=1)){
|
for(S64 i = 0;(i<string_to_lex.len);i+=1){
|
||||||
if(is_numeric((string_to_lex.str[i]))){
|
if(is_numeric((string_to_lex.str[i]))){
|
||||||
(t.kind=0);
|
t.kind=0;
|
||||||
(t.str=(&(string_to_lex.str[i])));
|
t.str=(&(string_to_lex.str[i]));
|
||||||
(t.len=i);
|
t.len=i;
|
||||||
for(;is_numeric((string_to_lex.str[i]));){
|
for(;is_numeric((string_to_lex.str[i]));){
|
||||||
(i+=1);
|
i+=1;
|
||||||
}
|
}
|
||||||
(t.len=(i-t.len));
|
t.len=(i-t.len);
|
||||||
((token_array[(token_count++)])=t);
|
(((Token *)token_array.data)[(token_count++)])=t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(S64 i = 0;(i<token_count);(i++)){
|
for(S64 i = 0;(i<token_count);(i++)){
|
||||||
Token *tk = (&(token_array[i]));
|
Token *tk = (&(((Token *)token_array.data)[i]));
|
||||||
printf("%.*s", ((S32 )tk->len), tk->str);
|
printf("%.*s", ((S32 )tk->len), tk->str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -509,7 +509,7 @@ resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Operand
|
function Operand
|
||||||
field_access_string(Ast_Expr *right){
|
field_access_builtin_string(Ast_Expr *right){
|
||||||
if(right->kind == AST_BINARY) invalid_codepath; // @todo entire field access needs a rework
|
if(right->kind == AST_BINARY) invalid_codepath; // @todo entire field access needs a rework
|
||||||
assert(right->kind == AST_IDENT);
|
assert(right->kind == AST_IDENT);
|
||||||
|
|
||||||
@@ -523,6 +523,19 @@ field_access_string(Ast_Expr *right){
|
|||||||
else invalid_return;
|
else invalid_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Operand
|
||||||
|
field_access_builtin_array(Ast_Expr *right){
|
||||||
|
if(right->kind == AST_BINARY) invalid_codepath; // @todo entire field access needs a rework
|
||||||
|
assert(right->kind == AST_IDENT);
|
||||||
|
|
||||||
|
auto a = (Ast_Atom *)right;
|
||||||
|
if(a->intern_val == pctx->intern("len"_s)){
|
||||||
|
return operand_lvalue(type_s64);
|
||||||
|
}
|
||||||
|
else invalid_return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function Operand
|
function Operand
|
||||||
resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_resolve){
|
resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_resolve){
|
||||||
if(!ast) return {}; // @todo: add option for better error prevention
|
if(!ast) return {}; // @todo: add option for better error prevention
|
||||||
@@ -554,19 +567,14 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
|||||||
// @todo: Arrays of inferred size []
|
// @todo: Arrays of inferred size []
|
||||||
Operand type = resolve_expr(node->base);
|
Operand type = resolve_expr(node->base);
|
||||||
if(type.type != type_type) parsing_error(node->pos, "Prefix array operator is only allowed on types");
|
if(type.type != type_type) parsing_error(node->pos, "Prefix array operator is only allowed on types");
|
||||||
Operand expr = require_const_int(node->expr, AST_CANT_BE_NULL);
|
Operand expr = require_const_int(node->expr, AST_CAN_BE_NULL);
|
||||||
|
|
||||||
Ast_Resolved_Type *resolved = type_array(type.type_val, bigint_as_unsigned(&expr.big_int_val));
|
Ast_Resolved_Type *resolved = type_array(type.type_val, node->expr ? 1 : 0, bigint_as_unsigned(&expr.big_int_val));
|
||||||
sym_type(resolved, node);
|
sym_type(resolved, node);
|
||||||
return operand_type(resolved);
|
return operand_type(resolved);
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
CASE(LAMBDA, Lambda){
|
|
||||||
return resolve_lambda(node);
|
|
||||||
BREAK();
|
|
||||||
}
|
|
||||||
|
|
||||||
CASE(INDEX, Index){
|
CASE(INDEX, Index){
|
||||||
Operand left = resolve_expr(node->expr);
|
Operand left = resolve_expr(node->expr);
|
||||||
Operand index = resolve_expr(node->index);
|
Operand index = resolve_expr(node->index);
|
||||||
@@ -576,10 +584,17 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
|||||||
if(!is_array(left.type) && !is_pointer(left.type)){
|
if(!is_array(left.type) && !is_pointer(left.type)){
|
||||||
parsing_error(node->pos, "Indexing variable that is not an [Array] or [Pointer], it's of type %s instead", docname(left.type));
|
parsing_error(node->pos, "Indexing variable that is not an [Array] or [Pointer], it's of type %s instead", docname(left.type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sym_new_resolved(SYM_VAR, {}, left.value, node);
|
||||||
return operand_lvalue(left.type->arr.base);
|
return operand_lvalue(left.type->arr.base);
|
||||||
BREAK();
|
BREAK();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CASE(LAMBDA, Lambda){
|
||||||
|
return resolve_lambda(node);
|
||||||
|
BREAK();
|
||||||
|
}
|
||||||
|
|
||||||
CASE(CALL, Call){
|
CASE(CALL, Call){
|
||||||
Operand name = resolve_expr(node->name);
|
Operand name = resolve_expr(node->name);
|
||||||
Ast_Resolved_Type *type = name.type;
|
Ast_Resolved_Type *type = name.type;
|
||||||
@@ -594,7 +609,8 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
|||||||
node->type = type;
|
node->type = type;
|
||||||
|
|
||||||
if(type->kind == TYPE_ARRAY){
|
if(type->kind == TYPE_ARRAY){
|
||||||
if(node->exprs.len > type->arr.size) parsing_error(node->pos, "compound statement has too many items for this type");
|
if(node->exprs.len > type->arr.size && type->arr.size != ARRAY_SIZE_INFERRED)
|
||||||
|
parsing_error(node->pos, "compound statement has too many items for this type");
|
||||||
Ast_Resolved_Type *item_type = type->arr.base;
|
Ast_Resolved_Type *item_type = type->arr.base;
|
||||||
|
|
||||||
For(node->exprs){
|
For(node->exprs){
|
||||||
@@ -850,7 +866,10 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
|
|||||||
|
|
||||||
sym_var({}, resolved_ident.type, node->left);
|
sym_var({}, resolved_ident.type, node->left);
|
||||||
if(is_string(type) && !required_to_be_const){
|
if(is_string(type) && !required_to_be_const){
|
||||||
result = field_access_string(node->right);
|
result = field_access_builtin_string(node->right);
|
||||||
|
}
|
||||||
|
else if(is_array(type) && !required_to_be_const){
|
||||||
|
result = field_access_builtin_array(node->right);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
type_complete(type);
|
type_complete(type);
|
||||||
@@ -1094,9 +1113,9 @@ test_types(){
|
|||||||
parse_init(&ctx, scratch, scratch);
|
parse_init(&ctx, scratch, scratch);
|
||||||
pctx = &ctx;
|
pctx = &ctx;
|
||||||
|
|
||||||
Ast_Resolved_Type *array_type1 = type_array(type_s64, 32);
|
Ast_Resolved_Type *array_type1 = type_array(type_s64, 1, 32);
|
||||||
Ast_Resolved_Type *array_type2 = type_array(type_s64, 32);
|
Ast_Resolved_Type *array_type2 = type_array(type_s64, 1, 32);
|
||||||
Ast_Resolved_Type *array_type3 = type_array(type_s64, 48);
|
Ast_Resolved_Type *array_type3 = type_array(type_s64, 1, 48);
|
||||||
assert(array_type1 == array_type2);
|
assert(array_type1 == array_type2);
|
||||||
assert(array_type2 != array_type3);
|
assert(array_type2 != array_type3);
|
||||||
Ast_Resolved_Type *pointer_type1 = type_pointer(type_s64);
|
Ast_Resolved_Type *pointer_type1 = type_pointer(type_s64);
|
||||||
@@ -1108,14 +1127,14 @@ test_types(){
|
|||||||
assert(pointer_type3 == pointer_type4);
|
assert(pointer_type3 == pointer_type4);
|
||||||
|
|
||||||
Array<Ast_Resolved_Type*> types = {scratch};
|
Array<Ast_Resolved_Type*> types = {scratch};
|
||||||
types.add(type_array(type_s64, 32));
|
types.add(type_array(type_s64, 1, 32));
|
||||||
Ast_Resolved_Type *func_type1 = type_lambda(0, types[0], types);
|
Ast_Resolved_Type *func_type1 = type_lambda(0, types[0], types);
|
||||||
Ast_Resolved_Type *func_type2 = type_lambda(0, types[0], types);
|
Ast_Resolved_Type *func_type2 = type_lambda(0, types[0], types);
|
||||||
assert(func_type1 == func_type2);
|
assert(func_type1 == func_type2);
|
||||||
|
|
||||||
Array<Ast_Resolved_Type*> types2 = {scratch};
|
Array<Ast_Resolved_Type*> types2 = {scratch};
|
||||||
{
|
{
|
||||||
types2.add(type_array(type_s64, 32));
|
types2.add(type_array(type_s64, 1, 32));
|
||||||
types2.add(type_s64);
|
types2.add(type_s64);
|
||||||
}
|
}
|
||||||
types.add(type_s64);
|
types.add(type_s64);
|
||||||
|
|||||||
@@ -287,7 +287,11 @@ type_pointer(Ast_Resolved_Type *base){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Ast_Resolved_Type *
|
function Ast_Resolved_Type *
|
||||||
type_array(Ast_Resolved_Type *base, SizeU size){
|
type_array(Ast_Resolved_Type *base, B32 size_present, S64 size){
|
||||||
|
if(!size_present){
|
||||||
|
size = ARRAY_SIZE_INFERRED;
|
||||||
|
}
|
||||||
|
|
||||||
U64 hash = hash_mix(hash_ptr(base), hash_u64(size));
|
U64 hash = hash_mix(hash_ptr(base), hash_u64(size));
|
||||||
Ast_Resolved_Type *result = (Ast_Resolved_Type *)map_get(&pctx->type_map, hash);
|
Ast_Resolved_Type *result = (Ast_Resolved_Type *)map_get(&pctx->type_map, hash);
|
||||||
if(result){
|
if(result){
|
||||||
|
|||||||
3
types.h
3
types.h
@@ -88,6 +88,7 @@ struct Ast_Resolved_Member{
|
|||||||
U64 offset;
|
U64 offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define ARRAY_SIZE_INFERRED (-1)
|
||||||
struct Ast_Resolved_Type{
|
struct Ast_Resolved_Type{
|
||||||
Ast_Resolved_Type_Kind kind;
|
Ast_Resolved_Type_Kind kind;
|
||||||
SizeU size;
|
SizeU size;
|
||||||
@@ -98,7 +99,7 @@ struct Ast_Resolved_Type{
|
|||||||
Ast_Resolved_Type *base;
|
Ast_Resolved_Type *base;
|
||||||
struct{
|
struct{
|
||||||
Ast_Resolved_Type *base;
|
Ast_Resolved_Type *base;
|
||||||
SizeU size;
|
S64 size;
|
||||||
}arr;
|
}arr;
|
||||||
struct{
|
struct{
|
||||||
Array<Ast_Resolved_Member> members;
|
Array<Ast_Resolved_Member> members;
|
||||||
|
|||||||
Reference in New Issue
Block a user