Bit Negating now works properly for different types

This commit is contained in:
Krzosa Karol
2022-06-06 17:14:42 +02:00
parent 7173557d26
commit d042251c21
4 changed files with 57 additions and 44 deletions

View File

@@ -127,6 +127,8 @@ bigint_copy(Allocator *allocator, BigInt *src){
}
dest.is_negative = src->is_negative;
dest.digit_count = src->digit_count;
count_bigint_alloc();
dest.digits = exp_alloc_array(allocator, uint64_t, dest.digit_count, AF_ZeroMemory);
memcpy(dest.digits, src->digits, sizeof(uint64_t) * dest.digit_count);
return dest;

View File

@@ -31,6 +31,45 @@ For now I don't thing it should be overloadable.
-------------------------------------------------------------------------------
Type resolution cases
CONST :: expr - dont need to handle
make new symbol
val := expr (1)
convert untyped to typed default
check bounds
make new symbol
call(default:type = expr) (1)
val: type = expr (1)
convert untyped to typed based on type
make sure expr.type == type
check bounds
expr == expr (2)
expr * expr (2)
make sure compatible types, floats with ints are ok(convert to float)
if only one of them is typed convert the untyped to typed
if both types typed make sure they are the same
check bounds
!expr
make sure correct type
return bool
compound(expr)
call(expr, expr)
convert untyped to matching typed
check if types match
cast(expr: type)
convert from untyped to typed
convert between typed to other typed
check if types compatible
@todo
[ ] - Fix casting
[ ] - Passing down program to compile through command line
@@ -59,6 +98,7 @@ For now I don't thing it should be overloadable.
[ ] - [Using] keyword that brings in the struct enviroment into current scope etc.
[ ] - Constant arrays that evaluate fully at compile time
[ ] - Rust like enum where you associate values(other structs) with keys
[ ] - Compound that zeros values - .{} , Compound that assumes defaults from struct definition - {}
@donzo
[x] - Test new operators, add constant eval for them

View File

@@ -12,7 +12,7 @@ unary_test :: ()
notb := !true
neg64: S64 = ~int_val
neg32: S32 = ~int_val
// big_neg32: U32 = ~41512512 // This doesn't work cause we are negating untyped
big_neg32: U32 = ~cast(41512512: U32)
// uns: U64 = -int_val
// int_float: S64 = float_val

View File

@@ -105,45 +105,6 @@ convert_untyped(Token *pos, Value a, Ast_Resolved_Type *new_type){
return a;
}
/*
Type resolution cases
val := expr
convert untyped to typed default
check bounds
make new symbol
CONST :: expr
make new symbol
call(default:type = expr)
val: type = expr
convert untyped to typed based on type
make sure expr.type == type
check bounds
expr == expr
expr * expr
make sure compatible types, floats with ints are ok(convert to float)
if only one of them is typed convert the untyped to typed
if both types typed make sure they are the same
check bounds
!expr
make sure correct type
return bool
call(expr, expr)
convert untyped to matching typed
check if types match
cast(expr: type)
convert from untyped to typed
convert between typed to other typed
check if types compatible
*/
function void
match_values(Token *pos, Value *a, Value *b){
if(is_typed(a->type) && is_typed(b->type)){
@@ -269,6 +230,15 @@ eval_binary(Token *pos, Token_Kind op, Value a, Value b){
return result;
}
function S64
digit_count(Value a){
S64 digit_count = a.big_int_val.digit_count*64;
if(is_typed(a.type)){
digit_count = a.type->size*8;
}
return digit_count;
}
function Value
eval_unary(Token *pos, Token_Kind op, Value a){
BigInt result = {};
@@ -289,13 +259,15 @@ eval_unary(Token *pos, Token_Kind op, Value a){
}
} break;
case TK_Neg:{
switch(a.type->kind){
CASE_SINT: case TYPE_UNTYPED_INT:{
bigint_not(&result, &a.big_int_val, a.big_int_val.digit_count*64, 1);
bigint_not(&result, &a.big_int_val, digit_count(a), 1);
return value_int(result);
}break;
CASE_UINT:{
bigint_not(&result, &a.big_int_val, a.big_int_val.digit_count*64, 0);
bigint_not(&result, &a.big_int_val, digit_count(a), 0);
return value_int(result);
}
default:goto failure;
@@ -471,7 +443,6 @@ resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){
Ast_Resolved_Type *type = resolve_typespec(it->typespec, AST_CANT_BE_NULL);
Operand default_value = resolve_expr(it->default_value, type);
resolve_var(it->pos, &default_value, type);
args.add(type);
}
@@ -493,7 +464,6 @@ resolve_lambda(Ast_Lambda *lambda, Sym *sym = 0){
For(lambda->args){
S64 i = lambda->args.get_index(&it);
Ast_Resolved_Type *type = args[i];
sym_var(it->name, type, it, INSERT_INTO_SCOPE);
}
For(lambda->block->stmts){
@@ -637,6 +607,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *lambda_to_res
found->flags = set_flag(found->flags, AST_ITEM_INCLUDED);
Operand op = resolve_expr(expr->item, found_type->type);
op.value = convert_untyped(node->pos, op.value, found_type->type);
if(found_type->type != op.type) parsing_error(expr->pos, "Invalid type of compound constructor item, expected %s got instead %s", type_names[found_type->type->kind], type_names[op.type->kind]);
}