Codegen basic arrays with size attached

This commit is contained in:
Krzosa Karol
2022-06-07 17:38:15 +02:00
parent ec89defb5d
commit 9cdc5ee6c9
7 changed files with 118 additions and 42 deletions

View File

@@ -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){
Sym *sym = resolved_get(node);
if(is_array(sym->type)){
gen("("); gen("(");
gen("(");
gen("(");
gen_simple_decl(sym->type->arr.base, {});
gen("*)");
gen_expr(node->expr); gen_expr(node->expr);
gen(".data)");
gen("["); gen("[");
gen_expr(node->index); gen_expr(node->index);
gen("]"); gen("]");
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);
if(is_array(sym->type)){
gen("Slice %s", node->name.str);
} else{
gen_simple_decl(sym->type, node->name); 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}}};

View File

@@ -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;
} }

View File

@@ -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

View File

@@ -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);
} }
} }

View File

@@ -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);

View File

@@ -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){

View File

@@ -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;