Skip to content

Commit

Permalink
volatile type done
Browse files Browse the repository at this point in the history
  • Loading branch information
travisdoor committed Sep 16, 2019
1 parent f853ed2 commit 0b1c7f9
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 118 deletions.
4 changes: 2 additions & 2 deletions demos/simple_sdl_game/src/level.bl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ LEVEL_LAYER_HILLS1 :: 1;
LEVEL_LAYER_CLOUDS1 :: 2;
LEVEL_LAYER_HILLS2 :: 3;
LEVEL_LAYER_CLOUDS2 :: 4;
PLAYER_ID :: cast(usize) 0;
PLAYER_ID :: 0;

Level :: struct {
layers: [5]*LevelLayer,
Expand Down Expand Up @@ -132,4 +132,4 @@ level_layer_render :: fn (self: *LevelLayer, game: *Game) {
level_layer_update :: fn (self: *LevelLayer, dt: f32) {
self.x_position += self.x_speed * dt;
if self.x_position < -(cast(f32) ScreenWidth) { self.x_position = 0.f; }
};
};
2 changes: 1 addition & 1 deletion demos/simple_sdl_game/src/skyshooter.bl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ game_init :: fn (game: *Game) {
srand(666);
print("Initialize SDL.\n");

if SDL_Init(SDL_INIT_VIDEO) != 0 {
if SDL_Init(SDL_INIT_VIDEO) != -1 {
print("Unable to init SDL\n");
abort();
} else {
Expand Down
7 changes: 2 additions & 5 deletions examples/type_cast.bl
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
i := 666;

// type of the integer literal is changed to u64
j : u64 = 666;

// 'j' is implicitly casted to 'u32'
k : u32 = j;
j : u16 = 666;

// implicit cast on function call
fn (num: u16) {
fn (num: u64) {
} (j);

// explicit cast of 'f32' type to 's32'
Expand Down
78 changes: 37 additions & 41 deletions lib/bl/api/experimental/sdl2/sdl2.bl
Original file line number Diff line number Diff line change
Expand Up @@ -28,47 +28,43 @@

#link "SDL2"

SDL_INIT_TIMER :: 0x00000001;
SDL_INIT_AUDIO :: 0x00000010;
SDL_INIT_VIDEO :: 0x00000020;
SDL_INIT_JOYSTICK :: 0x00000200;
SDL_INIT_HAPTIC :: 0x00001000;
SDL_INIT_GAMECONTROLLER :: 0x00002000;
SDL_INIT_EVENTS :: 0x00004000;
SDL_INIT_NOPARACHUTE :: 0x00100000;
SDL_INIT_EVERYTHING :: SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO |
SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS;

SDL_WINDOW_FULLSCREEN :: 0x00000001;
SDL_WINDOW_OPENGL :: 0x00000002;
SDL_WINDOW_SHOWN :: 0x00000004;
SDL_WINDOW_HIDDEN :: 0x00000008;
SDL_WINDOW_BORDERLESS :: 0x00000010;
SDL_WINDOW_RESIZABLE :: 0x00000020;
SDL_WINDOW_MINIMIZED :: 0x00000040;
SDL_WINDOW_MAXIMIZED :: 0x00000080;
SDL_WINDOW_INPUTGRABBED :: 0x00000100;
SDL_WINDOW_INPUTFOCUS :: 0x00000200;
SDL_WINDOW_MOUSEFOCUS :: 0x00000400;
SDL_WINDOW_FULLSCREENDESKTOP :: SDL_WINDOW_FULLSCREEN | 0x00001000;
SDL_WINDOW_FOREIGN :: 0x00000800;
SDL_WINDOW_ALLOWHIGHDPI :: 0x00002000;
SDL_WINDOW_MOUSECAPTURE :: 0x00004000;
SDL_WINDOW_ALWAYSONTOP :: 0x00008000;
SDL_WINDOW_SKIPTASKBAR :: 0x00010000;
SDL_WINDOW_UTILITY :: 0x00020000;
SDL_WINDOW_TOOLTIP :: 0x00040000;
SDL_WINDOW_POPUPMENU :: 0x00080000;
SDL_WINDOW_VULKAN :: 0x10000000;

SDL_RENDERER_SOFTWARE :: 0x00000001;
SDL_RENDERER_ACCELERATED :: 0x00000002;
SDL_RENDERER_PRESENTVSYNC :: 0x00000004;
SDL_RENDERER_TARGETTEXTURE :: 0x00000008;

SDL_FLIP_NONE :: 0x00000000;
SDL_FLIP_HORIZONTAL :: 0x00000001;
SDL_FLIP_VERTICAL :: 0x00000002;
SDL_INIT_TIMER : u32 : 0x00000001;
SDL_INIT_AUDIO : u32 : 0x00000010;
SDL_INIT_VIDEO : u32 : 0x00000020;
SDL_INIT_JOYSTICK : u32 : 0x00000200;
SDL_INIT_HAPTIC : u32 : 0x00001000;
SDL_INIT_GAMECONTROLLER : u32 : 0x00002000;
SDL_INIT_EVENTS : u32 : 0x00004000;
SDL_INIT_NOPARACHUTE : u32 : 0x00100000;
SDL_INIT_EVERYTHING : u32 : SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS;
SDL_WINDOW_FULLSCREEN : u32 : 0x00000001;
SDL_WINDOW_OPENGL : u32 : 0x00000002;
SDL_WINDOW_SHOWN : u32 : 0x00000004;
SDL_WINDOW_HIDDEN : u32 : 0x00000008;
SDL_WINDOW_BORDERLESS : u32 : 0x00000010;
SDL_WINDOW_RESIZABLE : u32 : 0x00000020;
SDL_WINDOW_MINIMIZED : u32 : 0x00000040;
SDL_WINDOW_MAXIMIZED : u32 : 0x00000080;
SDL_WINDOW_INPUTGRABBED : u32 : 0x00000100;
SDL_WINDOW_INPUTFOCUS : u32 : 0x00000200;
SDL_WINDOW_MOUSEFOCUS : u32 : 0x00000400;
SDL_WINDOW_FULLSCREENDESKTOP : u32 : SDL_WINDOW_FULLSCREEN | 0x00001000;
SDL_WINDOW_FOREIGN : u32 : 0x00000800;
SDL_WINDOW_ALLOWHIGHDPI : u32 : 0x00002000;
SDL_WINDOW_MOUSECAPTURE : u32 : 0x00004000;
SDL_WINDOW_ALWAYSONTOP : u32 : 0x00008000;
SDL_WINDOW_SKIPTASKBAR : u32 : 0x00010000;
SDL_WINDOW_UTILITY : u32 : 0x00020000;
SDL_WINDOW_TOOLTIP : u32 : 0x00040000;
SDL_WINDOW_POPUPMENU : u32 : 0x00080000;
SDL_WINDOW_VULKAN : u32 : 0x10000000;
SDL_RENDERER_SOFTWARE : u32 : 0x00000001;
SDL_RENDERER_ACCELERATED : u32 : 0x00000002;
SDL_RENDERER_PRESENTVSYNC : u32 : 0x00000004;
SDL_RENDERER_TARGETTEXTURE : u32 : 0x00000008;
SDL_FLIP_NONE : u32 : 0x00000000;
SDL_FLIP_HORIZONTAL : u32 : 0x00000001;
SDL_FLIP_VERTICAL : u32 : 0x00000002;

SDL_EventType :: enum u32 {
FIRSTEVENT :: 0,
Expand Down
102 changes: 37 additions & 65 deletions src/mir.c
Original file line number Diff line number Diff line change
Expand Up @@ -940,9 +940,8 @@ analyze_stage_set_auto(Context *cnt, MirInstr **input, MirType *slot_type);
static AnalyzeStageState
analyze_stage_toany(Context *cnt, MirInstr **input, MirType *slot_type);

/* Do implicit cast if possible. */
static AnalyzeStageState
analyze_stage_set_const_int(Context *cnt, MirInstr **input, MirType *slot_type);
analyze_stage_set_volatile_expr(Context *cnt, MirInstr **input, MirType *slot_type);

/* Do implicit cast if possible. */
static AnalyzeStageState
Expand All @@ -951,27 +950,22 @@ analyze_stage_implicit_cast(Context *cnt, MirInstr **input, MirType *slot_type);
static AnalyzeStageState
analyze_stage_report_type_mismatch(Context *cnt, MirInstr **input, MirType *slot_type);

static AnalyzeStageState
analyze_stage_set_mutable_expr(Context *cnt, MirInstr **input, MirType *slot_type);

static const AnalyzeSlotConfig analyze_slot_conf_basic = {.count = 1,
.stages = {analyze_stage_load}};

static const AnalyzeSlotConfig analyze_slot_conf_default = {.count = 7,
static const AnalyzeSlotConfig analyze_slot_conf_default = {.count = 6,
.stages = {
analyze_stage_set_const_int,
analyze_stage_set_mutable_expr,
analyze_stage_set_volatile_expr,
analyze_stage_set_null,
analyze_stage_set_auto,
analyze_stage_load,
analyze_stage_implicit_cast,
analyze_stage_report_type_mismatch,
}};

static const AnalyzeSlotConfig analyze_slot_conf_full = {.count = 8,
static const AnalyzeSlotConfig analyze_slot_conf_full = {.count = 7,
.stages = {
analyze_stage_set_const_int,
analyze_stage_set_mutable_expr,
analyze_stage_set_volatile_expr,
analyze_stage_set_null,
analyze_stage_set_auto,
analyze_stage_toany,
Expand Down Expand Up @@ -1247,6 +1241,30 @@ static void
exec_copy_comptime_to_stack(Context *cnt, MirStackPtr dest_ptr, MirConstValue *src_value);

/* INLINES */

/* Determinate if instruction has volatile type, that means we can change type of the value during
* analyze pass as needed. This is used for constant integer literals. */
static inline bool
is_volatile_expr(MirInstr *instr)
{
MirType *type = instr->value.type;

if (!type) return false;
if (type->kind != MIR_TYPE_INT) return false;

switch (instr->kind) {
case MIR_INSTR_CONST:
/* Integer constant literals has always volatile type. */
return true;
case MIR_INSTR_UNOP:
return ((MirInstrUnop *)instr)->volatile_type;
case MIR_INSTR_BINOP:
return ((MirInstrBinop *)instr)->volatile_type;
default:
return false;
}
}

static inline bool
can_impl_cast(MirType *from, MirType *to)
{
Expand Down Expand Up @@ -4140,13 +4158,7 @@ reduce_instr(Context *cnt, MirInstr *instr)
}

case MIR_INSTR_UNOP: {
MirInstrUnop *unop = (MirInstrUnop *)instr;
exec_instr_unop(cnt, unop);

if (unop->mutate_to_literal) {
bl_log("mutate unop to const literal");
}

exec_instr_unop(cnt, (MirInstrUnop *)instr);
erase_instr(instr);
break;
}
Expand Down Expand Up @@ -4837,7 +4849,7 @@ analyze_instr_cast(Context *cnt, MirInstrCast *cast, bool analyze_op_only)
MirType *expr_type = cast->expr->value.type;

/* Setup const int type. */
if (analyze_stage_set_const_int(cnt, &cast->expr, dest_type) == ANALYZE_STAGE_BREAK) {
if (analyze_stage_set_volatile_expr(cnt, &cast->expr, dest_type) == ANALYZE_STAGE_BREAK) {
cast->op = MIR_CAST_NONE;
goto DONE;
}
Expand Down Expand Up @@ -5749,6 +5761,8 @@ analyze_instr_binop(Context *cnt, MirInstrBinop *binop)
*/
if (lhs->comptime && rhs->comptime) binop->base.comptime = true;

binop->volatile_type = is_volatile_expr(lhs) && is_volatile_expr(rhs);

return analyze_result(ANALYZE_PASSED, 0);
#undef is_valid
}
Expand All @@ -5757,43 +5771,17 @@ AnalyzeResult
analyze_instr_unop(Context *cnt, MirInstrUnop *unop)
{
MirType *type = unop->expr->value.type;
/*
if (unop->op == UNOP_NEG && unop->expr->kind == MIR_INSTR_CONST &&
type->kind == MIR_TYPE_INT) {
const uint64_t val = unop->expr->value.data.v_u64;
const int32_t desired_bits = count_bits(val);
if (desired_bits <= 32)
type = cnt->builtin_types.t_s32;
else if (desired_bits <= 64)
type = cnt->builtin_types.t_s64;
unref_instr(unop->expr);
erase_instr_tree(unop->expr);
mutate_instr(&unop->base, MIR_INSTR_CONST);
unop->base.comptime = true;
init_or_create_const_integer(cnt, &unop->base.value, type, val);
return analyze_result(ANALYZE_PASSED, 0);
}
*/

if (analyze_slot(cnt, &analyze_slot_conf_basic, &unop->expr, NULL) != ANALYZE_PASSED) {
return analyze_result(ANALYZE_FAILED, 0);
}

if (unop->op == UNOP_NEG && unop->expr->kind == MIR_INSTR_CONST &&
type->kind == MIR_TYPE_INT) {
unop->mutate_to_literal = true;
}

bl_assert(unop->expr && unop->expr->analyzed);
type = unop->expr->value.type;
bl_assert(type);
unop->base.value.type = type;

unop->base.comptime = unop->expr->comptime;
unop->volatile_type = is_volatile_expr(unop->expr);

return analyze_result(ANALYZE_PASSED, 0);
}
Expand Down Expand Up @@ -6422,32 +6410,16 @@ analyze_stage_toany(Context *cnt, MirInstr **input, MirType *slot_type)
}

AnalyzeStageState
analyze_stage_set_const_int(Context *cnt, MirInstr **input, MirType *slot_type)
analyze_stage_set_volatile_expr(Context *cnt, MirInstr **input, MirType *slot_type)
{
bl_assert(slot_type);

MirInstr *_input = *input;
if (_input->value.type->kind != MIR_TYPE_INT) return ANALYZE_STAGE_CONTINUE;
if (slot_type->kind != MIR_TYPE_INT) return ANALYZE_STAGE_CONTINUE;
if (_input->kind != MIR_INSTR_CONST) return ANALYZE_STAGE_CONTINUE;
if (!is_volatile_expr(*input)) return ANALYZE_STAGE_CONTINUE;

_input->value.type = slot_type;
(*input)->value.type = slot_type;
return ANALYZE_STAGE_BREAK;
}

AnalyzeStageState
analyze_stage_set_mutable_expr(Context *cnt, MirInstr **input, MirType *slot_type)
{
bl_assert(slot_type);
MirInstr *_input = *input;

if (_input->kind == MIR_INSTR_UNOP && ((MirInstrUnop *)_input)->mutate_to_literal) {
bl_log("mutate unop to lit");
}

return ANALYZE_STAGE_CONTINUE;
}

AnalyzeStageState
analyze_stage_implicit_cast(Context *cnt, MirInstr **input, MirType *slot_type)
{
Expand Down
8 changes: 7 additions & 1 deletion src/mir.h
Original file line number Diff line number Diff line change
Expand Up @@ -568,14 +568,20 @@ struct MirInstrBinop {
BinopKind op;
MirInstr *lhs;
MirInstr *rhs;

/* volatile type flag, if true, this instruction can change type during analyze pass, this
* is used for const integer literals like (123 * 123) */
bool volatile_type;
};

struct MirInstrUnop {
MirInstr base;

UnopKind op;
MirInstr *expr;
bool mutate_to_literal;
/* volatile type flag, if true, this instruction can change type during analyze pass, this
* is used for const integer literals like (-123) */
bool volatile_type;
};

struct MirInstrFnProto {
Expand Down
2 changes: 1 addition & 1 deletion tests/src/test_typeinfo.bl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
info := cast(*TypeInfoInt) typeinfo(s32);
assert(info.base.kind == TypeKind.Int);
assert(info.base.size_bytes == sizeof(s32));
assert(info.bit_count == sizeof(s32) * 8);
assert(info.bit_count == auto sizeof(s32) * 8);
assert(info.is_signed);
};

Expand Down
7 changes: 6 additions & 1 deletion tests/test.bl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@

#load "std/print.bl"

MIN : s8 : -(127 + 1);
MAX : s8 : 127;

main :: fn () s32 {
print("%\n", S64_MIN);
i := 0b10101;
print("%\n", MIN);
print("%\n", MAX);
return 0;
};
2 changes: 1 addition & 1 deletion todo.org
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@
- [X] Wrong initialization of globals with defined type:
Foo : u64 : 10;

- [ ] Unstable function pointers and invalid error reporting locaitons.
- [ ] Unstable function pointers and invalid error reporting locations.

0 comments on commit 0b1c7f9

Please sign in to comment.