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
gen_simple_decl_prefix(Ast_Resolved_Type *ast){
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_LAMBDA:break;
case TYPE_ENUM:
@@ -37,7 +37,12 @@ function void
gen_simple_decl_postfix(Ast_Resolved_Type *ast){
switch(ast->kind){
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_ENUM: case TYPE_STRUCT:break;
default: name(ast);
@@ -59,14 +64,13 @@ gen_simple_decl(Ast_Resolved_Type *ast, Intern_String name){
gen_simple_decl_prefix(ast);
if(name.len) {
gen("%s", name.str);
gen_simple_decl_postfix(ast);
}
gen_simple_decl_postfix(ast);
}
}
function void
gen_value(Value a){
// gen("%s", docname(a.type));
switch(a.type->kind){
CASE_INT: {
Scratch scratch;
@@ -94,13 +98,30 @@ gen_expr(Ast_Expr *ast){
}
CASE(INDEX, Index){
Sym *sym = resolved_get(node);
if(is_array(sym->type)){
gen("(");
gen("(");
gen("(");
gen_simple_decl(sym->type->arr.base, {});
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();
}
@@ -123,11 +144,11 @@ gen_expr(Ast_Expr *ast){
}
}
else{
gen("(");
if(!token_is_assign(node->op)) gen("(");
gen_expr(node->left);
gen("%s", name(node->op));
gen_expr(node->right);
gen(")");
if(!token_is_assign(node->op)) gen(")");
}
BREAK();
}
@@ -153,7 +174,10 @@ gen_expr(Ast_Expr *ast){
CASE(CALL, Call){
// @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_simple_decl(node->type, {});
gen(")");
@@ -177,6 +201,9 @@ gen_expr(Ast_Expr *ast){
if(!node->exprs.is_last(&it)) gen(", ");
}
gen("}");
if(is_array(node->type)){
gen("}");
}
}
else{
gen_expr(node->name);
@@ -240,10 +267,21 @@ gen_ast(Ast *ast){
CASE(VAR, Var){
Sym *sym = resolved_get(node);
if(is_array(sym->type)){
gen("Slice %s", node->name.str);
} else{
gen_simple_decl(sym->type, node->name);
}
if(node->expr){
gen(" = ");
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(";");
BREAK();
@@ -498,3 +536,15 @@ compile_file(String filename){
String result = compile_string(filecontent, filename);
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_NEW(Array, ARRAY, pos, AST_EXPR);
result->expr = expr;
result->expr->parent = result;
if(result->expr) result->expr->parent = result;
return result;
}

View File

@@ -84,4 +84,6 @@ Custom_Data :: struct
thing: S32
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(){
String string_to_lex = LIT("Identifier 2425525 Not_Number");
Token token_array[32];
Slice token_array = (Slice){32, (Token [32]){}};
S64 token_count = 0;
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]))){
(t.kind=0);
(t.str=(&(string_to_lex.str[i])));
(t.len=i);
t.kind=0;
t.str=(&(string_to_lex.str[i]));
t.len=i;
for(;is_numeric((string_to_lex.str[i]));){
(i+=1);
i+=1;
}
(t.len=(i-t.len));
((token_array[(token_count++)])=t);
t.len=(i-t.len);
(((Token *)token_array.data)[(token_count++)])=t;
}
}
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);
}
}

View File

@@ -509,7 +509,7 @@ resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){
}
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
assert(right->kind == AST_IDENT);
@@ -523,6 +523,19 @@ field_access_string(Ast_Expr *right){
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
resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_resolve){
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 []
Operand type = resolve_expr(node->base);
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);
return operand_type(resolved);
BREAK();
}
CASE(LAMBDA, Lambda){
return resolve_lambda(node);
BREAK();
}
CASE(INDEX, Index){
Operand left = resolve_expr(node->expr);
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)){
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);
BREAK();
}
CASE(LAMBDA, Lambda){
return resolve_lambda(node);
BREAK();
}
CASE(CALL, Call){
Operand name = resolve_expr(node->name);
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;
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;
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);
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{
type_complete(type);
@@ -1094,9 +1113,9 @@ test_types(){
parse_init(&ctx, scratch, scratch);
pctx = &ctx;
Ast_Resolved_Type *array_type1 = type_array(type_s64, 32);
Ast_Resolved_Type *array_type2 = type_array(type_s64, 32);
Ast_Resolved_Type *array_type3 = type_array(type_s64, 48);
Ast_Resolved_Type *array_type1 = type_array(type_s64, 1, 32);
Ast_Resolved_Type *array_type2 = type_array(type_s64, 1, 32);
Ast_Resolved_Type *array_type3 = type_array(type_s64, 1, 48);
assert(array_type1 == array_type2);
assert(array_type2 != array_type3);
Ast_Resolved_Type *pointer_type1 = type_pointer(type_s64);
@@ -1108,14 +1127,14 @@ test_types(){
assert(pointer_type3 == pointer_type4);
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_type2 = type_lambda(0, types[0], types);
assert(func_type1 == func_type2);
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);
}
types.add(type_s64);

View File

@@ -287,7 +287,11 @@ type_pointer(Ast_Resolved_Type *base){
}
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));
Ast_Resolved_Type *result = (Ast_Resolved_Type *)map_get(&pctx->type_map, hash);
if(result){

View File

@@ -88,6 +88,7 @@ struct Ast_Resolved_Member{
U64 offset;
};
#define ARRAY_SIZE_INFERRED (-1)
struct Ast_Resolved_Type{
Ast_Resolved_Type_Kind kind;
SizeU size;
@@ -98,7 +99,7 @@ struct Ast_Resolved_Type{
Ast_Resolved_Type *base;
struct{
Ast_Resolved_Type *base;
SizeU size;
S64 size;
}arr;
struct{
Array<Ast_Resolved_Member> members;