diff --git a/reid-llvm-lib/src/builder.rs b/reid-llvm-lib/src/builder.rs index 4161c64..b4f9583 100644 --- a/reid-llvm-lib/src/builder.rs +++ b/reid-llvm-lib/src/builder.rs @@ -610,30 +610,9 @@ impl Builder { Instr::PtrToInt(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), Instr::IntToPtr(instr, ty) => instr.cast_to(self, &ty).map(|_| ()), Instr::BitCast(..) => Ok(()), - Instr::ShiftRightLogical(_, rhs) => { - let rhs_ty = rhs.get_type(&self)?; - if rhs_ty.category() == TypeCategory::UnsignedInteger { - Ok(()) - } else { - Err(ErrorKind::Null) - } - } - Instr::ShiftRightArithmetic(_, rhs) => { - let rhs_ty = rhs.get_type(&self)?; - if rhs_ty.category() == TypeCategory::UnsignedInteger { - Ok(()) - } else { - Err(ErrorKind::Null) - } - } - Instr::ShiftLeft(_, rhs) => { - let rhs_ty = rhs.get_type(&self)?; - if rhs_ty.category() == TypeCategory::UnsignedInteger { - Ok(()) - } else { - Err(ErrorKind::Null) - } - } + Instr::ShiftRightLogical(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()), + Instr::ShiftRightArithmetic(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()), + Instr::ShiftLeft(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()), Instr::GetGlobal(_) => Ok(()), } } diff --git a/reid/src/codegen/intrinsics.rs b/reid/src/codegen/intrinsics.rs index 342bc24..ed1248c 100644 --- a/reid/src/codegen/intrinsics.rs +++ b/reid/src/codegen/intrinsics.rs @@ -1,4 +1,4 @@ -use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValueKind, Instr, Type}; +use reid_lib::{CmpPredicate, ConstValueKind, Instr, Type, builder::InstructionValue}; use crate::{ codegen::{ErrorKind, StackValueKind}, @@ -74,7 +74,7 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option {} } @@ -247,26 +247,17 @@ pub fn form_intrinsic_binops() -> Vec { scope.block.build(Instr::XOr(lhs, rhs)).unwrap() })); if ty.signed() { - intrinsics.push(complex_binop_def( - BitshiftRight, - &ty, - &TypeKind::U64, - |scope, lhs, rhs| scope.block.build(Instr::ShiftRightArithmetic(lhs, rhs)).unwrap(), - )); + intrinsics.push(complex_binop_def(BitshiftRight, &ty, &ty, |scope, lhs, rhs| { + scope.block.build(Instr::ShiftRightArithmetic(lhs, rhs)).unwrap() + })); } else { - intrinsics.push(complex_binop_def( - BitshiftRight, - &ty, - &TypeKind::U64, - |scope, lhs, rhs| scope.block.build(Instr::ShiftRightLogical(lhs, rhs)).unwrap(), - )); + intrinsics.push(complex_binop_def(BitshiftRight, &ty, &ty, |scope, lhs, rhs| { + scope.block.build(Instr::ShiftRightLogical(lhs, rhs)).unwrap() + })); } - intrinsics.push(complex_binop_def( - BitshiftLeft, - &ty, - &TypeKind::U64, - |scope, lhs, rhs| scope.block.build(Instr::ShiftLeft(lhs, rhs)).unwrap(), - )); + intrinsics.push(complex_binop_def(BitshiftLeft, &ty, &ty, |scope, lhs, rhs| { + scope.block.build(Instr::ShiftLeft(lhs, rhs)).unwrap() + })); } for ty in INTEGERS.iter().chain(&[TypeKind::Bool, TypeKind::Char]) { intrinsics.push(boolean_binop_def(Cmp(CmpOperator::EQ), &ty, |scope, lhs, rhs| { diff --git a/test.reid b/test.reid new file mode 100644 index 0000000..16d60d2 --- /dev/null +++ b/test.reid @@ -0,0 +1,215 @@ +//////////// +/// math /// +//////////// + +struct Vec2 { x: f32, y: f32 } + +impl Vec2 { + pub fn zero() -> Vec2 { Vec2 { x: 0.0, y: 0.0 } } + pub fn at(x: f32, y: f32) -> Vec2 { Vec2 { x: x, y: y } } +} + +//impl binop () + + +/////////////////// +/// SDL externs /// +/////////////////// + +struct SDL_FPoint { x: f32, y: f32 } +struct SDL_FColor { r: f32, g: f32, b: f32, a: f32 } +struct SDL_Vertex { position: SDL_FPoint, color: SDL_FColor, tex_coord: SDL_FPoint } +impl SDL_Vertex { + pub fn new() -> SDL_Vertex { + SDL_Vertex { + position: SDL_FPoint { x: 0.0, y: 0.0 }, + color: SDL_FColor { r: 1.0, g: 0.0, b: 1.0, a: 1.0 }, + tex_coord: SDL_FPoint { x: 0.0, y: 0.0 }, + } + } + + pub fn pos(self, pos: Vec2) -> SDL_Vertex { + return SDL_Vertex { + position: SDL_FPoint { x: pos.x, y: pos.y }, + color: self.color, + tex_coord: self.tex_coord, + }; + } + + pub fn col(self, color: [f32; 3]) -> SDL_Vertex { + return SDL_Vertex { + position: self.position, + color: [color[0], color[1], color[2], self.color.a], + tex_coord: self.tex_coord, + }; + } +} + +struct SDL_Window {} +struct SDL_Renderer {} +struct SDL_Texture {} +struct SDL_Event { type: u32, reserved: [u8; 124] } +struct SDL_FRect { x: f32, y: f32, w: f32, h: f32 } +struct SDL_Rect { x: i32, y: i32, w: i32, h: i32 } +extern fn SDL_malloc(size: u64) -> *u8; +extern fn SDL_Init(flags: u32) -> bool; +extern fn SDL_Quit(); +extern fn SDL_CreateWindowAndRenderer(title: *char, width: i32, height: i32, flags: i32, + window_out: &mut *SDL_Window, renderer_out: &mut *SDL_Renderer) -> bool; +extern fn SDL_Delay(ms: u32); +extern fn SDL_SetRenderDrawColor(renderer: *SDL_Renderer, r: u8, g: u8, b: u8, a: u8); +extern fn SDL_RenderClear(renderer: *SDL_Renderer); +extern fn SDL_RenderPresent(renderer: *SDL_Renderer); +extern fn SDL_HasEvent(event_type: u32) -> bool; +extern fn SDL_PollEvent(event: &mut SDL_Event) -> bool; +extern fn SDL_PumpEvents(); +extern fn SDL_FlushEvents(min_type: u32, max_type: u32); +extern fn SDL_GetTicks() -> u64; +extern fn SDL_SetWindowTitle(window: *SDL_Window, title: *char) -> bool; +extern fn SDL_CreateTexture(renderer: *SDL_Renderer, + pixel_format: u32, texture_access: u32, width: u32, height: u32) -> *SDL_Texture; +extern fn SDL_RenderTexture(renderer: *SDL_Renderer, + texture: *SDL_Texture, srcfrect: &SDL_FRect, dstfrect: &SDL_FRect) -> bool; +extern fn SDL_UpdateTexture(texture: *SDL_Texture, rect: &SDL_Rect, pixels: *u8, pitch: u32) -> bool; +extern fn SDL_GetError() -> *char; +extern fn SDL_GetWindowSize(window: *SDL_Window, w: &mut i32, h: &mut i32) -> bool; +extern fn SDL_rand(max_exclusive: u32) -> u32; +extern fn SDL_SetTextureScaleMode(texture: *SDL_Texture, scale_mode: i32) -> bool; +extern fn SDL_sqrtf(value: f32) -> f32; +extern fn SDL_randf() -> f32; +extern fn SDL_powf(value: f32, power: f32) -> f32; +extern fn exit(exit_code: i32); +extern fn SDL_RenderGeometry(renderer: *SDL_Renderer, texture: *SDL_Texture, + vertices: *SDL_Vertex, num_vertices: i32, indices: *i32, num_indices: i32) -> bool; + +// SDL error reporting helper +import std::print; +import std::String; +fn print_sdl_error(context: *char) { + let mut message = String::new(); + message = message + context + ": " + SDL_GetError(); + print(message); + message.free(); +} + + +//////////////// +/// the game /// +//////////////// + +struct Ship { + position: Vec2, +} + +struct Game { + ship: Ship, +} + +impl Game { + pub fn new() -> Game { + Game { + ship: Ship { + position: Vec2::zero(), + }, + } + } + + pub fn run_frame(&mut self, dt: f32, renderer: *SDL_Renderer, aspect_ratio: f32) { + let ship = *self.ship; + let vertices = [ + SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0]), + SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0]), + SDL_Vertex::new().pos(ship.position).col([1.0, 1.0, 1.0]) + ]; + let borrow: &[SDL_Vertex; 3] = &vertices; + SDL_RenderGeometry(renderer, SDL_Texture::null(), + borrow as *SDL_Vertex, 3, i32::null(), 0); + // TODO: add a ship + // TODO: wind sim + // TODO: wave sim + } +} + + +//////////////// +/// the game /// +//////////////// + +struct Platform { + window: *SDL_Window, + renderer: *SDL_Renderer, + game: Game, + last_frame_ticks: u64, +} + +impl Platform { + pub fn new() -> Platform { + let SDL_INIT_VIDEO = 32; + let SDL_WINDOW_RESIZABLE = 32; + + let init_success = SDL_Init(SDL_INIT_VIDEO); + if init_success == false { + print_sdl_error("SDL init failed"); + return exit(1); + } + + let mut window = SDL_Window::null(); + let mut renderer = SDL_Renderer::null(); + let mut window_title = "Yacht Reid"; + let gfx_init_success = SDL_CreateWindowAndRenderer( + window_title, 640, 480, SDL_WINDOW_RESIZABLE, + &mut window, &mut renderer + ); + if gfx_init_success == false { + print_sdl_error("SDL renderer and window creation failed"); + return exit(1); + } + + return Platform { + window: window, + renderer: renderer, + game: Game::new(), + last_frame_ticks: SDL_GetTicks(), + }; + } + + pub fn run_frame(&mut self) -> bool { + let mut event = SDL_Event { type: 0, reserved: [0; 124] }; + while (SDL_PollEvent(&mut event)) { + if event.type == 256 { // SDL_EVENT_QUIT + return false; + } + } + + let now = SDL_GetTicks(); + let dt = (now - *self.last_frame_ticks) as f32 / 1000.0; + *self.last_frame_ticks = now; + + let mut screen_width = 0; + let mut screen_height = 0; + SDL_GetWindowSize(*self.window, &mut screen_width, &mut screen_height); + let aspect_ratio = screen_width as f32 / screen_height as f32; + + SDL_SetRenderDrawColor(*self.renderer, 0, 50, 90, 255); + SDL_RenderClear(*self.renderer); + + *self.game.run_frame(dt, *self.renderer, aspect_ratio); + + SDL_RenderPresent(*self.renderer); + return true; + } + + pub fn cleanup(&mut self) { + SDL_Quit(); + } +} + +//////////// +/// main /// +//////////// + +fn main() -> i32 { + let mut platform = Platform::new(); + while platform.run_frame() {} + return 0; +}