Bit Negating now works properly for different types
This commit is contained in:
@@ -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;
|
||||
|
||||
40
main.cpp
40
main.cpp
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user