From 87db7538d05166cb8cdb701886b38b32de9bc708 Mon Sep 17 00:00:00 2001 From: core Date: Fri, 28 Mar 2025 09:16:55 -0400 Subject: [PATCH] cargo fmt --- crates/client/src/components.rs | 2 +- crates/client/src/lib.rs | 9 +- crates/client/src/networking/mod.rs | 13 +- crates/client/src/rendering/assets.rs | 2 +- crates/client/src/rendering/mod.rs | 56 +- crates/client/src/ui/colors.rs | 2 +- crates/client/src/ui/mod.rs | 58 +- crates/client/src/ui/widgets.rs | 2 +- crates/client/src/wasm/assets.rs | 2 +- crates/kabel/src/ast.rs | 15 +- crates/kabel/src/codegen.rs | 496 +++++++++++----- crates/kabel/src/debug.rs | 121 ++-- crates/kabel/src/error.rs | 9 +- crates/kabel/src/lexer.rs | 71 ++- crates/kabel/src/lib.rs | 14 +- crates/kabel/src/macros.rs | 17 +- crates/kabel/src/main.rs | 8 +- crates/kabel/src/name_resolution.rs | 219 +++++-- crates/kabel/src/opcodes.rs | 85 +-- crates/kabel/src/parser.rs | 416 +++++++++---- crates/kabel/src/runtime_error.rs | 8 +- crates/kabel/src/test.rs | 5 +- crates/kabel/src/vm.rs | 559 ++++++++++++++---- crates/server/src/crafting/components.rs | 19 +- crates/server/src/crafting/mining.rs | 31 +- crates/server/src/module/mod.rs | 10 +- crates/server/src/module/save.rs | 7 +- crates/server/src/planet.rs | 76 ++- crates/server/src/player/client_login.rs | 23 +- crates/server/src/player/mod.rs | 19 +- crates/server/src/player/packet.rs | 5 +- .../server/src/player/player_mouse_input.rs | 14 +- crates/xtask/src/main.rs | 73 ++- 33 files changed, 1800 insertions(+), 666 deletions(-) diff --git a/crates/client/src/components.rs b/crates/client/src/components.rs index 9e8824522ee6efb388c99b379b634a8c3dadd8b7..19addb39d56f72f92d41bb300de7701f6c9b50f7 100644 --- a/crates/client/src/components.rs +++ b/crates/client/src/components.rs @@ -16,7 +16,7 @@ pub struct Transform { #[derive(Resource, Debug)] pub struct PlayerResources { pub fuel_amount: u32, - pub fuel_max: u32 + pub fuel_max: u32, } impl Transform { diff --git a/crates/client/src/lib.rs b/crates/client/src/lib.rs index bc21badba369120884d7833cf01df18b028f8b86..e5324ef96f82c83e852eaa883748106954ff1a92 100644 --- a/crates/client/src/lib.rs +++ b/crates/client/src/lib.rs @@ -1,13 +1,13 @@ +use crate::components::PlayerResources; use bevy_ecs::{event::Events, world::World}; use components::{Camera, Chat, Part, Player, RecvPacket, SendPacket, Texture, Transform}; use nalgebra::{Rotation2, Scale3, Translation3}; use networking::ws::Ws; -use rendering::App; use platform::assets::Assets; +use rendering::assets::AssetLoader; +use rendering::App; use tracing::info; use winit::event_loop::{ControlFlow, EventLoop}; -use crate::components::PlayerResources; -use rendering::assets::AssetLoader; #[cfg(target_arch = "wasm32")] #[path = "wasm/mod.rs"] @@ -51,8 +51,7 @@ pub fn start() { fuel_max: 0, }); world.insert_resource(Chat { - messages: vec![ - ], + messages: vec![], textbox: String::new(), }); diff --git a/crates/client/src/networking/mod.rs b/crates/client/src/networking/mod.rs index 45839a7877f9fdea3189c01daa6059fc5285539a..a842806db794a7bbb45de5b373256dd9859a0f5c 100644 --- a/crates/client/src/networking/mod.rs +++ b/crates/client/src/networking/mod.rs @@ -9,7 +9,10 @@ use bevy_ecs::{ use nalgebra::{Rotation2, Scale3, Translation3}; use starkingdoms_common::{packet::Packet, PartType, PlanetType}; -use crate::components::{Camera, Chat, Menu, Part, Player, PlayerResources, RecvPacket, SendPacket, ServerId, SpriteBundle, Texture, Transform}; +use crate::components::{ + Camera, Chat, Menu, Part, Player, PlayerResources, RecvPacket, SendPacket, ServerId, + SpriteBundle, Texture, Transform, +}; #[cfg(target_arch = "wasm32")] #[path = "ws_wasm.rs"] @@ -194,10 +197,7 @@ pub fn process_packets( } } } - EnergyUpdate { - amount, - max, - } => { + EnergyUpdate { amount, max } => { let mut r = world.resource_mut::(); r.fuel_amount = *amount; r.fuel_max = *max; @@ -216,7 +216,8 @@ pub fn process_packets( } Message { actor, content, .. } => { let mut chat = world.get_resource_mut::().unwrap(); - chat.messages.push(format!("{}: {}", actor.clone(), content.clone())); + chat.messages + .push(format!("{}: {}", actor.clone(), content.clone())); } PlayerLeave { id } => { let mut part_query = world.query_filtered::<(Entity, &ServerId), With>(); diff --git a/crates/client/src/rendering/assets.rs b/crates/client/src/rendering/assets.rs index 1b66adda2f79228eb8b980ffc3e8bdf110772eb8..445a7577d7ed57d34fe6fdafaf2e39bc10174bf0 100644 --- a/crates/client/src/rendering/assets.rs +++ b/crates/client/src/rendering/assets.rs @@ -26,4 +26,4 @@ pub struct ImgData { pub trait AssetLoader { fn new() -> Self; fn get(&self, local_path: impl Into) -> Option; -} \ No newline at end of file +} diff --git a/crates/client/src/rendering/mod.rs b/crates/client/src/rendering/mod.rs index 45bae0ee3034b5fb7fce1ffd8aef763338c741b6..39b73770129d87237a32c02247c52c105363208f 100644 --- a/crates/client/src/rendering/mod.rs +++ b/crates/client/src/rendering/mod.rs @@ -33,12 +33,8 @@ use winit::keyboard::{KeyCode, PhysicalKey}; #[cfg(target_arch = "wasm32")] use winit::platform::web::{WindowAttributesExtWebSys, WindowExtWebSys}; use winit::{ - application::ApplicationHandler, - dpi::LogicalSize, - event::WindowEvent, - event_loop::ActiveEventLoop, - raw_window_handle::HasWindowHandle, - window::{Window}, + application::ApplicationHandler, dpi::LogicalSize, event::WindowEvent, + event_loop::ActiveEventLoop, raw_window_handle::HasWindowHandle, window::Window, }; use crate::components::{Camera, Menu, Player, RecvPacket, SendPacket, Texture, Transform}; @@ -555,33 +551,51 @@ impl ApplicationHandler for App { let assets = self.world.resource::(); match assets.get("starfield.svg") { Some(image) => { - let texture_object = gl.create_texture().expect("Failed to create texture object"); + let texture_object = gl + .create_texture() + .expect("Failed to create texture object"); gl.bind_texture(glow::TEXTURE_2D, Some(texture_object)); - gl.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::LINEAR_MIPMAP_LINEAR as i32); - gl.tex_image_2d(glow::TEXTURE_2D, 0, glow::RGBA as i32, - image.width as i32, image.height as i32, 0, glow::RGBA, - glow::UNSIGNED_BYTE, PixelUnpackData::Slice(Some(&image.bytes))); + gl.tex_parameter_i32( + glow::TEXTURE_2D, + glow::TEXTURE_MIN_FILTER, + glow::LINEAR_MIPMAP_LINEAR as i32, + ); + gl.tex_image_2d( + glow::TEXTURE_2D, + 0, + glow::RGBA as i32, + image.width as i32, + image.height as i32, + 0, + glow::RGBA, + glow::UNSIGNED_BYTE, + PixelUnpackData::Slice(Some(&image.bytes)), + ); gl.generate_mipmap(glow::TEXTURE_2D); - self.textures.insert("starfield.svg".to_string(), texture_object); + self.textures + .insert("starfield.svg".to_string(), texture_object); } None => {} } } if self.textures.contains_key("starfield.svg") { - gl.bind_texture(glow::TEXTURE_2D, self.textures.get("starfield.svg").copied()); + gl.bind_texture( + glow::TEXTURE_2D, + self.textures.get("starfield.svg").copied(), + ); let camera = self.world.get_resource::().unwrap(); - let x = -(camera.x + camera.x.signum() * 200.0) - + camera.x % 400.0; - let y = -(camera.y + camera.y.signum() * 200.0) - + camera.y % 400.0; + let x = -(camera.x + camera.x.signum() * 200.0) + camera.x % 400.0; + let y = -(camera.y + camera.y.signum() * 200.0) + camera.y % 400.0; let x_range = camera.width as f32 / camera.zoom / 400.0; let y_range = camera.height as f32 / camera.zoom / 400.0; - for i in ((-x_range/2.0) as i32 - 1)..=((x_range/2.0) as i32 + 1) { - for j in ((-y_range/2.0) as i32 - 1)..=((y_range/2.0) as i32 + 1) { - let model = Translation3::new(x + (i*400) as f32, y + (j*400) as f32, 0.0).to_homogeneous() - * Scale3::new(200.0, 200.0, 1.0).to_homogeneous(); + for i in ((-x_range / 2.0) as i32 - 1)..=((x_range / 2.0) as i32 + 1) { + for j in ((-y_range / 2.0) as i32 - 1)..=((y_range / 2.0) as i32 + 1) { + let model = + Translation3::new(x + (i * 400) as f32, y + (j * 400) as f32, 0.0) + .to_homogeneous() + * Scale3::new(200.0, 200.0, 1.0).to_homogeneous(); gl.uniform_matrix_4_f32_slice(model_loc.as_ref(), false, model.as_slice()); gl.draw_elements(glow::TRIANGLES, 6, glow::UNSIGNED_INT, 0); } diff --git a/crates/client/src/ui/colors.rs b/crates/client/src/ui/colors.rs index 35d9b01ac2fb6eb4daadf80ea76ecf8f36a97664..0bdfcf364de6f572d9171a7944987e671cb1b8c0 100644 --- a/crates/client/src/ui/colors.rs +++ b/crates/client/src/ui/colors.rs @@ -30,4 +30,4 @@ color!(SURFACE_1, rgb(69, 71, 90)); color!(SURFACE_0, rgb(49, 50, 68)); color!(BASE, rgb(30, 30, 46)); color!(MANTLE, rgb(24, 24, 37)); -color!(CRUST, rgb(17, 17, 27)); \ No newline at end of file +color!(CRUST, rgb(17, 17, 27)); diff --git a/crates/client/src/ui/mod.rs b/crates/client/src/ui/mod.rs index 2dd9a6c7997cfd26e81e1f79fdcc886c5af0f632..abd17c3648feced7fc3972a2d0995fc71da63787 100644 --- a/crates/client/src/ui/mod.rs +++ b/crates/client/src/ui/mod.rs @@ -3,14 +3,14 @@ mod widgets; use std::f32; +use crate::components::{Camera, Chat, Menu, Player, PlayerResources, SendPacket, Transform}; +use crate::ui::widgets::{progress_bar, RichTextExt}; use bevy_ecs::entity::Entity; use bevy_ecs::event::Events; use bevy_ecs::prelude::With; use bevy_ecs::world::World; use egui::{Align, Align2, CursorIcon, Layout, Margin, Order, RichText, Shadow, Visuals}; use starkingdoms_common::packet::Packet; -use crate::components::{Camera, Chat, Menu, Player, PlayerResources, SendPacket, Transform}; -use crate::ui::widgets::{progress_bar, RichTextExt}; pub fn init_ui(ctx: egui::Context) { // set colors @@ -19,7 +19,6 @@ pub fn init_ui(ctx: egui::Context) { let mut visuals = Visuals::default(); visuals.dark_mode = true; - // TODO(core): code_bg_colors visuals.warn_fg_color = colors::YELLOW; // used for warning text @@ -43,17 +42,18 @@ pub fn init_ui(ctx: egui::Context) { visuals.hyperlink_color = colors::BLUE; - - visuals.widgets.noninteractive.fg_stroke.color = colors::TEXT; // standard text color - style.visuals = visuals; ctx.set_style(style); } -pub fn draw_ui(ctx: &egui::Context, world: &mut World, send_packet_events: &mut Events) { +pub fn draw_ui( + ctx: &egui::Context, + world: &mut World, + send_packet_events: &mut Events, +) { draw_status_bar(ctx, world); draw_chat(ctx, world, send_packet_events); draw_crafting(ctx, world); @@ -71,11 +71,14 @@ pub fn draw_status_bar(ctx: &egui::Context, world: &mut World) { .order(Order::Foreground) .anchor(Align2::CENTER_BOTTOM, [0.0, -5.0]) .show(ctx, |ui| { - ui.horizontal(|ui| { ui.vertical(|ui| { ui.label(RichText::new("Position:").stk_weak()); - ui.label(RichText::new(format!("{:.0}, {:.0}", player_position.translation.x / 10.0, player_position.translation.y / 10.0))) + ui.label(RichText::new(format!( + "{:.0}, {:.0}", + player_position.translation.x / 10.0, + player_position.translation.y / 10.0 + ))) }); ui.add_space(8.0); @@ -84,20 +87,30 @@ pub fn draw_status_bar(ctx: &egui::Context, world: &mut World) { ui.horizontal(|ui| { ui.label(RichText::new("Fuel:").stk_weak()); ui.with_layout(Layout::right_to_left(Align::Center), |ui| { - ui.label(RichText::new(format!("{}/{} ({:.2}%)", player_resources.fuel_amount, player_resources.fuel_max, player_resources.fuel_amount as f32 / player_resources.fuel_max as f32 * 100.0))) + ui.label(RichText::new(format!( + "{}/{} ({:.2}%)", + player_resources.fuel_amount, + player_resources.fuel_max, + player_resources.fuel_amount as f32 + / player_resources.fuel_max as f32 + * 100.0 + ))) }); - }); - ui.add( - progress_bar(player_resources.fuel_amount as f32 / player_resources.fuel_max as f32) - ); + ui.add(progress_bar( + player_resources.fuel_amount as f32 / player_resources.fuel_max as f32, + )); }) }); }); } -pub fn draw_chat(ctx: &egui::Context, world: &mut World, send_packet_events: &mut Events) { +pub fn draw_chat( + ctx: &egui::Context, + world: &mut World, + send_packet_events: &mut Events, +) { let mut chat = world.get_resource_mut::().unwrap(); egui::Window::new("Chat") @@ -122,8 +135,10 @@ pub fn draw_chat(ctx: &egui::Context, world: &mut World, send_packet_events: &mu }); ui.horizontal(|ui| { let output = egui::TextEdit::singleline(&mut chat.textbox).show(ui); - if ui.button("Send").clicked() || - (ctx.input(|i| i.key_pressed(egui::Key::Enter)) && output.response.lost_focus()) { + if ui.button("Send").clicked() + || (ctx.input(|i| i.key_pressed(egui::Key::Enter)) + && output.response.lost_focus()) + { send_packet_events.send(SendPacket(Packet::SendMessage { target: None, content: chat.textbox.clone(), @@ -141,9 +156,10 @@ pub fn draw_crafting(ctx: &egui::Context, world: &mut World) { egui::Window::new("Crafting") .id(format!("Crafting{}", entity.index()).into()) .pivot(Align2::LEFT_BOTTOM) - .fixed_pos(((menu.translation.x + camera.x) * camera.zoom + camera.width as f32 / 2.0, - (menu.translation.y + camera.y) * camera.zoom + camera.height as f32 / 2.0)) - .show(ctx, |ui| { - }); + .fixed_pos(( + (menu.translation.x + camera.x) * camera.zoom + camera.width as f32 / 2.0, + (menu.translation.y + camera.y) * camera.zoom + camera.height as f32 / 2.0, + )) + .show(ctx, |ui| {}); } } diff --git a/crates/client/src/ui/widgets.rs b/crates/client/src/ui/widgets.rs index 7affcde7331602b2ad4b20ff0871ed3304849b1f..cd7b8f132b023c6b3bfe8c6e13574cc0eac2199c 100644 --- a/crates/client/src/ui/widgets.rs +++ b/crates/client/src/ui/widgets.rs @@ -13,4 +13,4 @@ impl RichTextExt for RichText { fn stk_weak(self) -> Self { self.color(super::colors::OVERLAY_2) } -} \ No newline at end of file +} diff --git a/crates/client/src/wasm/assets.rs b/crates/client/src/wasm/assets.rs index acee6a6ffe91fd8b20418dfd68966674950802c9..8f2e7a7f6568dbd8c1543c649997e03977b3fa6e 100644 --- a/crates/client/src/wasm/assets.rs +++ b/crates/client/src/wasm/assets.rs @@ -4,11 +4,11 @@ use std::{ sync::{Arc, Mutex}, }; +use crate::rendering::assets::{AssetLoader, ImgData}; use bevy_ecs::system::Resource; use image::EncodableLayout; use poll_promise::Promise; use resvg::{tiny_skia, usvg}; -use crate::rendering::assets::{AssetLoader, ImgData}; #[derive(Resource)] pub struct Assets { diff --git a/crates/kabel/src/ast.rs b/crates/kabel/src/ast.rs index bff6c3b1abadb3d9bfe5f56f756307ecf49b8ebc..5232f433c24c2a7669d35c54ad175413d0eccd33 100644 --- a/crates/kabel/src/ast.rs +++ b/crates/kabel/src/ast.rs @@ -11,9 +11,9 @@ pub enum ASTType { // statements Function(Name, Vec, Box), // name, args, block - Return(Box>), // expression - Loop(Box), // block - While(Box, Box), // condition, block + Return(Box>), // expression + Loop(Box), // block + While(Box, Box), // condition, block For( Box>, Box>, @@ -22,10 +22,10 @@ pub enum ASTType { ), // expr1, expr2, expr3, block Break, Continue, - If(Box, Box, Box>), // condition, block, else/else if - Block(Vec), // statements - Decl(Name, Box), // identifier, expression - Expr(Box), // expr + If(Box, Box, Box>), // condition, block, else/else if + Block(Vec), // statements + Decl(Name, Box), // identifier, expression + Expr(Box), // expr // REMOVE LATER Print(Box), @@ -93,4 +93,3 @@ pub enum LhsAssignType { Ident(String), Subscript(Box, Box), } - diff --git a/crates/kabel/src/codegen.rs b/crates/kabel/src/codegen.rs index ef64c240155869591e2d1a6a65e1dad22b3a3dea..b428b1fe591acba64ffbc2a9b82bf0e8836e9be6 100644 --- a/crates/kabel/src/codegen.rs +++ b/crates/kabel/src/codegen.rs @@ -1,4 +1,10 @@ -use crate::{ast::{ASTType, BinOp, LhsAssign, LhsAssignType, Lit, Name, UnOp, AST}, codegen_binary, codegen_unary, extension::Extension, opcodes::OpCode, vm::{Function, Unit, Value, VM}}; +use crate::{ + ast::{ASTType, BinOp, LhsAssign, LhsAssignType, Lit, Name, UnOp, AST}, + codegen_binary, codegen_unary, + extension::Extension, + opcodes::OpCode, + vm::{Function, Unit, Value, VM}, +}; pub struct Codegen { pub vm: VM, @@ -10,8 +16,7 @@ pub struct Codegen { impl Codegen { pub fn new(text: String) -> Self { Codegen { - vm: VM::new(Vec::new(), Vec::new(), - Vec::new(), text), + vm: VM::new(Vec::new(), Vec::new(), Vec::new(), text), scopes: vec![(ScopeType::Main, 0)], break_stack: Vec::new(), continue_stack: Vec::new(), @@ -88,24 +93,32 @@ impl Codegen { self.vm.units.push(Unit::new_empty()); // add function to constant pool and add a load expression in its place - let new_unit_ptr = self.vm.units.len()-1; + let new_unit_ptr = self.vm.units.len() - 1; self.vm.variables.push(Value::Fun(Function { unit_ptr: new_unit_ptr, arity: args.len(), })); - self.scopes.last_mut().expect("codegen scopes vec was empty").1 += 1; + self.scopes + .last_mut() + .expect("codegen scopes vec was empty") + .1 += 1; let old_unit_ptr = self.vm.unit_ptr; let old_ip = self.vm.ip; // set unit to write to self.vm.unit_ptr = new_unit_ptr; self.vm.ip = 0; - self.vm.units[self.vm.unit_ptr].pool.push(Value::Fun(Function { - unit_ptr: new_unit_ptr, - arity: args.len(), - })); - self.scopes.last_mut().expect("codegen scopes vec was empty").1 += args.len(); - + self.vm.units[self.vm.unit_ptr] + .pool + .push(Value::Fun(Function { + unit_ptr: new_unit_ptr, + arity: args.len(), + })); + self.scopes + .last_mut() + .expect("codegen scopes vec was empty") + .1 += args.len(); + if let ASTType::Block(ref stmts) = block.kind { self.visit_block(&block, stmts.clone(), ScopeType::Function); } @@ -113,12 +126,18 @@ impl Codegen { Some(instr) => { if *instr != >::into(OpCode::RET) { self.vm.units[self.vm.unit_ptr].pool.push(Value::Null); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::LOAD.into()); - let loc = (self.vm.units[self.vm.unit_ptr].pool.len()-1) as u8; + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::LOAD.into()); + let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8; self.vm.units[self.vm.unit_ptr].code.push(loc); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::RET.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::RET.into()); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != block.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((block.end_line, 3)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((block.end_line, 3)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 3; } @@ -126,12 +145,18 @@ impl Codegen { } None => { self.vm.units[self.vm.unit_ptr].pool.push(Value::Null); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::LOAD.into()); - let loc = (self.vm.units[self.vm.unit_ptr].pool.len()-1) as u8; + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::LOAD.into()); + let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8; self.vm.units[self.vm.unit_ptr].code.push(loc); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::RET.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::RET.into()); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != block.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((block.end_line, 3)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((block.end_line, 3)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 3; } @@ -145,18 +170,26 @@ impl Codegen { self.visit(expr); } else { self.vm.units[self.vm.unit_ptr].pool.push(Value::Null); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::LOAD.into()); - let loc = (self.vm.units[self.vm.unit_ptr].pool.len()-1) as u8; + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::LOAD.into()); + let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8; self.vm.units[self.vm.unit_ptr].code.push(loc); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } } - self.vm.units[self.vm.unit_ptr].code.push(OpCode::RET.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::RET.into()); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 1)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 1)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 1; } @@ -167,25 +200,37 @@ impl Codegen { let end_jmp = self.vm.units[self.vm.unit_ptr].code.len(); self.visit(condition.clone()); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::JNE.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::JNE.into()); self.vm.units[self.vm.unit_ptr].code.push(0xFF); // placeholder self.vm.units[self.vm.unit_ptr].code.push(0xFF); // placeholder - let start_jmp_loc = self.vm.units[self.vm.unit_ptr].code.len()-2; + let start_jmp_loc = self.vm.units[self.vm.unit_ptr].code.len() - 2; if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != condition.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((condition.end_line, 3)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((condition.end_line, 3)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 3; } if let ASTType::Block(ref stmts) = block.kind { self.visit_block(&block, stmts.clone(), ScopeType::Loop); } - self.vm.units[self.vm.unit_ptr].code.push(OpCode::JMP_UP.into()); - let current = self.vm.units[self.vm.unit_ptr].code.len()+2; + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::JMP_UP.into()); + let current = self.vm.units[self.vm.unit_ptr].code.len() + 2; let current_to_start = current - end_jmp; - self.vm.units[self.vm.unit_ptr].code.push(((current_to_start >> 8) & 0xFF) as u8); - self.vm.units[self.vm.unit_ptr].code.push((current_to_start & 0xFF) as u8); + self.vm.units[self.vm.unit_ptr] + .code + .push(((current_to_start >> 8) & 0xFF) as u8); + self.vm.units[self.vm.unit_ptr] + .code + .push((current_to_start & 0xFF) as u8); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != block.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((block.end_line, 3)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((block.end_line, 3)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 3; } @@ -195,15 +240,23 @@ impl Codegen { for loc in breaks { self.patch_jump(loc, 0); } - let continues = self.continue_stack.pop().expect("continue stack empty on pop"); + let continues = self + .continue_stack + .pop() + .expect("continue stack empty on pop"); for loc in continues { let jump = loc - end_jmp + 2; self.vm.units[self.vm.unit_ptr].code[loc] = ((jump >> 8) & 0xFF) as u8; self.vm.units[self.vm.unit_ptr].code[loc + 1] = (jump & 0xFF) as u8; } } - pub fn visit_for(&mut self, expr1: Option, expr2: Option, - expr3: Option, block: AST) { + pub fn visit_for( + &mut self, + expr1: Option, + expr2: Option, + expr3: Option, + block: AST, + ) { self.scopes.push((ScopeType::Other, 0)); self.break_stack.push(Vec::new()); @@ -216,12 +269,16 @@ impl Codegen { let mut start_jmp_loc = None; if let Some(expr2) = expr2 { self.visit(expr2.clone()); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::JNE.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::JNE.into()); self.vm.units[self.vm.unit_ptr].code.push(0xFF); // placeholder self.vm.units[self.vm.unit_ptr].code.push(0xFF); // placeholder - start_jmp_loc = Some(self.vm.units[self.vm.unit_ptr].code.len()-2); + start_jmp_loc = Some(self.vm.units[self.vm.unit_ptr].code.len() - 2); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != expr2.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((expr2.end_line, 3)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((expr2.end_line, 3)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 3; } @@ -229,7 +286,10 @@ impl Codegen { if let ASTType::Block(ref stmts) = block.kind { self.visit_block(&block, stmts.clone(), ScopeType::Loop); } - let continues = self.continue_stack.pop().expect("continue stack empty on pop"); + let continues = self + .continue_stack + .pop() + .expect("continue stack empty on pop"); for loc in continues { /*let jump = loc - end_jmp + 2; self.vm.units[self.vm.unit_ptr].code[loc] = ((jump >> 8) & 0xFF) as u8; @@ -238,23 +298,35 @@ impl Codegen { } if let Some(expr3) = expr3 { self.visit(expr3); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::POP.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::POP.into()); self.vm.units[self.vm.unit_ptr].code.push(0x01); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != block.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((block.end_line, 2)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((block.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } } // write instruction to loop - self.vm.units[self.vm.unit_ptr].code.push(OpCode::JMP_UP.into()); - let current = self.vm.units[self.vm.unit_ptr].code.len()+2; + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::JMP_UP.into()); + let current = self.vm.units[self.vm.unit_ptr].code.len() + 2; let current_to_start = current - end_jmp; - self.vm.units[self.vm.unit_ptr].code.push(((current_to_start >> 8) & 0xFF) as u8); - self.vm.units[self.vm.unit_ptr].code.push((current_to_start & 0xFF) as u8); + self.vm.units[self.vm.unit_ptr] + .code + .push(((current_to_start >> 8) & 0xFF) as u8); + self.vm.units[self.vm.unit_ptr] + .code + .push((current_to_start & 0xFF) as u8); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != block.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((block.end_line, 3)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((block.end_line, 3)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 3; } @@ -264,20 +336,22 @@ impl Codegen { self.patch_jump(loc, 0); } - if let Some(loc) = start_jmp_loc { self.patch_jump(loc, 0); } let (_scope_type, variables) = self.scopes.pop().expect("popped scope in block"); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::POP.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::POP.into()); self.vm.units[self.vm.unit_ptr].code.push(variables as u8); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != block.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((block.end_line, 2)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((block.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } - } pub fn visit_break(&mut self, ast: &AST) { let mut scopes = self.scopes.clone(); @@ -289,18 +363,27 @@ impl Codegen { break; } } - self.vm.units[self.vm.unit_ptr].code.push(OpCode::POP.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::POP.into()); self.vm.units[self.vm.unit_ptr].code.push(pop_count as u8); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::JMP.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::JMP.into()); self.vm.units[self.vm.unit_ptr].code.push(0xFF); self.vm.units[self.vm.unit_ptr].code.push(0xFF); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 5)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 5)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 5; } - self.break_stack.last_mut().expect("break not in a loop").push(self.vm.units[self.vm.unit_ptr].code.len()-2); + self.break_stack + .last_mut() + .expect("break not in a loop") + .push(self.vm.units[self.vm.unit_ptr].code.len() - 2); } pub fn visit_continue(&mut self, ast: &AST) { let mut scopes = self.scopes.clone(); @@ -312,27 +395,40 @@ impl Codegen { break; } } - self.vm.units[self.vm.unit_ptr].code.push(OpCode::POP.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::POP.into()); self.vm.units[self.vm.unit_ptr].code.push(pop_count as u8); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::JMP.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::JMP.into()); self.vm.units[self.vm.unit_ptr].code.push(0xFF); self.vm.units[self.vm.unit_ptr].code.push(0xFF); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 5)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 5)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 5; } - self.continue_stack.last_mut().expect("continue not in a loop").push(self.vm.units[self.vm.unit_ptr].code.len()-2); + self.continue_stack + .last_mut() + .expect("continue not in a loop") + .push(self.vm.units[self.vm.unit_ptr].code.len() - 2); } pub fn visit_if(&mut self, condition: AST, block: AST, else_expr: Option) { self.visit(condition.clone()); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::JNE.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::JNE.into()); self.vm.units[self.vm.unit_ptr].code.push(0xFF); // placeholder self.vm.units[self.vm.unit_ptr].code.push(0xFF); // placeholder - let start_jmp_loc = self.vm.units[self.vm.unit_ptr].code.len()-2; + let start_jmp_loc = self.vm.units[self.vm.unit_ptr].code.len() - 2; if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != condition.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((condition.end_line, 5)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((condition.end_line, 5)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 5; } @@ -342,39 +438,48 @@ impl Codegen { if let Some(ast) = else_expr { match ast.kind { ASTType::If(_, _, _) => { - self.vm.units[self.vm.unit_ptr].code.push(OpCode::JMP.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::JMP.into()); self.vm.units[self.vm.unit_ptr].code.push(0xFF); // placeholder self.vm.units[self.vm.unit_ptr].code.push(0xFF); // placeholder - let end_jmp_loc = self.vm.units[self.vm.unit_ptr].code.len()-2; + let end_jmp_loc = self.vm.units[self.vm.unit_ptr].code.len() - 2; if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 3)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 3)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 3; } - + self.patch_jump(start_jmp_loc, 0); self.visit(ast); self.patch_jump(end_jmp_loc, 0); } ASTType::Block(_) => { - - self.vm.units[self.vm.unit_ptr].code.push(OpCode::JMP.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::JMP.into()); self.vm.units[self.vm.unit_ptr].code.push(0xFF); // placeholder self.vm.units[self.vm.unit_ptr].code.push(0xFF); // placeholder if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 3)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 3)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 3; } - - let end_jmp_loc = self.vm.units[self.vm.unit_ptr].code.len()-2; + + let end_jmp_loc = self.vm.units[self.vm.unit_ptr].code.len() - 2; self.patch_jump(start_jmp_loc, 0); // jmp to else if let ASTType::Block(ref stmts) = ast.kind { self.visit_block(&ast, stmts.clone(), ScopeType::If); } self.patch_jump(end_jmp_loc, 0); // jmp to after else } - _ => { println!("unimplemented"); } + _ => { + println!("unimplemented"); + } } } else { self.patch_jump(start_jmp_loc, 0); @@ -386,36 +491,55 @@ impl Codegen { self.visit(stmt); } let (_scope_type, variables) = self.scopes.pop().expect("popped scope in block"); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::POP.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::POP.into()); self.vm.units[self.vm.unit_ptr].code.push(variables as u8); match self.vm.units[self.vm.unit_ptr].lines.last() { - Some(last) => if last.0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)); - } else { - self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; + Some(last) => { + if last.0 != ast.end_line { + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)); + } else { + self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; + } } - None => self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)) + None => self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)), } } pub fn visit_decl(&mut self, ast: &AST, _name: Name, expr: AST) { self.visit(expr); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::DECL.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::DECL.into()); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 1)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 1)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 1; } #[allow(irrefutable_let_patterns)] if let Extension::Resolution(_scope, _ptr) = ast.extensions[0] { - self.scopes.last_mut().expect("codegen scopes vec was empty").1 += 1; + self.scopes + .last_mut() + .expect("codegen scopes vec was empty") + .1 += 1; } } pub fn visit_expr_stmt(&mut self, ast: &AST, expr: AST) { self.visit(expr); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::POP.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::POP.into()); self.vm.units[self.vm.unit_ptr].code.push(0x01); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } @@ -423,9 +547,13 @@ impl Codegen { // REMOVE LATER pub fn visit_print(&mut self, ast: &AST, expr: AST) { self.visit(expr); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::PRINT.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::PRINT.into()); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 1)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 1)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 1; } @@ -437,10 +565,14 @@ impl Codegen { LhsAssignType::Ident(_) => { #[allow(irrefutable_let_patterns)] if let Extension::Resolution(_scope, ptr) = ast.extensions[0] { - self.vm.units[self.vm.unit_ptr].code.push(OpCode::ASN.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::ASN.into()); self.vm.units[self.vm.unit_ptr].code.push(ptr as u8); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } @@ -451,10 +583,14 @@ impl Codegen { #[allow(irrefutable_let_patterns)] if let Extension::Resolution(_scope, ptr) = name.extensions[0] { - self.vm.units[self.vm.unit_ptr].code.push(OpCode::REF.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::REF.into()); self.vm.units[self.vm.unit_ptr].code.push(ptr as u8); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } @@ -462,10 +598,14 @@ impl Codegen { panic!("Subscript assignment should always have a Resolution"); } - self.vm.units[self.vm.unit_ptr].code.push(OpCode::ASNARR.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::ASNARR.into()); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 1)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 1)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 1; } @@ -475,21 +615,32 @@ impl Codegen { pub fn visit_anonymous(&mut self, params: Vec, block: AST) { self.vm.units.push(Unit::new_empty()); - let new_unit_ptr = self.vm.units.len()-1; - self.vm.units[self.vm.unit_ptr].pool.push(Value::Fun(Function { - unit_ptr: new_unit_ptr, - arity: params.len(), - })); + let new_unit_ptr = self.vm.units.len() - 1; + self.vm.units[self.vm.unit_ptr] + .pool + .push(Value::Fun(Function { + unit_ptr: new_unit_ptr, + arity: params.len(), + })); // load function to stack - self.vm.units[self.vm.unit_ptr].code.push(OpCode::LOAD.into()); - let loc = (self.vm.units[self.vm.unit_ptr].pool.len()-1) as u8; + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::LOAD.into()); + let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8; self.vm.units[self.vm.unit_ptr].code.push(loc); - if self.vm.units[self.vm.unit_ptr].lines.len() == 0 || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != block.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((block.end_line, 2)); + if self.vm.units[self.vm.unit_ptr].lines.len() == 0 + || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != block.end_line + { + self.vm.units[self.vm.unit_ptr] + .lines + .push((block.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } - self.scopes.last_mut().expect("codegen scopes vec was empty").1 += 1; + self.scopes + .last_mut() + .expect("codegen scopes vec was empty") + .1 += 1; // enter function unit let old_unit_ptr = self.vm.unit_ptr; @@ -498,8 +649,11 @@ impl Codegen { self.vm.ip = 0; // update scopes with number of parameters - self.scopes.last_mut().expect("codegen scopes vec was empty").1 += params.len(); - + self.scopes + .last_mut() + .expect("codegen scopes vec was empty") + .1 += params.len(); + if let ASTType::Block(ref stmts) = block.kind { self.visit_block(&block, stmts.clone(), ScopeType::Function); } @@ -508,12 +662,18 @@ impl Codegen { Some(instr) => { if *instr != >::into(OpCode::RET) { self.vm.units[self.vm.unit_ptr].pool.push(Value::Null); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::LOAD.into()); - let loc = (self.vm.units[self.vm.unit_ptr].pool.len()-1) as u8; + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::LOAD.into()); + let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8; self.vm.units[self.vm.unit_ptr].code.push(loc); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::RET.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::RET.into()); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != block.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((block.end_line, 3)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((block.end_line, 3)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 3; } @@ -521,36 +681,48 @@ impl Codegen { } None => { self.vm.units[self.vm.unit_ptr].pool.push(Value::Null); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::LOAD.into()); - let loc = (self.vm.units[self.vm.unit_ptr].pool.len()-1) as u8; + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::LOAD.into()); + let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8; self.vm.units[self.vm.unit_ptr].code.push(loc); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::RET.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::RET.into()); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != block.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((block.end_line, 3)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((block.end_line, 3)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 3; } } }; - + self.vm.unit_ptr = old_unit_ptr; self.vm.ip = old_ip; } pub fn visit_subscript(&mut self, ast: &AST, left: AST, right: AST) { self.visit(left); self.visit(right); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::SCR.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::SCR.into()); if self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 1)); + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 1)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 1; } } pub fn visit_binary(&mut self, left: AST, oper: BinOp, right: AST) { use crate::ast::BinOp::*; - codegen_binary!(self, left, right, oper, Add, ADD, Sub, SUB, Mul, MUL, - Div, DIV, Mod, MOD, BitAnd, BITAND, BitXor, BITXOR, BitOr, BITOR, - Eq, EQ, Ne, NE, Gr, GR, Ge, GE, Ls, LS, Le, LE, Or, OR, And, AND); + codegen_binary!( + self, left, right, oper, Add, ADD, Sub, SUB, Mul, MUL, Div, DIV, Mod, MOD, BitAnd, + BITAND, BitXor, BITXOR, BitOr, BITOR, Eq, EQ, Ne, NE, Gr, GR, Ge, GE, Ls, LS, Le, LE, + Or, OR, And, AND + ); } pub fn visit_unary(&mut self, oper: UnOp, right: AST) { use crate::ast::UnOp::*; @@ -560,33 +732,55 @@ impl Codegen { match lit { Lit::Num(value) => { self.vm.units[self.vm.unit_ptr].pool.push(Value::Num(value)); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::LOAD.into()); - let loc = (self.vm.units[self.vm.unit_ptr].pool.len()-1) as u8; + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::LOAD.into()); + let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8; self.vm.units[self.vm.unit_ptr].code.push(loc); - if self.vm.units[self.vm.unit_ptr].lines.len() == 0 || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)); + if self.vm.units[self.vm.unit_ptr].lines.len() == 0 + || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line + { + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } } Lit::Str(value) => { - self.vm.units[self.vm.unit_ptr].pool.push(Value::Str(value.into())); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::LOAD.into()); - let loc = (self.vm.units[self.vm.unit_ptr].pool.len()-1) as u8; + self.vm.units[self.vm.unit_ptr] + .pool + .push(Value::Str(value.into())); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::LOAD.into()); + let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8; self.vm.units[self.vm.unit_ptr].code.push(loc); - if self.vm.units[self.vm.unit_ptr].lines.len() == 0 || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)); + if self.vm.units[self.vm.unit_ptr].lines.len() == 0 + || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line + { + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } } Lit::Bool(value) => { - self.vm.units[self.vm.unit_ptr].pool.push(Value::Bool(value)); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::LOAD.into()); - let loc = (self.vm.units[self.vm.unit_ptr].pool.len()-1) as u8; + self.vm.units[self.vm.unit_ptr] + .pool + .push(Value::Bool(value)); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::LOAD.into()); + let loc = (self.vm.units[self.vm.unit_ptr].pool.len() - 1) as u8; self.vm.units[self.vm.unit_ptr].code.push(loc); - if self.vm.units[self.vm.unit_ptr].lines.len() == 0 || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)); + if self.vm.units[self.vm.unit_ptr].lines.len() == 0 + || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line + { + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } @@ -595,16 +789,24 @@ impl Codegen { for expr in &exprs { self.visit(expr.clone()); } - self.vm.units[self.vm.unit_ptr].code.push(OpCode::LIST.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::LIST.into()); self.vm.units[self.vm.unit_ptr].code.push(exprs.len() as u8); - if self.vm.units[self.vm.unit_ptr].lines.len() == 0 || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)); + if self.vm.units[self.vm.unit_ptr].lines.len() == 0 + || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line + { + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } } Lit::Ident(_name) => { - self.vm.units[self.vm.unit_ptr].code.push(OpCode::VAR.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::VAR.into()); #[allow(irrefutable_let_patterns)] if let Extension::Resolution(_scope, ptr) = ast.extensions[0] { /*println!("line: {} ptr: {} locals: {:?}", ast.end_line, ptr, self.locals); @@ -612,8 +814,12 @@ impl Codegen { println!("slot: {}", *slot); self.vm.units[self.vm.unit_ptr].code.push(*slot);*/ self.vm.units[self.vm.unit_ptr].code.push(ptr as u8); - if self.vm.units[self.vm.unit_ptr].lines.len() == 0 || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)); + if self.vm.units[self.vm.unit_ptr].lines.len() == 0 + || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line + { + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } @@ -627,10 +833,16 @@ impl Codegen { self.visit(arg.clone()); } self.visit(ident); - self.vm.units[self.vm.unit_ptr].code.push(OpCode::CALL.into()); + self.vm.units[self.vm.unit_ptr] + .code + .push(OpCode::CALL.into()); self.vm.units[self.vm.unit_ptr].code.push(args.len() as u8); - if self.vm.units[self.vm.unit_ptr].lines.len() == 0 || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line { - self.vm.units[self.vm.unit_ptr].lines.push((ast.end_line, 2)); + if self.vm.units[self.vm.unit_ptr].lines.len() == 0 + || self.vm.units[self.vm.unit_ptr].lines.last().unwrap().0 != ast.end_line + { + self.vm.units[self.vm.unit_ptr] + .lines + .push((ast.end_line, 2)); } else { self.vm.units[self.vm.unit_ptr].lines.last_mut().unwrap().1 += 2; } @@ -645,5 +857,9 @@ impl Codegen { #[derive(Debug, Clone, PartialEq, Eq)] pub enum ScopeType { - Main, Function, Loop, If, Other, + Main, + Function, + Loop, + If, + Other, } diff --git a/crates/kabel/src/debug.rs b/crates/kabel/src/debug.rs index 246588e83aec78ffbc9a30d14f604b0e8d5f25c5..8594353ade90a0fe271096e2d20910fae0c0eb0f 100644 --- a/crates/kabel/src/debug.rs +++ b/crates/kabel/src/debug.rs @@ -1,4 +1,9 @@ -use crate::{ast::{LhsAssignType, AST}, lexer::Token, push_codegen, push_output, vm::{Value, VM}}; +use crate::{ + ast::{LhsAssignType, AST}, + lexer::Token, + push_codegen, push_output, + vm::{Value, VM}, +}; pub fn debug_token_array(tokens: Vec) -> String { let mut output = "".to_string(); @@ -6,13 +11,13 @@ pub fn debug_token_array(tokens: Vec) -> String { output += &token.token_type.to_string(); output += "\n"; } - output[..output.len()-1].to_string() + output[..output.len() - 1].to_string() } pub fn debug_ast(ast: AST, level: usize) -> String { use crate::ast::ASTType::*; use crate::ast::BinOp::*; - use crate::ast::UnOp::*; use crate::ast::Lit::*; + use crate::ast::UnOp::*; let mut output = "".to_string(); match ast.kind { Program(asts) => { @@ -20,7 +25,7 @@ pub fn debug_ast(ast: AST, level: usize) -> String { output += "Program"; for ast in asts { output += "\n"; - output += &debug_ast(ast, level+1); + output += &debug_ast(ast, level + 1); } } Function(name, params, block) => { @@ -32,47 +37,47 @@ pub fn debug_ast(ast: AST, level: usize) -> String { } output += &format!(" {:?}", ast.extensions); output += "\n"; - output += &debug_ast(*block, level+1); + output += &debug_ast(*block, level + 1); } Return(expr) => { output += &"| ".repeat(level); output += "Return"; if let Some(expr) = *expr { output += "\n"; - output += &debug_ast(expr, level+1); + output += &debug_ast(expr, level + 1); } } Loop(block) => { output += &"| ".repeat(level); output += "Loop"; output += "\n"; - output += &debug_ast(*block, level+1); + output += &debug_ast(*block, level + 1); } While(condition, block) => { output += &"| ".repeat(level); output += "While"; output += "\n"; - output += &debug_ast(*condition, level+1); + output += &debug_ast(*condition, level + 1); output += "\n"; - output += &debug_ast(*block, level+1); + output += &debug_ast(*block, level + 1); } For(expr1, expr2, expr3, block) => { output += &"| ".repeat(level); output += "For"; if let Some(expr1) = *expr1 { output += "\n"; - output += &debug_ast(expr1, level+1); + output += &debug_ast(expr1, level + 1); } if let Some(expr2) = *expr2 { output += "\n"; - output += &debug_ast(expr2, level+1); + output += &debug_ast(expr2, level + 1); } if let Some(expr3) = *expr3 { output += "\n"; - output += &debug_ast(expr3, level+1); + output += &debug_ast(expr3, level + 1); } output += "\n"; - output += &debug_ast(*block, level+1); + output += &debug_ast(*block, level + 1); } Break => { output += &"| ".repeat(level); @@ -85,15 +90,15 @@ pub fn debug_ast(ast: AST, level: usize) -> String { If(condition, block, else_expr) => { output += &"| ".repeat(level); output += "If\n"; - output += &debug_ast(*condition, level+1); + output += &debug_ast(*condition, level + 1); output += "\n"; - output += &debug_ast(*block, level+1); + output += &debug_ast(*block, level + 1); if let Some(else_expr) = *else_expr { output += "\n"; output += &"| ".repeat(level); output += "Else"; output += "\n"; - output += &debug_ast(else_expr, level+1); + output += &debug_ast(else_expr, level + 1); } } Block(asts) => { @@ -101,19 +106,19 @@ pub fn debug_ast(ast: AST, level: usize) -> String { output += "Block"; for ast in asts { output += "\n"; - output += &debug_ast(ast, level+1); + output += &debug_ast(ast, level + 1); } } Expr(expr) => { output += &"| ".repeat(level); output += "Expr\n"; - output += &debug_ast(*expr, level+1); + output += &debug_ast(*expr, level + 1); } // REMOVE LATER Print(expr) => { output += &"| ".repeat(level); output += "Print\n"; - output += &debug_ast(*expr, level+1); + output += &debug_ast(*expr, level + 1); } Decl(name, expr) => { output += &"| ".repeat(level); @@ -121,7 +126,7 @@ pub fn debug_ast(ast: AST, level: usize) -> String { output += &name.name; output += &format!(" {:?}", ast.extensions); output += "\n"; - output += &debug_ast(*expr, level+1); + output += &debug_ast(*expr, level + 1); } Assign(lhs, expr) => { output += &"| ".repeat(level); @@ -132,16 +137,16 @@ pub fn debug_ast(ast: AST, level: usize) -> String { } LhsAssignType::Subscript(name, index) => { output += "\n"; - output += &"| ".repeat(level+1); + output += &"| ".repeat(level + 1); output += "Subscript\n"; - output += &debug_ast(*name, level+2); + output += &debug_ast(*name, level + 2); output += "\n"; - output += &debug_ast(*index, level+2); + output += &debug_ast(*index, level + 2); } } output += &format!(" {:?}", ast.extensions); output += "\n"; - output += &debug_ast(*expr, level+1); + output += &debug_ast(*expr, level + 1); } Anonymous(params, block) => { output += &"| ".repeat(level); @@ -150,42 +155,42 @@ pub fn debug_ast(ast: AST, level: usize) -> String { output += &(" ".to_string() + ¶m.name); } output += "\n"; - output += &debug_ast(*block, level+1); + output += &debug_ast(*block, level + 1); } Ternary(condition, true_expr, false_expr) => { output += &"| ".repeat(level); output += "Ternary\n"; - output += &debug_ast(*condition, level+1); + output += &debug_ast(*condition, level + 1); output += "\n"; - output += &debug_ast(*true_expr, level+1); + output += &debug_ast(*true_expr, level + 1); output += "\n"; - output += &debug_ast(*false_expr, level+1); + output += &debug_ast(*false_expr, level + 1); } Subscript(array, index) => { output += &"| ".repeat(level); output += "Subscript\n"; - output += &debug_ast(*array, level+1); + output += &debug_ast(*array, level + 1); output += "\n"; - output += &debug_ast(*index, level+1); + output += &debug_ast(*index, level + 1); } Binary(left, oper, right) => { output += &"| ".repeat(level); output += "Binary "; - push_output!(oper, output, - Add, Sub, Mul, Div, Mod, BitAnd, BitXor, BitOr, - Eq, Ne, Gr, Ge, Ls, Le, Or, And); + push_output!( + oper, output, Add, Sub, Mul, Div, Mod, BitAnd, BitXor, BitOr, Eq, Ne, Gr, Ge, Ls, + Le, Or, And + ); output += "\n"; - output += &debug_ast(*left, level+1); + output += &debug_ast(*left, level + 1); output += "\n"; - output += &debug_ast(*right, level+1); + output += &debug_ast(*right, level + 1); } Unary(oper, right) => { output += &"| ".repeat(level); output += "Unary "; - push_output!(oper, output, - Not, Neg); + push_output!(oper, output, Not, Neg); output += "\n"; - output += &debug_ast(*right, level+1); + output += &debug_ast(*right, level + 1); } Lit(lit) => { output += &"| ".repeat(level); @@ -207,7 +212,7 @@ pub fn debug_ast(ast: AST, level: usize) -> String { Array(value) => { for value in value { output += "\n"; - output += &debug_ast(value, level+1); + output += &debug_ast(value, level + 1); } } } @@ -215,18 +220,18 @@ pub fn debug_ast(ast: AST, level: usize) -> String { Call(name, args) => { output += &"| ".repeat(level); output += "Call\n"; - output += &debug_ast(*name, level+1); + output += &debug_ast(*name, level + 1); for arg in args { output += "\n"; - output += &debug_ast(arg, level+1); + output += &debug_ast(arg, level + 1); } } Member(left, right) => { output += &"| ".repeat(level); output += "Member\n"; - output += &debug_ast(*left, level+1); + output += &debug_ast(*left, level + 1); output += "\n"; - output += &debug_ast(*right, level+1); + output += &debug_ast(*right, level + 1); } } output @@ -239,9 +244,31 @@ pub fn debug_bytecode(vm: &VM) -> String { let mut vm = vm.clone(); while vm.ip < vm.units[vm.unit_ptr].code.len() { // remove PRINT later - push_codegen!(vm.units[vm.unit_ptr].code[vm.ip].into(), vm, output, ADD, SUB, MUL, DIV, MOD, BITAND, - BITXOR, BITOR, EQ, NE, GR, GE, LS, LE, OR, AND, NOT, NEG, - PRINT, ERR); + push_codegen!( + vm.units[vm.unit_ptr].code[vm.ip].into(), + vm, + output, + ADD, + SUB, + MUL, + DIV, + MOD, + BITAND, + BITXOR, + BITOR, + EQ, + NE, + GR, + GE, + LS, + LE, + OR, + AND, + NOT, + NEG, + PRINT, + ERR + ); match vm.units[vm.unit_ptr].code[vm.ip].into() { LOAD => { output += &vm.ip.to_string(); @@ -270,7 +297,7 @@ pub fn debug_bytecode(vm: &VM) -> String { output += &vm.units[vm.unit_ptr].code[vm.ip].to_string(); output += "\n"; } - ASN => { + ASN => { output += &vm.ip.to_string(); output += " "; output += &vm.find_line().to_string(); diff --git a/crates/kabel/src/error.rs b/crates/kabel/src/error.rs index 736dc9c7ef936f26e8f3da0c834f70a7f2b51558..42d79b0d14f6af227fd7823f5d4194be17c2e127 100644 --- a/crates/kabel/src/error.rs +++ b/crates/kabel/src/error.rs @@ -9,7 +9,14 @@ pub struct KabelError { } impl KabelError { - pub fn new(kind: ErrorKind, message: String, hint: Option, line: usize, column: usize, code: String) -> Self { + pub fn new( + kind: ErrorKind, + message: String, + hint: Option, + line: usize, + column: usize, + code: String, + ) -> Self { Self { kind, message, diff --git a/crates/kabel/src/lexer.rs b/crates/kabel/src/lexer.rs index bd8c1babb4176939ea5bf623422a64bf2dc114df..816b6bb432496531f4e15868c708d8f9ae475988 100644 --- a/crates/kabel/src/lexer.rs +++ b/crates/kabel/src/lexer.rs @@ -53,7 +53,10 @@ impl Lexer { let result = self.read_next_token(); match result { Ok(b) => b, - Err(e) => { self.errors.push(e); true } + Err(e) => { + self.errors.push(e); + true + } } } @@ -429,15 +432,63 @@ pub enum TokenType { impl Display for TokenType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { use TokenType::*; - token_display!(*self, f, Function, Return, Loop, While, For, - Break, Continue, If, Else, Var, True, False, Print, - Star, StarEqual, Slash, SlashEqual, Percent, PercentEqual, - Plus, PlusPlus, PlusEqual, Minus, MinusMinus, MinusEqual, - LeftParen, RightParen, LeftBrace, RightBrace, - LeftSquare, RightSquare, Equal, EqualEqual, - Bang, BangEqual, Greater, GreaterEqual, Less, - LessEqual, And, AndEqual, AndAnd, Or, OrEqual, OrOr, - Caret, CaretEqual, Period, Comma, Semicolon, Colon, Question, Arrow); + token_display!( + *self, + f, + Function, + Return, + Loop, + While, + For, + Break, + Continue, + If, + Else, + Var, + True, + False, + Print, + Star, + StarEqual, + Slash, + SlashEqual, + Percent, + PercentEqual, + Plus, + PlusPlus, + PlusEqual, + Minus, + MinusMinus, + MinusEqual, + LeftParen, + RightParen, + LeftBrace, + RightBrace, + LeftSquare, + RightSquare, + Equal, + EqualEqual, + Bang, + BangEqual, + Greater, + GreaterEqual, + Less, + LessEqual, + And, + AndEqual, + AndAnd, + Or, + OrEqual, + OrOr, + Caret, + CaretEqual, + Period, + Comma, + Semicolon, + Colon, + Question, + Arrow + ); match *self { Ident(ref name) => { f.write_str("Ident ")?; diff --git a/crates/kabel/src/lib.rs b/crates/kabel/src/lib.rs index 038a6417f640f2b70ea3e268e7711e8d5a57d5c9..b430a86ac61830caf7f8c204c7e29e71d9c654ad 100644 --- a/crates/kabel/src/lib.rs +++ b/crates/kabel/src/lib.rs @@ -4,22 +4,22 @@ use std::time::Instant; use ast::AST; use codegen::Codegen; use lexer::{Lexer, Token}; -use parser::Parser; use name_resolution::Resolver; +use parser::Parser; +pub mod ast; +pub mod codegen; pub mod debug; pub mod error; -pub mod runtime_error; +pub mod extension; pub mod lexer; pub mod macros; -pub mod parser; -pub mod ast; pub mod name_resolution; pub mod opcodes; -pub mod codegen; -pub mod vm; +pub mod parser; +pub mod runtime_error; pub mod test; -pub mod extension; +pub mod vm; pub fn run_lexer(input: String) -> Lexer { let mut lexer = Lexer::new(input); diff --git a/crates/kabel/src/macros.rs b/crates/kabel/src/macros.rs index 7f9431846cc7c00f761be9a267e2fef8c01109e7..a9303093f84998ca93508667e1e43026d359dbc7 100644 --- a/crates/kabel/src/macros.rs +++ b/crates/kabel/src/macros.rs @@ -123,13 +123,15 @@ macro_rules! push_output { } } - #[macro_export] macro_rules! unexpected_token { ($self:expr, $message:expr, $token:expr, $hint:expr) => { $crate::error::KabelError::new( $crate::error::ErrorKind::UnexpectedToken, - format!($message, $self.text[$token.line][$token.start_column..$token.end_column].to_string()), + format!( + $message, + $self.text[$token.line][$token.start_column..$token.end_column].to_string() + ), Some($hint), $token.line, $token.start_column, @@ -139,7 +141,10 @@ macro_rules! unexpected_token { ($self:expr, $message:expr, $token:expr) => { $crate::error::KabelError::new( $crate::error::ErrorKind::UnexpectedToken, - format!($message, $self.text[$token.line][$token.start_column..$token.end_column].to_string()), + format!( + $message, + $self.text[$token.line][$token.start_column..$token.end_column].to_string() + ), None, $token.line, $token.start_column, @@ -268,7 +273,11 @@ macro_rules! wrong_type { #[macro_export] macro_rules! collect_lines { ($string:expr) => { - $string.iter().fold("".to_string(), |acc, string| acc + string + "\n").trim_end().to_string() + $string + .iter() + .fold("".to_string(), |acc, string| acc + string + "\n") + .trim_end() + .to_string() }; } diff --git a/crates/kabel/src/main.rs b/crates/kabel/src/main.rs index 19c35be556f4a46dc9d03b52ffc13ce785a7576f..6dcb088397b267d686a2f41fec1799a820bfaf5b 100644 --- a/crates/kabel/src/main.rs +++ b/crates/kabel/src/main.rs @@ -2,7 +2,10 @@ use std::{env, fs, process::exit}; -use kabel::{debug::{debug_ast, debug_bytecode}, run_codegen, run_lexer, run_parser, run_semantic_analysis}; +use kabel::{ + debug::{debug_ast, debug_bytecode}, + run_codegen, run_lexer, run_parser, run_semantic_analysis, +}; fn main() { let args: Vec = env::args().collect(); @@ -10,8 +13,7 @@ fn main() { println!("Must provide kabel file to run"); exit(1); } - let program = - fs::read_to_string(args[1].clone()).unwrap(); + let program = fs::read_to_string(args[1].clone()).unwrap(); let mut output = "".to_string(); diff --git a/crates/kabel/src/name_resolution.rs b/crates/kabel/src/name_resolution.rs index 558214ef4c54bfe357d20ea14521facd15d4826f..750733d2c88ec3df2e84bea7fba58925938743c2 100644 --- a/crates/kabel/src/name_resolution.rs +++ b/crates/kabel/src/name_resolution.rs @@ -1,11 +1,17 @@ use std::collections::HashMap; -use crate::{ast::{ASTType, LhsAssign, LhsAssignType, AST}, ast_error, ast_from_ast, error::{ErrorKind, KabelError}, extension::Extension, out_of_scope_var}; +use crate::{ + ast::{ASTType, LhsAssign, LhsAssignType, AST}, + ast_error, ast_from_ast, + error::{ErrorKind, KabelError}, + extension::Extension, + out_of_scope_var, +}; pub struct Resolver { text: Vec, symbol_table: Vec>, // (Symbol, reference to locals) - pub locals: Vec>, // scope + pub locals: Vec>, // scope pub scope: usize, pub errors: Vec, } @@ -13,7 +19,12 @@ pub struct Resolver { impl Resolver { pub fn new(text: String) -> Self { Self { - text: text.lines().collect::>().iter().map(|s| s.to_string()).collect(), + text: text + .lines() + .collect::>() + .iter() + .map(|s| s.to_string()) + .collect(), symbol_table: vec![HashMap::new()], locals: vec![Vec::new()], scope: 0, @@ -58,27 +69,73 @@ impl Resolver { ErrorKind::FunctionAlreadyDeclaredFunction, ast, "Function \"{}\" already declared", name ; "hint: has function \"{}\" already been declared?", name.name)); - } else {} + } else { + } } } - self.locals.last_mut().expect("locals last in function push").push(self.scope); - self.symbol_table.last_mut().unwrap().insert(name.name.clone(), - (Symbol::Function(args.len()), self.locals.last().expect("locals last in function symbol len").len()-1)); + self.locals + .last_mut() + .expect("locals last in function push") + .push(self.scope); + self.symbol_table.last_mut().unwrap().insert( + name.name.clone(), + ( + Symbol::Function(args.len()), + self.locals + .last() + .expect("locals last in function symbol len") + .len() + - 1, + ), + ); self.locals.push(Vec::new()); self.symbol_table.push(HashMap::new()); - self.locals.last_mut().expect("locals last in function self-reference push").push(self.scope+1); - self.symbol_table.last_mut().unwrap().insert(name.name.clone(), (Symbol::Var,self.locals.last().expect("locals last in function self-reference len").len()-1)); + self.locals + .last_mut() + .expect("locals last in function self-reference push") + .push(self.scope + 1); + self.symbol_table.last_mut().unwrap().insert( + name.name.clone(), + ( + Symbol::Var, + self.locals + .last() + .expect("locals last in function self-reference len") + .len() + - 1, + ), + ); for arg in args.clone() { - self.locals.last_mut().expect("locals last in function arg push").push(self.scope+1); - self.symbol_table.last_mut().unwrap().insert(arg.name, (Symbol::Var,self.locals.last().expect("locals last in function arg len").len()-1)); + self.locals + .last_mut() + .expect("locals last in function arg push") + .push(self.scope + 1); + self.symbol_table.last_mut().unwrap().insert( + arg.name, + ( + Symbol::Var, + self.locals + .last() + .expect("locals last in function arg len") + .len() + - 1, + ), + ); } let block = self.visit(*block); self.symbol_table.pop(); self.locals.pop(); AST { kind: Function(name, args, Box::new(block)), - extensions: vec![Extension::Resolution(self.scope, self.locals.last().expect("locals last in function ast len").len()-1)], + extensions: vec![Extension::Resolution( + self.scope, + self.locals + .last() + .expect("locals last in function ast len") + .len() + - 1, + )], start_line: ast.start_line, end_line: ast.end_line, start_column: ast.start_column, @@ -101,8 +158,12 @@ impl Resolver { let block = self.visit(*block); ast_from_ast!(AST, While(Box::new(condition), Box::new(block)), ast, ast) } - Break => { ast_from_ast!(AST, Break, ast, ast) } - Continue => { ast_from_ast!(AST, Continue, ast, ast) } + Break => { + ast_from_ast!(AST, Break, ast, ast) + } + Continue => { + ast_from_ast!(AST, Continue, ast, ast) + } For(expr1, expr2, expr3, block) => { self.symbol_table.push(HashMap::new()); self.scope += 1; @@ -121,14 +182,27 @@ impl Resolver { let block = self.visit(*block); while let Some(scope) = self.locals.last().expect("locals failed in For").last() { if self.scope == *scope { - self.locals.last_mut().expect("locals failed in For pop").pop(); + self.locals + .last_mut() + .expect("locals failed in For pop") + .pop(); } else { break; } } self.scope -= 1; self.symbol_table.pop(); - ast_from_ast!(AST, For(Box::new(n_expr1), Box::new(n_expr2), Box::new(n_expr3), Box::new(block)), ast, ast) + ast_from_ast!( + AST, + For( + Box::new(n_expr1), + Box::new(n_expr2), + Box::new(n_expr3), + Box::new(block) + ), + ast, + ast + ) } If(condition, block, else_expr) => { let condition = self.visit(*condition); @@ -137,7 +211,12 @@ impl Resolver { if let Some(else_expr) = *else_expr { n_else_expr = Some(self.visit(else_expr)); } - ast_from_ast!(AST, If(Box::new(condition), Box::new(block), Box::new(n_else_expr)), ast, ast) + ast_from_ast!( + AST, + If(Box::new(condition), Box::new(block), Box::new(n_else_expr)), + ast, + ast + ) } Block(stmts) => { self.symbol_table.push(HashMap::new()); @@ -153,7 +232,10 @@ impl Resolver { }*/ while let Some(scope) = self.locals.last().expect("locals last in block").last() { if self.scope == *scope { - self.locals.last_mut().expect("locals last in block pop").pop(); + self.locals + .last_mut() + .expect("locals last in block pop") + .pop(); } else { break; } @@ -164,7 +246,10 @@ impl Resolver { } Decl(name, expr) => { let expr = self.visit(*expr); - self.locals.last_mut().expect("locals last in decl push").push(self.scope); + self.locals + .last_mut() + .expect("locals last in decl push") + .push(self.scope); let resolution = self.resolve_var(&name.name); if resolution.0 && resolution.2 == self.scope { self.errors.push(out_of_scope_var!(self, @@ -185,13 +270,27 @@ impl Resolver { ErrorKind::VariableAlreadyDeclaredFunction, ast, "Variable \"{}\" already declared", name ; "hint: has function \"{}\" already been declared?", name.name)); - } else {} + } else { + } } } - self.symbol_table.last_mut().unwrap().insert(name.name.clone(), (Symbol::Var, self.locals.last().expect("locals last in decl symbol").len()-1)); + self.symbol_table.last_mut().unwrap().insert( + name.name.clone(), + ( + Symbol::Var, + self.locals + .last() + .expect("locals last in decl symbol") + .len() + - 1, + ), + ); AST { kind: Decl(name, Box::new(expr)), - extensions: vec![Extension::Resolution(self.scope, self.locals.last().expect("locals last in decl ast").len()-1)], + extensions: vec![Extension::Resolution( + self.scope, + self.locals.last().expect("locals last in decl ast").len() - 1, + )], start_line: ast.start_line, end_line: ast.end_line, start_column: ast.start_column, @@ -207,15 +306,19 @@ impl Resolver { let expr = self.visit(*expr); ast_from_ast!(AST, Print(Box::new(expr)), ast, ast) } - Assign(lhs , expr) => { + Assign(lhs, expr) => { let expr = self.visit(*expr); match lhs.kind.clone() { LhsAssignType::Ident(name) => { let resolution = self.resolve_var(&name); if !resolution.0 { - self.errors.push(out_of_scope_var!(self, - ErrorKind::OutOfScope, lhs, - "Variable \"{}\" not in scope", name)); + self.errors.push(out_of_scope_var!( + self, + ErrorKind::OutOfScope, + lhs, + "Variable \"{}\" not in scope", + name + )); } AST { kind: Assign(lhs, Box::new(expr)), @@ -230,7 +333,15 @@ impl Resolver { let name = self.visit(*name); let index = self.visit(*index); AST { - kind: Assign(ast_from_ast!(LhsAssign, LhsAssignType::Subscript(Box::new(name), Box::new(index)), lhs, lhs), Box::new(expr)), + kind: Assign( + ast_from_ast!( + LhsAssign, + LhsAssignType::Subscript(Box::new(name), Box::new(index)), + lhs, + lhs + ), + Box::new(expr), + ), extensions: Vec::new(), start_line: ast.start_line, end_line: ast.end_line, @@ -243,10 +354,26 @@ impl Resolver { Anonymous(params, block) => { self.locals.push(Vec::new()); self.symbol_table.push(HashMap::new()); - self.locals.last_mut().expect("locals last in anonymous self-reference push").push(self.scope); + self.locals + .last_mut() + .expect("locals last in anonymous self-reference push") + .push(self.scope); for param in params.clone() { - self.locals.last_mut().expect("locals last in anonymous param push").push(self.scope+1); - self.symbol_table.last_mut().unwrap().insert(param.name, (Symbol::Var,self.locals.last().expect("locals last in anonymous param len").len()-1)); + self.locals + .last_mut() + .expect("locals last in anonymous param push") + .push(self.scope + 1); + self.symbol_table.last_mut().unwrap().insert( + param.name, + ( + Symbol::Var, + self.locals + .last() + .expect("locals last in anonymous param len") + .len() + - 1, + ), + ); } let block = self.visit(*block); self.symbol_table.pop(); @@ -257,7 +384,16 @@ impl Resolver { let condition = self.visit(*condition); let true_expr = self.visit(*true_expr); let false_expr = self.visit(*false_expr); - ast_from_ast!(AST, Ternary(Box::new(condition), Box::new(true_expr), Box::new(false_expr)), ast, ast) + ast_from_ast!( + AST, + Ternary( + Box::new(condition), + Box::new(true_expr), + Box::new(false_expr) + ), + ast, + ast + ) } Subscript(array, index) => { let array = self.visit(*array); @@ -279,7 +415,13 @@ impl Resolver { crate::ast::Lit::Ident(ref name) => { let resolution = self.resolve_var(name); if !resolution.0 { - self.errors.push(ast_error!(self, ErrorKind::OutOfScope, ast, "Variable \"{}\" not in scope", name)) + self.errors.push(ast_error!( + self, + ErrorKind::OutOfScope, + ast, + "Variable \"{}\" not in scope", + name + )) } else { return AST { kind: Lit(lit), @@ -313,7 +455,9 @@ impl Resolver { /*Member(left, right) => { self.visit_member(*left, *right); }*/ - _ => { panic!("not implemented") } // not implemented + _ => { + panic!("not implemented") + } // not implemented } } // TODO: make visit_member not throw out of scope errors @@ -323,13 +467,18 @@ impl Resolver { }*/ fn resolve_var(&self, name: &String) -> (bool, usize, usize) { for (scope_num, scope) in self.symbol_table.iter().enumerate().rev() { - if let Some((Symbol::Var, place)) | Some((Symbol::Function(_), place)) = scope.get(name) { + if let Some((Symbol::Var, place)) | Some((Symbol::Function(_), place)) = scope.get(name) + { return (true, *place, scope_num); } } (false, 0, 0) } - fn resolve_function(&mut self, name: &String, arity: usize) -> Result, Option)>{ + fn resolve_function( + &mut self, + name: &String, + arity: usize, + ) -> Result, Option)> { for scope in self.symbol_table.iter().rev() { if let Some((Symbol::Function(f_arity), place)) = scope.get(name) { if *f_arity == arity { diff --git a/crates/kabel/src/opcodes.rs b/crates/kabel/src/opcodes.rs index 8584e0c6d9059db5d64e0a62640167678e5d2516..0b27cfc4f69f6d5a59087c72200cc4ac11abe7b5 100644 --- a/crates/kabel/src/opcodes.rs +++ b/crates/kabel/src/opcodes.rs @@ -48,52 +48,53 @@ impl From for u8 { fn from(value: OpCode) -> Self { use OpCode::*; match value { - LOAD => 0x00, - VAR => 0x01, - REF => 0x02, - ASN => 0x03, - ASNARR => 0x04, - DECL => 0x05, - - ADD => 0x06, - SUB => 0x07, - MUL => 0x08, - DIV => 0x09, - MOD => 0x0A, - BITAND => 0x0B, - BITXOR => 0x0C, - BITOR => 0x0D, - EQ => 0x0E, - NE => 0x0F, - GR => 0x10, - GE => 0x11, - LS => 0x12, - LE => 0x13, - OR => 0x14, - AND => 0x15, - - NOT => 0x16, - NEG => 0x17, - - JMP => 0x18, - JMP_UP => 0x19, - JNE => 0x1A, - - CALL => 0x1B, - RET => 0x1C, - - LIST => 0x1D, - SCR => 0x1E, - - POP => 0xFD, - PRINT => 0xFE, - ERR => 0xFF + LOAD => 0x00, + VAR => 0x01, + REF => 0x02, + ASN => 0x03, + ASNARR => 0x04, + DECL => 0x05, + + ADD => 0x06, + SUB => 0x07, + MUL => 0x08, + DIV => 0x09, + MOD => 0x0A, + BITAND => 0x0B, + BITXOR => 0x0C, + BITOR => 0x0D, + EQ => 0x0E, + NE => 0x0F, + GR => 0x10, + GE => 0x11, + LS => 0x12, + LE => 0x13, + OR => 0x14, + AND => 0x15, + + NOT => 0x16, + NEG => 0x17, + + JMP => 0x18, + JMP_UP => 0x19, + JNE => 0x1A, + + CALL => 0x1B, + RET => 0x1C, + + LIST => 0x1D, + SCR => 0x1E, + + POP => 0xFD, + PRINT => 0xFE, + ERR => 0xFF, } } } impl From for OpCode { fn from(value: u8) -> Self { - use OpCode::*; match value { + use OpCode::*; + match value { 0x00 => LOAD, 0x01 => VAR, 0x02 => REF, @@ -133,7 +134,7 @@ impl From for OpCode { 0xFD => POP, 0xFE => PRINT, - _ => ERR + _ => ERR, } } } diff --git a/crates/kabel/src/parser.rs b/crates/kabel/src/parser.rs index 82c9dbd1e3dcb52a2d49d60ac7c52eae486c8047..dc586f455d264a796ad8824224c5dfe0cc6e0117 100644 --- a/crates/kabel/src/parser.rs +++ b/crates/kabel/src/parser.rs @@ -1,7 +1,11 @@ +use crate::ast::{ASTType, BinOp, Lit, UnOp, AST}; use crate::{ - ast::{LhsAssign, LhsAssignType}, ast_from_ast, ast_from_ast_token, ast_from_token, ast_from_token_ast, collect_lines, error::{ErrorKind, KabelError}, lexer::{Token, TokenType}, lit, name, unexpected_token + ast::{LhsAssign, LhsAssignType}, + ast_from_ast, ast_from_ast_token, ast_from_token, ast_from_token_ast, collect_lines, + error::{ErrorKind, KabelError}, + lexer::{Token, TokenType}, + lit, name, unexpected_token, }; -use crate::ast::{AST, ASTType, BinOp, UnOp, Lit}; pub struct Parser { input: Vec, @@ -15,7 +19,12 @@ impl Parser { pub fn new(text: String, input: Vec) -> Self { Self { input: input.clone(), - text: text.lines().collect::>().iter().map(|s| s.to_string()).collect(), + text: text + .lines() + .collect::>() + .iter() + .map(|s| s.to_string()) + .collect(), current: 0, token: input[0].clone(), errors: Vec::new(), @@ -72,7 +81,11 @@ impl Parser { if let TokenType::Ident(name) = ident.token_type { expressions.push(name!(name, ident)); } else { - return Err(unexpected_token!(self, "Expected identifier but found {}", ident)); + return Err(unexpected_token!( + self, + "Expected identifier but found {}", + ident + )); } if let TokenType::Comma = self.peek()?.token_type { self.read_token()?; @@ -81,20 +94,25 @@ impl Parser { let right_paren = self.read_token()?; if let TokenType::RightParen = right_paren.token_type { let block = self.block()?; - return Ok(ast_from_token_ast!(AST, - ASTType::Function( - name!(name, ident), - expressions, - Box::new(block.clone()) - ), + return Ok(ast_from_token_ast!( + AST, + ASTType::Function(name!(name, ident), expressions, Box::new(block.clone())), function_ident, block )); } else { - return Err(unexpected_token!(self, "Expected ) but found {}", right_paren)); + return Err(unexpected_token!( + self, + "Expected ) but found {}", + right_paren + )); } } else { - return Err(unexpected_token!(self, "Expected ( but found {}", left_paren)); + return Err(unexpected_token!( + self, + "Expected ( but found {}", + left_paren + )); } } else { return Err(unexpected_token!( @@ -109,7 +127,8 @@ impl Parser { let return_ident = self.read_token()?; if let TokenType::Semicolon = self.peek()?.token_type { let semicolon = self.read_token()?; - return Ok(ast_from_token!(AST, + return Ok(ast_from_token!( + AST, ASTType::Return(Box::new(None)), return_ident, semicolon @@ -118,20 +137,26 @@ impl Parser { let expression = self.expression()?; let semicolon = self.read_token()?; if let TokenType::Semicolon = semicolon.token_type { - Ok(ast_from_token!(AST, + Ok(ast_from_token!( + AST, ASTType::Return(Box::new(Some(expression))), return_ident, semicolon )) } else { - return Err(unexpected_token!(self, "Expected ; but found {}", semicolon)); + return Err(unexpected_token!( + self, + "Expected ; but found {}", + semicolon + )); } } pub fn loop_statement(&mut self) -> Result { let loop_ident = self.read_token()?; let block = self.block()?; - Ok(ast_from_token_ast!(AST, + Ok(ast_from_token_ast!( + AST, ASTType::Loop(Box::new(block.clone())), loop_ident, block @@ -146,16 +171,25 @@ impl Parser { let right_paren = self.read_token()?; if let TokenType::RightParen = right_paren.token_type { let block = self.block()?; - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::While(Box::new(condition), Box::new(block.clone())), while_ident, block )); } else { - return Err(unexpected_token!(self, "Expected ) but found {}", right_paren)); + return Err(unexpected_token!( + self, + "Expected ) but found {}", + right_paren + )); } } else { - return Err(unexpected_token!(self, "Expected ( but found {}", left_paren)); + return Err(unexpected_token!( + self, + "Expected ( but found {}", + left_paren + )); } } @@ -172,9 +206,14 @@ impl Parser { } else { expression1 = Some(self.expression()?); let semicolon = self.read_token()?; - if let TokenType::Semicolon = semicolon.token_type {} else { + if let TokenType::Semicolon = semicolon.token_type { + } else { self.current -= 1; - return Err(unexpected_token!(self, "Expected ; but found {}", semicolon)); + return Err(unexpected_token!( + self, + "Expected ; but found {}", + semicolon + )); } } } @@ -188,14 +227,16 @@ impl Parser { if let TokenType::Semicolon = semicolon_2.token_type { let expression3; if let TokenType::RightParen = self.peek()?.token_type { - expression3 = None; } else { + expression3 = None; + } else { expression3 = Some(self.expression()?); } let right_paren = self.read_token()?; if let TokenType::RightParen = right_paren.token_type { let block = self.block()?; //return Ok(Self::build_for(for_ident, semicolon_2, expression1, expression2, expression3, block)); - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::For( Box::new(expression1), Box::new(expression2), @@ -206,13 +247,25 @@ impl Parser { block )); } else { - return Err(unexpected_token!(self, "Expected ) but found {}", right_paren)); + return Err(unexpected_token!( + self, + "Expected ) but found {}", + right_paren + )); } } else { - return Err(unexpected_token!(self, "Expected ; but found {}", semicolon_2)); + return Err(unexpected_token!( + self, + "Expected ; but found {}", + semicolon_2 + )); } } else { - return Err(unexpected_token!(self, "Expected ( but found {}", left_paren)); + return Err(unexpected_token!( + self, + "Expected ( but found {}", + left_paren + )); } } /*fn build_for(for_ident: Token, semicolon_2: Token, expression1: Option, expression2: Option, expression3: Option, block: AST) -> AST { @@ -243,7 +296,11 @@ impl Parser { if let TokenType::Semicolon = semicolon.token_type { Ok(ast_from_token!(AST, ASTType::Break, break_ident, semicolon)) } else { - Err(unexpected_token!(self, "Expected ; but found {}", semicolon)) + Err(unexpected_token!( + self, + "Expected ; but found {}", + semicolon + )) } } @@ -251,9 +308,18 @@ impl Parser { let continue_ident = self.read_token()?; let semicolon = self.read_token()?; if let TokenType::Semicolon = semicolon.token_type { - Ok(ast_from_token!(AST, ASTType::Continue, continue_ident, semicolon)) + Ok(ast_from_token!( + AST, + ASTType::Continue, + continue_ident, + semicolon + )) } else { - Err(unexpected_token!(self, "Expected ; but found {}", semicolon)) + Err(unexpected_token!( + self, + "Expected ; but found {}", + semicolon + )) } } @@ -271,7 +337,8 @@ impl Parser { self.read_token()?; if let TokenType::LeftBrace = self.peek()?.token_type { let else_block = self.block()?; - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::If( Box::new(condition), Box::new(block.clone()), @@ -284,7 +351,8 @@ impl Parser { let else_if_ident = self.peek()?; if let TokenType::If = else_if_ident.token_type { let else_if = self.if_statement()?; - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::If( Box::new(condition), Box::new(block.clone()), @@ -297,16 +365,25 @@ impl Parser { return Err(unexpected_token!(self, "Unexpected token {}", else_ident)); } } - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::If(Box::new(condition), Box::new(block.clone()), Box::new(None)), if_ident, block )); } else { - return Err(unexpected_token!(self, "Expected ) but found {}", right_paren)); + return Err(unexpected_token!( + self, + "Expected ) but found {}", + right_paren + )); } } else { - return Err(unexpected_token!(self, "Expected ( but found {}", left_paren)); + return Err(unexpected_token!( + self, + "Expected ( but found {}", + left_paren + )); } } @@ -318,9 +395,18 @@ impl Parser { stmts.push(self.statement()?); } let right_brace = self.read_token()?; - return Ok(ast_from_token!(AST, ASTType::Block(stmts), left_brace, right_brace)); + return Ok(ast_from_token!( + AST, + ASTType::Block(stmts), + left_brace, + right_brace + )); } else { - return Err(unexpected_token!(self, "Expected {{ but found {}", left_brace)); + return Err(unexpected_token!( + self, + "Expected {{ but found {}", + left_brace + )); } } @@ -333,7 +419,8 @@ impl Parser { let expr = self.expression()?; let semicolon = self.read_token()?; if let TokenType::Semicolon = semicolon.token_type { - return Ok(ast_from_token!(AST, + return Ok(ast_from_token!( + AST, ASTType::Decl(name!(name, ident), Box::new(expr.clone())), var, semicolon @@ -359,9 +446,18 @@ impl Parser { let expression = self.expression()?; let semicolon = self.read_token()?; if matches!(semicolon.token_type, TokenType::Semicolon) { - Ok(ast_from_token!(AST, ASTType::Print(Box::new(expression)), print_ident, semicolon)) + Ok(ast_from_token!( + AST, + ASTType::Print(Box::new(expression)), + print_ident, + semicolon + )) } else { - Err(unexpected_token!(self, "Expected ; but found {}", semicolon)) + Err(unexpected_token!( + self, + "Expected ; but found {}", + semicolon + )) } } @@ -380,11 +476,19 @@ impl Parser { } let semicolon = self.read_token()?; if let TokenType::Semicolon = semicolon.token_type { - return Ok(ast_from_ast_token!(AST, ASTType::Expr(Box::new(expression.clone())), - expression, semicolon)); + return Ok(ast_from_ast_token!( + AST, + ASTType::Expr(Box::new(expression.clone())), + expression, + semicolon + )); } else { self.current -= 1; - return Err(unexpected_token!(self, "Expected ; but found {}", semicolon)); + return Err(unexpected_token!( + self, + "Expected ; but found {}", + semicolon + )); } } @@ -401,9 +505,18 @@ impl Parser { self.read_token()?; let index = self.expression()?; let right_square = self.read_token()?; - lhs_type = ast_from_token!(LhsAssign, LhsAssignType::Subscript(Box::new(lit!(Ident, name.clone(), ident)), Box::new(index)), ident, right_square); + lhs_type = ast_from_token!( + LhsAssign, + LhsAssignType::Subscript( + Box::new(lit!(Ident, name.clone(), ident)), + Box::new(index) + ), + ident, + right_square + ); } else { - lhs_type = ast_from_token!(LhsAssign, LhsAssignType::Ident(name.clone()), ident, ident); + lhs_type = + ast_from_token!(LhsAssign, LhsAssignType::Ident(name.clone()), ident, ident); } if self.current >= self.input.len() { self.current -= 1; @@ -422,20 +535,20 @@ impl Parser { let binop = self.read_token()?; let expr = self.expression()?; if binop.token_type == TokenType::Equal { - return Ok(ast_from_token_ast!(AST, - ASTType::Assign( - lhs_type, - Box::new(expr.clone()) - ), + return Ok(ast_from_token_ast!( + AST, + ASTType::Assign(lhs_type, Box::new(expr.clone())), ident, expr )); } else if binop.token_type == TokenType::PlusEqual { - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::Assign( lhs_type, Box::new( - ast_from_ast!(AST, + ast_from_ast!( + AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Add, @@ -451,11 +564,13 @@ impl Parser { expr )); } else if binop.token_type == TokenType::MinusEqual { - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::Assign( lhs_type, Box::new( - ast_from_ast!(AST, + ast_from_ast!( + AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Sub, @@ -471,11 +586,13 @@ impl Parser { expr )); } else if binop.token_type == TokenType::StarEqual { - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::Assign( lhs_type, Box::new( - ast_from_ast!(AST, + ast_from_ast!( + AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Mul, @@ -491,11 +608,13 @@ impl Parser { expr )); } else if binop.token_type == TokenType::SlashEqual { - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::Assign( lhs_type, Box::new( - ast_from_ast!(AST, + ast_from_ast!( + AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Div, @@ -511,11 +630,13 @@ impl Parser { expr )); } else if binop.token_type == TokenType::PercentEqual { - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::Assign( lhs_type, Box::new( - ast_from_ast!(AST, + ast_from_ast!( + AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Mod, @@ -531,11 +652,13 @@ impl Parser { expr )); } else if binop.token_type == TokenType::AndEqual { - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::Assign( lhs_type, Box::new( - ast_from_ast!(AST, + ast_from_ast!( + AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::BitAnd, @@ -551,11 +674,13 @@ impl Parser { expr )); } else if binop.token_type == TokenType::CaretEqual { - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::Assign( lhs_type, Box::new( - ast_from_ast!(AST, + ast_from_ast!( + AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::BitXor, @@ -571,11 +696,13 @@ impl Parser { expr )); } else { - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::Assign( lhs_type, Box::new( - ast_from_ast!(AST, + ast_from_ast!( + AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::BitOr, @@ -613,7 +740,11 @@ impl Parser { if let TokenType::Ident(name) = ident.token_type { params.push(name!(name, ident)); } else { - return Err(unexpected_token!(self, "Expected identifier but found {}", ident)); + return Err(unexpected_token!( + self, + "Expected identifier but found {}", + ident + )); } if let TokenType::Comma = self.peek()?.token_type { self.read_token()?; @@ -624,10 +755,19 @@ impl Parser { self.read_token()?; if let TokenType::LeftBrace = self.peek()?.token_type { let block = self.block()?; - return Ok(ast_from_token_ast!(AST, ASTType::Anonymous(params, Box::new(block.clone())), left_paren, block)); + return Ok(ast_from_token_ast!( + AST, + ASTType::Anonymous(params, Box::new(block.clone())), + left_paren, + block + )); } else { let left_brace = self.read_token()?; - return Err(unexpected_token!(self, "Expected {{ but found {}", left_brace)); + return Err(unexpected_token!( + self, + "Expected {{ but found {}", + left_brace + )); } } else { let arrow = self.read_token()?; @@ -640,10 +780,19 @@ impl Parser { self.read_token()?; if let TokenType::LeftBrace = self.peek()?.token_type { let block = self.block()?; - return Ok(ast_from_token_ast!(AST, ASTType::Anonymous(params, Box::new(block.clone())), left_paren, block)); + return Ok(ast_from_token_ast!( + AST, + ASTType::Anonymous(params, Box::new(block.clone())), + left_paren, + block + )); } else { let left_brace = self.read_token()?; - return Err(unexpected_token!(self, "Expected {{ but found {}", left_brace)); + return Err(unexpected_token!( + self, + "Expected {{ but found {}", + left_brace + )); } } else { let arrow = self.read_token()?; @@ -659,7 +808,12 @@ impl Parser { if let TokenType::Arrow = self.peek()?.token_type { self.read_token()?; let block = self.block()?; - return Ok(ast_from_token_ast!(AST, ASTType::Anonymous(Vec::new(), Box::new(block.clone())), left_paren, block)); + return Ok(ast_from_token_ast!( + AST, + ASTType::Anonymous(Vec::new(), Box::new(block.clone())), + left_paren, + block + )); } else { let arrow = self.read_token()?; return Err(unexpected_token!(self, "Expected => but found {}", arrow)); @@ -682,7 +836,8 @@ impl Parser { if let TokenType::Colon = self.peek()?.token_type { self.read_token()?; let false_expr = self.expression()?; - return Ok(ast_from_ast!(AST, + return Ok(ast_from_ast!( + AST, ASTType::Ternary( Box::new(condition.clone()), Box::new(true_expr), @@ -692,7 +847,11 @@ impl Parser { false_expr )); } else { - return Err(unexpected_token!(self, "Expected : but found {}", self.token)); + return Err(unexpected_token!( + self, + "Expected : but found {}", + self.token + )); } } @@ -705,7 +864,8 @@ impl Parser { while self.current < self.input.len() && self.peek()?.token_type == TokenType::OrOr { self.read_token()?; let right = self.logical_and()?; - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Or, Box::new(right.clone())), left, right @@ -720,7 +880,8 @@ impl Parser { while self.current < self.input.len() && self.peek()?.token_type == TokenType::AndAnd { self.read_token()?; let right = self.bit_and()?; - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::And, Box::new(right.clone())), left, right @@ -735,7 +896,8 @@ impl Parser { while self.current < self.input.len() && self.peek()?.token_type == TokenType::And { self.read_token()?; let right = self.bit_xor()?; - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary( Box::new(left.clone()), BinOp::BitAnd, @@ -754,7 +916,8 @@ impl Parser { while self.current < self.input.len() && self.peek()?.token_type == TokenType::Caret { self.read_token()?; let right = self.bit_or()?; - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary( Box::new(left.clone()), BinOp::BitXor, @@ -773,7 +936,8 @@ impl Parser { while self.current < self.input.len() && self.peek()?.token_type == TokenType::Or { self.read_token()?; let right = self.equality()?; - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary( Box::new(left.clone()), BinOp::BitOr, @@ -796,13 +960,15 @@ impl Parser { let binop = self.read_token()?; let right = self.comparison()?; if binop.token_type == TokenType::EqualEqual { - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Eq, Box::new(right.clone())), left, right ); } else { - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Ne, Box::new(right.clone())), left, right @@ -825,25 +991,29 @@ impl Parser { let binop = self.read_token()?; let right = self.term()?; if binop.token_type == TokenType::Less { - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Ls, Box::new(right.clone())), left, right ); } else if binop.token_type == TokenType::LessEqual { - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Le, Box::new(right.clone())), left, right ); } else if binop.token_type == TokenType::Greater { - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Gr, Box::new(right.clone())), left, right ); } else { - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Ge, Box::new(right.clone())), left, right @@ -865,13 +1035,15 @@ impl Parser { let right = self.factor()?; if binop.token_type == TokenType::Plus { - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Add, Box::new(right.clone())), left, right ); } else { - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Sub, Box::new(right.clone())), left, right @@ -892,19 +1064,22 @@ impl Parser { let right = self.unary()?; if binop.token_type == TokenType::Star { - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Mul, Box::new(right.clone())), left, right ); } else if binop.token_type == TokenType::Slash { - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Div, Box::new(right.clone())), left, right ); } else { - left = ast_from_ast!(AST, + left = ast_from_ast!( + AST, ASTType::Binary(Box::new(left.clone()), BinOp::Mod, Box::new(right.clone())), left, right @@ -918,13 +1093,15 @@ impl Parser { let token = self.read_token()?; let unary = self.unary()?; if token.token_type == TokenType::Bang { - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::Unary(UnOp::Not, Box::new(unary.clone())), token, unary )); } else { - return Ok(ast_from_token_ast!(AST, + return Ok(ast_from_token_ast!( + AST, ASTType::Unary(UnOp::Neg, Box::new(unary.clone())), token, unary @@ -942,13 +1119,18 @@ impl Parser { let expr = self.expression()?; let right_brace = self.read_token()?; if let TokenType::RightSquare = right_brace.token_type { - primary = ast_from_ast_token!(AST, + primary = ast_from_ast_token!( + AST, ASTType::Subscript(Box::new(primary.clone()), Box::new(expr)), primary, right_brace ); } else { - return Err(unexpected_token!(self, "Expected ] but found {}", right_brace)); + return Err(unexpected_token!( + self, + "Expected ] but found {}", + right_brace + )); } } @@ -1001,7 +1183,8 @@ impl Parser { } } let right_square = self.read_token()?; - Ok(ast_from_token!(AST, + Ok(ast_from_token!( + AST, ASTType::Lit(Lit::Array(expressions)), left_square, right_square @@ -1018,7 +1201,8 @@ impl Parser { if self.current < self.input.len() { if let TokenType::LeftParen = self.peek()?.token_type { let call = self.call(child)?; - expr = ast_from_ast!(AST, + expr = ast_from_ast!( + AST, ASTType::Member(Box::new(expr.clone()), Box::new(call.clone())), expr, call @@ -1029,7 +1213,8 @@ impl Parser { continue; } } - expr = ast_from_ast_token!(AST, + expr = ast_from_ast_token!( + AST, ASTType::Member( Box::new(expr.clone()), Box::new(lit!(Ident, child_str, child)) @@ -1060,7 +1245,8 @@ impl Parser { } let right_paren = self.read_token()?; if let TokenType::Ident(name) = ident.token_type { - return Ok(ast_from_token!(AST, + return Ok(ast_from_token!( + AST, ASTType::Call(Box::new(lit!(Ident, name, ident)), expressions), ident, right_paren @@ -1072,10 +1258,17 @@ impl Parser { if let TokenType::Ident(name) = ident.token_type { let oper = self.read_token()?; if oper.token_type == TokenType::PlusPlus { - return Ok(ast_from_token!(AST, + return Ok(ast_from_token!( + AST, ASTType::Assign( - ast_from_token!(LhsAssign, LhsAssignType::Ident(name.clone()), ident, ident), - Box::new(ast_from_token!(AST, + ast_from_token!( + LhsAssign, + LhsAssignType::Ident(name.clone()), + ident, + ident + ), + Box::new(ast_from_token!( + AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Add, @@ -1089,10 +1282,17 @@ impl Parser { oper )); } else { - return Ok(ast_from_token!(AST, + return Ok(ast_from_token!( + AST, ASTType::Assign( - ast_from_token!(LhsAssign, LhsAssignType::Ident(name.clone()), ident, ident), - Box::new(ast_from_token!(AST, + ast_from_token!( + LhsAssign, + LhsAssignType::Ident(name.clone()), + ident, + ident + ), + Box::new(ast_from_token!( + AST, ASTType::Binary( Box::new(lit!(Ident, name, ident)), BinOp::Sub, @@ -1121,15 +1321,13 @@ impl Parser { None, right_paren.line, right_paren.start_column, - self.text[left_paren.line..right_paren.line].iter().fold("".to_string(), |acc, string| acc + string + "\n"), + self.text[left_paren.line..right_paren.line] + .iter() + .fold("".to_string(), |acc, string| acc + string + "\n"), )); } self.read_token()?; - return Ok(ast_from_token!(AST, - expr.kind, - left_paren, - right_paren - )); + return Ok(ast_from_token!(AST, expr.kind, left_paren, right_paren)); } if let Err(e) = right_paren { return Err(KabelError::new( diff --git a/crates/kabel/src/runtime_error.rs b/crates/kabel/src/runtime_error.rs index 09f355ad6be2422913df8134990572a708e8eb01..9a7a3cec790e43ebcf01a4cecfe460010858ac69 100644 --- a/crates/kabel/src/runtime_error.rs +++ b/crates/kabel/src/runtime_error.rs @@ -8,7 +8,13 @@ pub struct KabelRuntimeError { } impl KabelRuntimeError { - pub fn new(kind: RuntimeErrorKind, message: String, hint: Option, line: usize, code: String) -> Self { + pub fn new( + kind: RuntimeErrorKind, + message: String, + hint: Option, + line: usize, + code: String, + ) -> Self { Self { kind, message, diff --git a/crates/kabel/src/test.rs b/crates/kabel/src/test.rs index cca6b53fc0612757428962a7de54ed3386d9dbbb..325c871b94cb92fd951245a32964d4fce6d16d17 100644 --- a/crates/kabel/src/test.rs +++ b/crates/kabel/src/test.rs @@ -1,6 +1,9 @@ use test_each_file::test_each_file; -use crate::{debug::{debug_ast, debug_token_array}, run_lexer, run_parser}; +use crate::{ + debug::{debug_ast, debug_token_array}, + run_lexer, run_parser, +}; test_each_file! { for ["kab", "out"] in "./crates/kabel/test/runtime/" => test } test_each_file! { for ["kab", "out"] in "./crates/kabel/test/lexer/" => test_lexer } diff --git a/crates/kabel/src/vm.rs b/crates/kabel/src/vm.rs index 84c54ef42d4162bdd32a49478488066f6a7380d5..edce23dd7e408bd0d2a44f7130d9f185e667cdaa 100644 --- a/crates/kabel/src/vm.rs +++ b/crates/kabel/src/vm.rs @@ -1,6 +1,8 @@ - -use crate::{runtime_error::{KabelRuntimeError, RuntimeErrorKind}, vm_boolean_comparison, vm_boolean_equality}; use crate::vm_error; +use crate::{ + runtime_error::{KabelRuntimeError, RuntimeErrorKind}, + vm_boolean_comparison, vm_boolean_equality, +}; #[derive(Debug, Clone)] pub struct Unit { @@ -10,11 +12,7 @@ pub struct Unit { } impl Unit { pub fn new(code: Vec, pool: Vec, lines: Vec<(usize, usize)>) -> Self { - Self { - code, - pool, - lines, - } + Self { code, pool, lines } } pub fn new_empty() -> Self { Self { @@ -34,12 +32,16 @@ pub struct VM { pub stack: Vec, pub variables: Vec, pub variables_offset: usize, - text: Vec + text: Vec, } impl VM { - pub fn new(bytecode: Vec, lines: Vec<(usize, usize)>, pool: Vec, - text: String) -> Self { + pub fn new( + bytecode: Vec, + lines: Vec<(usize, usize)>, + pool: Vec, + text: String, + ) -> Self { Self { ip: 0, unit_ptr: 0, @@ -55,35 +57,45 @@ impl VM { use Value::*; while self.ip < self.units[self.unit_ptr].code.len() { match self.read() { - 0x00 => { // LOAD + 0x00 => { + // LOAD let byte = self.read() as usize; println!("ip: {}", self.ip); let value = self.units[self.unit_ptr].pool[byte].clone(); self.stack.push(value); } - 0x01 => { // VAR + 0x01 => { + // VAR let ptr = self.read() as usize; - let value = self.variables[ptr+self.variables_offset].clone(); + let value = self.variables[ptr + self.variables_offset].clone(); self.stack.push(value); } - 0x02 => { // REF + 0x02 => { + // REF let ptr = self.read() as usize; self.stack.push(Ref(ptr)); } - 0x03 => { // ASN + 0x03 => { + // ASN let value = self.stack.pop().unwrap(); let ptr = self.read(); let offset = self.call_stack.last().expect("var call stack last").2; self.variables[ptr as usize + offset] = value.clone(); self.stack.push(value); } - 0x04 => { // ASNARR + 0x04 => { + // ASNARR let listref = self.stack.pop().unwrap(); let index = self.stack.pop().unwrap(); let value = self.stack.pop().unwrap(); if let Value::Num(index) = index { if index.fract() != 0.0 { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Subscript index must be an integer but found {}", index)) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Subscript index must be an integer but found {}", + index + )); } let index = index as usize; if let Value::Ref(listref) = listref { @@ -91,166 +103,333 @@ impl VM { if let Value::List(ref mut list) = list { let len = list.len(); if index > len { - return Err(vm_error!(self, RuntimeErrorKind::ArrayOutOfBounds, "List length is {} but found index {}", len, index)) + return Err(vm_error!( + self, + RuntimeErrorKind::ArrayOutOfBounds, + "List length is {} but found index {}", + len, + index + )); } println!("index: {}", index); list[index] = value.clone(); self.stack.push(value); } else { let type_str = list.type_str(); - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to subscript non-list type {}", type_str)) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to subscript non-list type {}", + type_str + )); } } else { panic!("Something went wrong in kabel, listref was not a Ref"); } } else { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to use non-integer type {} to subscript list", index.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to use non-integer type {} to subscript list", + index.type_str() + )); } } - 0x05 => { // DECL + 0x05 => { + // DECL let value = self.stack.pop().unwrap(); self.variables.push(value); } - 0x06 => { // ADD + 0x06 => { + // ADD match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { (Num(v1), Num(v2)) => self.stack.push(Num(v1 + v2)), (Str(v1), Str(v2)) => { self.stack.push(Str(v1.clone() + &v2)); - }, + } (Bool(_v1), Bool(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot add booleans")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot add booleans" + )) } (v1, v2) => { - return Err(vm_error!(self, RuntimeErrorKind::MismatchedTypes, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::MismatchedTypes, + "Mismatched types: {} and {}", + v1.type_str(), + v2.type_str() + )) } } } - 0x07 => { // SUB + 0x07 => { + // SUB match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { (Num(v1), Num(v2)) => self.stack.push(Num(v1 - v2)), (Str(_v1), Str(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot subtract strings")) - }, + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot subtract strings" + )) + } (Bool(_v1), Bool(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot subtract booleans")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot subtract booleans" + )) } (v1, v2) => { - return Err(vm_error!(self, RuntimeErrorKind::MismatchedTypes, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::MismatchedTypes, + "Mismatched types: {} and {}", + v1.type_str(), + v2.type_str() + )) } } } - 0x08 => { // MUL + 0x08 => { + // MUL match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { (Num(v1), Num(v2)) => self.stack.push(Num(v1 * v2)), (Str(v1), Num(v2)) => { if v2.fract() == 0.0 { self.stack.push(Str(v1.repeat(v2 as usize))); } else { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Number must be an integer")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Number must be an integer" + )); } } (Str(_v1), Str(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot multiply strings")) - }, + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot multiply strings" + )) + } (Bool(_v1), Bool(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot multiply booleans")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot multiply booleans" + )) } (v1, v2) => { - return Err(vm_error!(self, RuntimeErrorKind::MismatchedTypes, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::MismatchedTypes, + "Mismatched types: {} and {}", + v1.type_str(), + v2.type_str() + )) } } } - 0x09 => { // DIV + 0x09 => { + // DIV match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { (Num(v1), Num(v2)) => self.stack.push(Num(v1 / v2)), (Str(_v1), Str(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot divide strings")) - }, + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot divide strings" + )) + } (Bool(_v1), Bool(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot divide booleans")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot divide booleans" + )) } (v1, v2) => { - return Err(vm_error!(self, RuntimeErrorKind::MismatchedTypes, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::MismatchedTypes, + "Mismatched types: {} and {}", + v1.type_str(), + v2.type_str() + )) } } } - 0x0A => { // MOD + 0x0A => { + // MOD match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { (Num(v1), Num(v2)) => self.stack.push(Num(v1 % v2)), (Str(_v1), Str(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform modulus on strings")) - }, + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform modulus on strings" + )) + } (Bool(_v1), Bool(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform modulus on booleans")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform modulus on booleans" + )) } (v1, v2) => { - return Err(vm_error!(self, RuntimeErrorKind::MismatchedTypes, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::MismatchedTypes, + "Mismatched types: {} and {}", + v1.type_str(), + v2.type_str() + )) } } } - 0x0B => { // BITAND + 0x0B => { + // BITAND match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { (Num(v1), Num(v2)) => { if v1.fract() != 0.0 { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise AND on {}", v1)) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise AND on {}", + v1 + )); } if v2.fract() != 0.0 { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise AND on {}", v2)) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise AND on {}", + v2 + )); } self.stack.push(Num((v1 as u32 & v2 as u32) as f32)) } (Str(_v1), Str(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise AND on strings")) - }, + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise AND on strings" + )) + } (Bool(_v1), Bool(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise AND on booleans")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise AND on booleans" + )) } (v1, v2) => { - return Err(vm_error!(self, RuntimeErrorKind::MismatchedTypes, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::MismatchedTypes, + "Mismatched types: {} and {}", + v1.type_str(), + v2.type_str() + )) } } } - 0x0C => { // BITXOR + 0x0C => { + // BITXOR match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { (Num(v1), Num(v2)) => { if v1.fract() != 0.0 { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise XOR on {}", v1)) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise XOR on {}", + v1 + )); } if v2.fract() != 0.0 { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise XOR on {}", v2)) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise XOR on {}", + v2 + )); } self.stack.push(Num((v1 as u32 ^ v2 as u32) as f32)) } (Str(_v1), Str(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise XOR on strings")) - }, + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise XOR on strings" + )) + } (Bool(_v1), Bool(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise XOR on booleans")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise XOR on booleans" + )) } (v1, v2) => { - return Err(vm_error!(self, RuntimeErrorKind::MismatchedTypes, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::MismatchedTypes, + "Mismatched types: {} and {}", + v1.type_str(), + v2.type_str() + )) } } } - 0x0D => { // BITOR + 0x0D => { + // BITOR match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { (Num(v1), Num(v2)) => { if v1.fract() != 0.0 { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise OR on {}", v1)) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise OR on {}", + v1 + )); } if v2.fract() != 0.0 { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise OR on {}", v2)) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise OR on {}", + v2 + )); } self.stack.push(Num((v1 as u32 | v2 as u32) as f32)) } (Str(_v1), Str(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise OR on strings")) - }, + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise OR on strings" + )) + } (Bool(_v1), Bool(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Cannot perform bitwise OR on booleans")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Cannot perform bitwise OR on booleans" + )) } (v1, v2) => { - return Err(vm_error!(self, RuntimeErrorKind::MismatchedTypes, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::MismatchedTypes, + "Mismatched types: {} and {}", + v1.type_str(), + v2.type_str() + )) } } } @@ -269,73 +448,177 @@ impl VM { // OR 0x14 => match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { (Num(_v1), Num(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"||\" on non-boolean numbers")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"||\" on non-boolean numbers" + )) } (Str(_v1), Str(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"||\" on non-boolean strings")) - }, + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"||\" on non-boolean strings" + )) + } (Bool(v1), Bool(v2)) => self.stack.push(Bool(v1 || v2)), - (Null, _) => return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"||\" on non-boolean value null")), - (_, Null) => return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"||\" on non-boolean value null")), + (Null, _) => { + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"||\" on non-boolean value null" + )) + } + (_, Null) => { + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"||\" on non-boolean value null" + )) + } (v1, v2) => { - return Err(vm_error!(self, RuntimeErrorKind::MismatchedTypes, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::MismatchedTypes, + "Mismatched types: {} and {}", + v1.type_str(), + v2.type_str() + )) } - } + }, // AND 0x15 => match (self.stack.pop().unwrap(), self.stack.pop().unwrap()) { (Num(_v1), Num(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"&&\" on non-boolean numbers")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"&&\" on non-boolean numbers" + )) } (Str(_v1), Str(_v2)) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"&&\" on non-boolean strings")) - }, + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"&&\" on non-boolean strings" + )) + } (Bool(v1), Bool(v2)) => self.stack.push(Bool(v1 && v2)), - (Null, _) => return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"&&\" on non-boolean value null")), - (_, Null) => return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"&&\" on non-boolean value null")), + (Null, _) => { + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"&&\" on non-boolean value null" + )) + } + (_, Null) => { + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"&&\" on non-boolean value null" + )) + } (v1, v2) => { - return Err(vm_error!(self, RuntimeErrorKind::MismatchedTypes, "Mismatched types: {} and {}", v1.type_str(), v2.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::MismatchedTypes, + "Mismatched types: {} and {}", + v1.type_str(), + v2.type_str() + )) } - } + }, // NOT 0x16 => match self.stack.pop().unwrap() { - Null => { return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"!\" on non-boolean value null")) } + Null => { + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"!\" on non-boolean value null" + )) + } Num(_v1) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"!\" on non-boolean number")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"!\" on non-boolean number" + )) } Str(_v1) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"!\" on non-boolean string")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"!\" on non-boolean string" + )) } Bool(v1) => self.stack.push(Bool(!v1)), List(_v1) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"!\" on non-boolean list")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"!\" on non-boolean list" + )) } Fun(_v1) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"!\" on non-boolean function")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"!\" on non-boolean function" + )) } Ref(_v1) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"!\" on non-boolean reference")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"!\" on non-boolean reference" + )) } - } + }, // NEG 0x17 => match self.stack.pop().unwrap() { - Null => { return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"-\" on non-number value null")) } + Null => { + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"-\" on non-number value null" + )) + } Num(v1) => self.stack.push(Num(-v1)), Str(_v1) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"-\" on non-number string")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"-\" on non-number string" + )) } Bool(_v1) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"-\" on non-number boolean")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"-\" on non-number boolean" + )) } List(_v1) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"!\" on non-number list")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"!\" on non-number list" + )) } Fun(_v1) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"-\" on non-number function")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"-\" on non-number function" + )) } Ref(_v1) => { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to perform \"-\" on non-number reference")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to perform \"-\" on non-number reference" + )) } - } + }, // JMP 0x18 => { let loc = self.read_u16(); @@ -357,7 +640,11 @@ impl VM { self.read_u16(); } } else { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "if must have condition of type boolean")) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "if must have condition of type boolean" + )); } } @@ -367,20 +654,34 @@ impl VM { let function = self.stack.pop().expect("Stack was empty in call"); if let Value::Fun(function) = function { if num_args as usize != function.arity { - return Err(vm_error!(self, RuntimeErrorKind::IncorrectArity, "Function has {} arguments, {} provided", function.arity, num_args)) + return Err(vm_error!( + self, + RuntimeErrorKind::IncorrectArity, + "Function has {} arguments, {} provided", + function.arity, + num_args + )); } self.variables_offset = self.stack.len() - num_args as usize; - self.call_stack.push((self.unit_ptr, self.ip, self.variables_offset)); - self.stack.insert(self.stack.len()-num_args as usize, Value::Fun(function)); + self.call_stack + .push((self.unit_ptr, self.ip, self.variables_offset)); + self.stack + .insert(self.stack.len() - num_args as usize, Value::Fun(function)); self.ip = 0; self.unit_ptr = function.unit_ptr as usize; } else { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to call non-function type {}", function.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to call non-function type {}", + function.type_str() + )); } } // RET 0x1C => { - let (unit_ptr, ip, variables_offset) = self.call_stack.pop().expect("Call stack empty on RET"); + let (unit_ptr, ip, variables_offset) = + self.call_stack.pop().expect("Call stack empty on RET"); let ret = self.stack.pop().expect("Missing return value"); self.stack = self.stack[..variables_offset].to_vec(); self.variables_offset = self.call_stack.last().expect("call stack empty").2; @@ -393,7 +694,10 @@ impl VM { // LIST 0x1D => { let len = self.read(); - let list = self.stack.drain(self.stack.len()-len as usize..).collect(); + let list = self + .stack + .drain(self.stack.len() - len as usize..) + .collect(); self.stack.push(Value::List(list)); } // SCR @@ -402,29 +706,54 @@ impl VM { let list = self.stack.pop().expect("stack empty on subscript list"); if let Value::Num(index) = index { if index.fract() != 0.0 { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Subscript index must be an integer but found {}", index)) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Subscript index must be an integer but found {}", + index + )); } let index = index as usize; if let Value::List(list) = list { if index > list.len() { - return Err(vm_error!(self, RuntimeErrorKind::ArrayOutOfBounds, "List length is {} but found index {}", list.len(), index)) + return Err(vm_error!( + self, + RuntimeErrorKind::ArrayOutOfBounds, + "List length is {} but found index {}", + list.len(), + index + )); } self.stack.push(list[index].clone()); } else { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to subscript non-list type {}", list.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to subscript non-list type {}", + list.type_str() + )); } } else { - return Err(vm_error!(self, RuntimeErrorKind::WrongType, "Tried to use non-integer type {} to subscript list", index.type_str())) + return Err(vm_error!( + self, + RuntimeErrorKind::WrongType, + "Tried to use non-integer type {} to subscript list", + index.type_str() + )); } } - 0xFD => { // POP + 0xFD => { + // POP let times = self.read(); for _ in 0..times { - self.stack.pop().expect(&format!("{}: Unable to pop stack", self.ip)); + self.stack + .pop() + .expect(&format!("{}: Unable to pop stack", self.ip)); } } - 0xFE => { // PRINT + 0xFE => { + // PRINT let value = self.stack.pop().unwrap(); /*match value { Null => *output += "null", @@ -460,7 +789,8 @@ impl VM { self.ip += 1; byte_one | byte_two } - pub fn find_line(&self) -> usize { // returns line # at ip + pub fn find_line(&self) -> usize { + // returns line # at ip let mut line_ip = 0; for (line, rep) in self.units[self.unit_ptr].lines.clone() { if line_ip + rep > self.ip { @@ -474,7 +804,12 @@ impl VM { #[derive(Debug, Clone)] pub enum Value { - Null, Num(f32), Str(String), Bool(bool), List(Vec), Fun(Function), + Null, + Num(f32), + Str(String), + Bool(bool), + List(Vec), + Fun(Function), Ref(usize), } @@ -510,7 +845,7 @@ impl ToString for Value { output } Fun(v) => format!("", v.unit_ptr), - Ref(v) => format!("", v) + Ref(v) => format!("", v), } } } diff --git a/crates/server/src/crafting/components.rs b/crates/server/src/crafting/components.rs index 5b3405772daa1c3bae1abd83bfda0a5e679de6f0..ae61e07f1248ce6f725085b234eaa142efb32311 100644 --- a/crates/server/src/crafting/components.rs +++ b/crates/server/src/crafting/components.rs @@ -5,16 +5,16 @@ use starkingdoms_common::PlanetType; #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum MaterialType { - Plasma, // Sun + Plasma, // Sun Composite, // Mercury - Sulfur, // Venus - Silicon, // Moon - Iron, // Mars - Hydrogen, // Jupiter - Helium, // Saturn - Rubber, // Uranus - Methane, // Neptune - Ice, // Pluto + Sulfur, // Venus + Silicon, // Moon + Iron, // Mars + Hydrogen, // Jupiter + Helium, // Saturn + Rubber, // Uranus + Methane, // Neptune + Ice, // Pluto } impl TryFrom for MaterialType { type Error = (); @@ -50,4 +50,3 @@ pub struct VarietyMaterialStorage { #[derive(Component, Debug, Clone, Default)] pub struct IsMining(pub bool); - diff --git a/crates/server/src/crafting/mining.rs b/crates/server/src/crafting/mining.rs index d13d5410c8d7390f0bd68a8d16e6ba886ffe750a..3ef37b65717bf581a7e764a4c5629424f9ba9149 100644 --- a/crates/server/src/crafting/mining.rs +++ b/crates/server/src/crafting/mining.rs @@ -1,16 +1,25 @@ +use crate::{module::component::Attach, planet::PlanetType}; use bevy::prelude::{Children, Entity, Query, Res}; use bevy_rapier2d::plugin::RapierContext; -use crate::{module::component::Attach, planet::PlanetType}; use super::components::{IsMining, VarietyMaterialStorage}; pub fn mine_materials( rapier_context: Res, planet_query: Query<(&PlanetType, &Children)>, - mut mineable_query: Query<(Entity, &mut Attach, Option<&IsMining>, Option<&mut VarietyMaterialStorage>)>, + mut mineable_query: Query<( + Entity, + &mut Attach, + Option<&IsMining>, + Option<&mut VarietyMaterialStorage>, + )>, ) { for (planet_type, children) in &planet_query { - for (entity1, entity2, intersecting) in rapier_context.intersection_pairs_with(*children.first().unwrap()) { - if !intersecting { continue } + for (entity1, entity2, intersecting) in + rapier_context.intersection_pairs_with(*children.first().unwrap()) + { + if !intersecting { + continue; + } let other = if *children.first().unwrap() == entity1 { entity2 } else { @@ -22,7 +31,7 @@ pub fn mine_materials( }; let associated_player = match attach.associated_player { Some(e) => e, - None => entity + None => entity, }; // is the module mining if let Some(mineable) = mineable { @@ -33,7 +42,9 @@ pub fn mine_materials( if let Ok(material) = planet_type.0.try_into() { match storage.materials.get_mut(&material) { Some(v) => *v += 1, - None => { storage.materials.insert(material, 1); } + None => { + storage.materials.insert(material, 1); + } } } } @@ -45,7 +56,12 @@ pub fn mine_materials( } pub fn find_storage( player: Entity, - mineable_query: &Query<(Entity, &mut Attach, Option<&IsMining>, Option<&mut VarietyMaterialStorage>)>, + mineable_query: &Query<( + Entity, + &mut Attach, + Option<&IsMining>, + Option<&mut VarietyMaterialStorage>, + )>, ) -> Option { for (entity, attach, _, storage) in mineable_query.iter() { if let Some(storage) = storage { @@ -65,7 +81,6 @@ pub fn find_storage( return Some(entity); } } - } return None; } diff --git a/crates/server/src/module/mod.rs b/crates/server/src/module/mod.rs index e94bdf4c5307d4fcf7279abf066a13f00a8006f7..ded366c12d85e76453e65a0963f394076044fffc 100644 --- a/crates/server/src/module/mod.rs +++ b/crates/server/src/module/mod.rs @@ -11,8 +11,7 @@ use starkingdoms_common::proto_transform; use crate::ws::PacketMessageConvert; use crate::{ - capacity, config::StkConfig, part, planet::PlanetType, player::component::Player, - ws::WsEvent, + capacity, config::StkConfig, part, planet::PlanetType, player::component::Player, ws::WsEvent, }; use starkingdoms_common::PartType as c_PartType; use starkingdoms_common::PlanetType as c_PlanetType; @@ -123,7 +122,7 @@ pub fn detach_recursive( energy += capacity!(*part_type); commands.entity(entity).remove::(); flags.attached = false; - if *part_type == c_PartType::LandingThrusterSuspension .into(){ + if *part_type == c_PartType::LandingThrusterSuspension.into() { let parent = attach.parent.unwrap(); let parent_attach = attached_query.get(parent).unwrap().3; commands.entity(parent).insert(LooseAttach { @@ -565,7 +564,8 @@ fn convert_modules_recursive( }); attach.children[2] = Some(suspension.id()); - increase_capacity_by += part!(c_PartType::LandingThruster.into()).energy_capacity; + increase_capacity_by += + part!(c_PartType::LandingThruster.into()).energy_capacity; let packet = Packet::DespawnPart { id: child.index() }; @@ -652,7 +652,7 @@ pub fn break_modules( } let handle = match joints.get(&entity) { Some(handle) => handle, - None => continue + None => continue, }; let joint = rapier_context.impulse_joints.get(*handle).unwrap(); if joint.impulses.magnitude() > 2.0 { diff --git a/crates/server/src/module/save.rs b/crates/server/src/module/save.rs index 06a3e0d7124fffa9369d3fe27fd995bbcba90b58..377ae235944562e3591490fae9f976d4b3ea0f81 100644 --- a/crates/server/src/module/save.rs +++ b/crates/server/src/module/save.rs @@ -5,8 +5,11 @@ use bevy_rapier2d::prelude::*; use starkingdoms_common::{packet::Packet, PartType as c_PartType, SaveModule}; use crate::{ - capacity, mass, planet::PlanetType, player::component::Player, ws::{PacketMessageConvert, WsEvent}, Attach, CanAttach, - LooseAttach, PartBundle, PartFlags, PartType, + capacity, mass, + planet::PlanetType, + player::component::Player, + ws::{PacketMessageConvert, WsEvent}, + Attach, CanAttach, LooseAttach, PartBundle, PartFlags, PartType, }; pub fn load_savefile( diff --git a/crates/server/src/planet.rs b/crates/server/src/planet.rs index f4cf36d34e6969c8d35d97812b9144fff2cce54f..cb69771d18c0465f8c69ad84d6f9f955a31e17e8 100644 --- a/crates/server/src/planet.rs +++ b/crates/server/src/planet.rs @@ -29,7 +29,9 @@ pub fn spawn_planets(mut commands: Commands) { .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Sun)).size + 0.3)) + .spawn(Collider::ball( + planet!(PlanetType(c_PlanetType::Sun)).size + 0.3, + )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -40,14 +42,18 @@ pub fn spawn_planets(mut commands: Commands) { planet_type: PlanetType(c_PlanetType::Mercury), transform: TransformBundle::from(mercury_pos), }) - .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Mercury)).size)) + .insert(Collider::ball( + planet!(PlanetType(c_PlanetType::Mercury)).size, + )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Mercury)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Mercury)).size + 0.3)) + .spawn(Collider::ball( + planet!(PlanetType(c_PlanetType::Mercury)).size + 0.3, + )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -58,14 +64,18 @@ pub fn spawn_planets(mut commands: Commands) { planet_type: PlanetType(c_PlanetType::Venus), transform: TransformBundle::from(venus_pos), }) - .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Venus)).size)) + .insert(Collider::ball( + planet!(PlanetType(c_PlanetType::Venus)).size, + )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Venus)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Venus)).size + 0.3)) + .spawn(Collider::ball( + planet!(PlanetType(c_PlanetType::Venus)).size + 0.3, + )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -76,14 +86,18 @@ pub fn spawn_planets(mut commands: Commands) { planet_type: PlanetType(c_PlanetType::Earth), transform: TransformBundle::from(earth_pos), }) - .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Earth)).size)) + .insert(Collider::ball( + planet!(PlanetType(c_PlanetType::Earth)).size, + )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Earth)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Earth)).size + 0.3)) + .spawn(Collider::ball( + planet!(PlanetType(c_PlanetType::Earth)).size + 0.3, + )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -101,7 +115,9 @@ pub fn spawn_planets(mut commands: Commands) { .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Moon)).size + 0.1)) + .spawn(Collider::ball( + planet!(PlanetType(c_PlanetType::Moon)).size + 0.1, + )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -119,7 +135,9 @@ pub fn spawn_planets(mut commands: Commands) { .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Mars)).size + 0.1)) + .spawn(Collider::ball( + planet!(PlanetType(c_PlanetType::Mars)).size + 0.1, + )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -130,14 +148,18 @@ pub fn spawn_planets(mut commands: Commands) { planet_type: PlanetType(c_PlanetType::Jupiter), transform: TransformBundle::from(jupiter_pos), }) - .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Jupiter)).size)) + .insert(Collider::ball( + planet!(PlanetType(c_PlanetType::Jupiter)).size, + )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Jupiter)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Jupiter)).size + 0.1)) + .spawn(Collider::ball( + planet!(PlanetType(c_PlanetType::Jupiter)).size + 0.1, + )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -148,14 +170,18 @@ pub fn spawn_planets(mut commands: Commands) { planet_type: PlanetType(c_PlanetType::Saturn), transform: TransformBundle::from(saturn_pos), }) - .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Saturn)).size)) + .insert(Collider::ball( + planet!(PlanetType(c_PlanetType::Saturn)).size, + )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Saturn)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Saturn)).size + 0.1)) + .spawn(Collider::ball( + planet!(PlanetType(c_PlanetType::Saturn)).size + 0.1, + )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -166,14 +192,18 @@ pub fn spawn_planets(mut commands: Commands) { planet_type: PlanetType(c_PlanetType::Uranus), transform: TransformBundle::from(uranus_pos), }) - .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Uranus)).size)) + .insert(Collider::ball( + planet!(PlanetType(c_PlanetType::Uranus)).size, + )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Uranus)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Uranus)).size + 0.1)) + .spawn(Collider::ball( + planet!(PlanetType(c_PlanetType::Uranus)).size + 0.1, + )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -184,14 +214,18 @@ pub fn spawn_planets(mut commands: Commands) { planet_type: PlanetType(c_PlanetType::Neptune), transform: TransformBundle::from(neptune_pos), }) - .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Neptune)).size)) + .insert(Collider::ball( + planet!(PlanetType(c_PlanetType::Neptune)).size, + )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Neptune)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Neptune)).size + 0.1)) + .spawn(Collider::ball( + planet!(PlanetType(c_PlanetType::Neptune)).size + 0.1, + )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -202,14 +236,18 @@ pub fn spawn_planets(mut commands: Commands) { planet_type: PlanetType(c_PlanetType::Pluto), transform: TransformBundle::from(pluto_pos), }) - .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Pluto)).size)) + .insert(Collider::ball( + planet!(PlanetType(c_PlanetType::Pluto)).size, + )) .insert(AdditionalMassProperties::Mass( planet!(PlanetType(c_PlanetType::Pluto)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Pluto)).size + 0.1)) + .spawn(Collider::ball( + planet!(PlanetType(c_PlanetType::Pluto)).size + 0.1, + )) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) diff --git a/crates/server/src/player/client_login.rs b/crates/server/src/player/client_login.rs index 6fb337b91820f415bdbbeff2dac78ae48a5877a1..f35eac194468453526b065f3152864b877899929 100644 --- a/crates/server/src/player/client_login.rs +++ b/crates/server/src/player/client_login.rs @@ -6,13 +6,21 @@ use hmac::{Hmac, Mac}; use jwt::VerifyWithKey; use rand::Rng; use sha2::Sha256; -use starkingdoms_common::{packet::{MessageType, Packet, Part, Planet, ProtoPartFlags}, proto_part_flags, proto_transform, unpack_savefile, PartType as c_PartType}; +use starkingdoms_common::{ + packet::{MessageType, Packet, Part, Planet, ProtoPartFlags}, + proto_part_flags, proto_transform, unpack_savefile, PartType as c_PartType, +}; use crate::{ - config::StkConfig, crafting::components::{IsMining, VarietyMaterialStorage}, module::{ + config::StkConfig, + crafting::components::{IsMining, VarietyMaterialStorage}, + module::{ component::{Attach, CanAttach, LooseAttach, PartBundle, PartFlags, PartType}, save::load_savefile, - }, planet::PlanetType, ws::{PacketMessageConvert, WsEvent}, AppKeys, UserToken, CLIENT_SCALE + }, + planet::PlanetType, + ws::{PacketMessageConvert, WsEvent}, + AppKeys, UserToken, CLIENT_SCALE, }; use super::component::{Input, Player}; @@ -232,9 +240,7 @@ pub fn packet_stream( transform: Transform, ) { // response in the handshake - let packet = Packet::LoginResponse { - id: index, - }; + let packet = Packet::LoginResponse { id: index }; event_queue.push(WsEvent::Send { to: *from, message: packet.into_message(), @@ -324,7 +330,10 @@ pub fn packet_stream( }, )); for part in parts { - let packet = Packet::SpawnPart { id: part.0, part: part.1 }; + let packet = Packet::SpawnPart { + id: part.0, + part: part.1, + }; event_queue.push(WsEvent::Send { to: *from, message: packet.into_message(), diff --git a/crates/server/src/player/mod.rs b/crates/server/src/player/mod.rs index 1778fedde3736d7f7fa0c07bfa59a65d25c3f0cc..4bc6149b054e48ab71762e9578efd3bd63863447 100644 --- a/crates/server/src/player/mod.rs +++ b/crates/server/src/player/mod.rs @@ -8,10 +8,18 @@ use send_message::send_message; use starkingdoms_common::{packet::Packet, PartType as c_PartType}; use crate::{ - config::StkConfig, crafting::components::IsMining, err_or_cont, mathutil::rot2d, module::{ + config::StkConfig, + crafting::components::IsMining, + err_or_cont, + mathutil::rot2d, + module::{ component::{Attach, CanAttach, LooseAttach, PartFlags, PartType}, PART_HALF_SIZE, - }, part, planet::PlanetType, ws::{PacketMessageConvert, WsEvent}, AppKeys, CLIENT_SCALE + }, + part, + planet::PlanetType, + ws::{PacketMessageConvert, WsEvent}, + AppKeys, CLIENT_SCALE, }; pub mod client_login; @@ -294,12 +302,15 @@ pub fn player_input_update( // process each thruster on hearty for (force_multiplier, x_offset, y_offset) in thrusters { - if force_multiplier != 0.0 && player.energy >= part!(c_PartType::Hearty.into()).thruster_energy { + if force_multiplier != 0.0 + && player.energy >= part!(c_PartType::Hearty.into()).thruster_energy + { player.energy -= part!(c_PartType::Hearty.into()).thruster_energy; let thruster_pos_uncast = vec2(x_offset, y_offset); let thruster_pos_cast = rot2d(thruster_pos_uncast, rot) + transform.translation.xy(); - let thruster_force = force_multiplier * part!(c_PartType::Hearty.into()).thruster_force; + let thruster_force = + force_multiplier * part!(c_PartType::Hearty.into()).thruster_force; let thruster_vec = vec2(-thruster_force * rot.sin(), thruster_force * rot.cos()); let thruster_force = ExternalForce::at_point( thruster_vec, diff --git a/crates/server/src/player/packet.rs b/crates/server/src/player/packet.rs index fb2af5446539d7fa39edb109377671252a8e7da8..e69a16303cfa675eee033b6144f31da88233ed98 100644 --- a/crates/server/src/player/packet.rs +++ b/crates/server/src/player/packet.rs @@ -1,5 +1,8 @@ use bevy::{ecs::event::ManualEventReader, prelude::*}; -use starkingdoms_common::{packet::{Packet, Part, Planet}, proto_part_flags, proto_transform}; +use starkingdoms_common::{ + packet::{Packet, Part, Planet}, + proto_part_flags, proto_transform, +}; use crate::{ module::component::{Attach, PartFlags, PartType}, diff --git a/crates/server/src/player/player_mouse_input.rs b/crates/server/src/player/player_mouse_input.rs index 418a6d6f303f65743937c6e9a26a30faff7c98b8..f3f10539178cc258aa5b54c3b7cb56c0ce9dc7fe 100644 --- a/crates/server/src/player/player_mouse_input.rs +++ b/crates/server/src/player/player_mouse_input.rs @@ -2,9 +2,15 @@ use bevy::{math::vec3, prelude::*}; use bevy_rapier2d::prelude::*; use crate::{ - crafting::components::IsMining, module::component::{Attach, CanAttach, LooseAttach, PartFlags, PartType}, planet::PlanetType, ws::{PacketMessageConvert, WsEvent} + crafting::components::IsMining, + module::component::{Attach, CanAttach, LooseAttach, PartFlags, PartType}, + planet::PlanetType, + ws::{PacketMessageConvert, WsEvent}, +}; +use starkingdoms_common::{ + packet::{ButtonType, Packet}, + PartType as c_PartType, }; -use starkingdoms_common::{packet::{ButtonType, Packet}, PartType as c_PartType}; use super::component::Player; @@ -187,9 +193,7 @@ pub fn mouse_picking( if *button == ButtonType::Right { send_events.push(WsEvent::Send { to: q_player.addr, - message: Packet::OpenCraftingUi { - id: entity.index(), - }.into_message(), + message: Packet::OpenCraftingUi { id: entity.index() }.into_message(), }); // toggle mining /*if let Ok(mut is_mining) = mining_query.get_mut(entity) { diff --git a/crates/xtask/src/main.rs b/crates/xtask/src/main.rs index 79e8d86cff815d078bfe5d72069cbd0bc4044055..1b00df4e7ffd7ca2d35e853a042b100a7e95548f 100644 --- a/crates/xtask/src/main.rs +++ b/crates/xtask/src/main.rs @@ -1,3 +1,5 @@ +use colored::Colorize; +use notify::{Event, EventKind, RecursiveMode, Watcher}; use std::env::{args, var}; use std::fs; use std::io::Cursor; @@ -7,8 +9,6 @@ use std::sync::mpsc; use std::sync::mpsc::TryRecvError; use std::thread::sleep; use std::time::Duration; -use colored::Colorize; -use notify::{Event, EventKind, RecursiveMode, Watcher}; use tiny_http::{Response, Server, StatusCode}; use wasm_pack::command::build::{BuildOptions, Target}; use wasm_pack::command::run_wasm_pack; @@ -56,11 +56,18 @@ fn build_client() -> anyhow::Result<()> { fn try_build_client() -> bool { match build_client() { Ok(_) => { - println!("{} -- Client package built successfully", "✓ Success".green().bold()); + println!( + "{} -- Client package built successfully", + "✓ Success".green().bold() + ); true - }, + } Err(e) => { - eprintln!("{} -- Client package failed to build: {}", "✗ Failed".red().bold(), e); + eprintln!( + "{} -- Client package failed to build: {}", + "✗ Failed".red().bold(), + e + ); false } } @@ -75,15 +82,21 @@ fn start_server() { if path == Path::new("/") { path = Path::new("/index.html"); } - + let path = path.strip_prefix(Path::new("/")).unwrap(); - + let full_path = workspace_dir().join("crates/client").join(path); - + let content = match fs::read(full_path.clone()) { Ok(r) => r, Err(_) => { - let _ = req.respond(Response::new(StatusCode::from(404), vec![], Cursor::new(vec![]), None, None)); + let _ = req.respond(Response::new( + StatusCode::from(404), + vec![], + Cursor::new(vec![]), + None, + None, + )); continue; } }; @@ -100,17 +113,16 @@ fn start_server() { &b"application/wasm"[..] } else { &b"application/octet-stream"[..] - } - ).unwrap(); - + }, + ) + .unwrap(); + let response = Response::new( StatusCode::from(200), - vec![ - header - ], + vec![header], Cursor::new(content), Some(len), - None + None, ); let _ = req.respond(response); } @@ -125,7 +137,7 @@ fn main() { if !try_build_client() { exit(1); } - }, + } "watch" | "serve" => { let serve = subcommand == "serve"; @@ -144,7 +156,9 @@ fn main() { // Add a path to be watched. All files and directories at that path and // below will be monitored for changes. - watcher.watch(&workspace_dir().join("crates"), RecursiveMode::Recursive).unwrap(); + watcher + .watch(&workspace_dir().join("crates"), RecursiveMode::Recursive) + .unwrap(); println!("{}", "[Watch] 🛈 Watching for file changes".blue().bold()); // Block forever, printing out events as they come in @@ -170,8 +184,8 @@ fn main() { } else { rx.recv().unwrap() } - }, - Err(TryRecvError::Disconnected) => panic!("{:?}", TryRecvError::Disconnected) + } + Err(TryRecvError::Disconnected) => panic!("{:?}", TryRecvError::Disconnected), }; match res { @@ -179,19 +193,24 @@ fn main() { if let EventKind::Modify(_) = event.kind { let has_non_generated_update = false; for path in &event.paths { - if !path.to_str().unwrap().contains("client/pkg") && !path.to_str().unwrap().ends_with("~") { + if !path.to_str().unwrap().contains("client/pkg") + && !path.to_str().unwrap().ends_with("~") + { needs_rebuild = true; } } } - - }, + } Err(e) => { - eprintln!("{} -- Error watching for files: {}", "[Watch] ✗ Error".red().bold(), e); - }, + eprintln!( + "{} -- Error watching for files: {}", + "[Watch] ✗ Error".red().bold(), + e + ); + } } } - }, - _ => panic!("unsupported command") + } + _ => panic!("unsupported command"), } }