From 820ead0c020857fa5b9ef93e5f6fdcf21647947e Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 7 Feb 2025 10:39:33 -0500 Subject: [PATCH] Store types in locals; Fix local disassembly --- dust-lang/src/chunk/disassembler.rs | 18 +++++--- dust-lang/src/chunk/local.rs | 14 +++++- dust-lang/src/compiler/mod.rs | 67 ++++++++++++++--------------- 3 files changed, 55 insertions(+), 44 deletions(-) diff --git a/dust-lang/src/chunk/disassembler.rs b/dust-lang/src/chunk/disassembler.rs index ac209cd..118ef46 100644 --- a/dust-lang/src/chunk/disassembler.rs +++ b/dust-lang/src/chunk/disassembler.rs @@ -43,7 +43,7 @@ use std::io::{self, Write}; use colored::{ColoredString, Colorize}; -use crate::{Chunk, Local}; +use crate::{Chunk, Local, Type}; const INSTRUCTION_COLUMNS: [(&str, usize); 4] = [("i", 5), ("POSITION", 12), ("OPERATION", 17), ("INFO", 41)]; @@ -53,17 +53,18 @@ const INSTRUCTION_BORDERS: [&str; 3] = [ "╰─────┴────────────┴─────────────────┴─────────────────────────────────────────╯", ]; -const LOCAL_COLUMNS: [(&str, usize); 5] = [ +const LOCAL_COLUMNS: [(&str, usize); 6] = [ ("i", 5), ("IDENTIFIER", 16), + ("TYPE", 26), ("REGISTER", 10), ("SCOPE", 7), ("MUTABLE", 7), ]; const LOCAL_BORDERS: [&str; 3] = [ - "╭─────┬────────────────┬──────────┬───────┬───────╮", - "├─────┼────────────────┼──────────┼───────┼───────┤", - "╰─────┴────────────────┴──────────┴───────┴───────╯", + "╭─────┬────────────────┬──────────────────────────┬──────────┬───────┬───────╮", + "├─────┼────────────────┼──────────────────────────┼──────────┼───────┼───────┤", + "╰─────┴────────────────┴──────────────────────────┴──────────┴───────┴───────╯", ]; const CONSTANT_COLUMNS: [(&str, usize); 3] = [("i", 5), ("TYPE", 26), ("VALUE", 26)]; @@ -314,6 +315,7 @@ impl<'a, W: Write> Disassembler<'a, W> { Local { identifier_index, register_index, + r#type, scope, is_mutable, }, @@ -325,10 +327,12 @@ impl<'a, W: Write> Disassembler<'a, W> { .get(*identifier_index as usize) .map(|value| value.to_string()) .unwrap_or_else(|| "unknown".to_string()); - let register_display = format!("R{register_index}"); + let type_display = r#type.to_string(); + let type_caps = type_display.to_uppercase(); + let register_display = format!("R_{type_caps}_{register_index}"); let scope = scope.to_string(); let row = format!( - "│{index:^5}│{identifier_display:^16}│{register_display:^10}│{scope:^7}│{is_mutable:^7}│" + "│{index:^5}│{identifier_display:^16}│{type_display:^26}│{register_display:^10}│{scope:^7}│{is_mutable:^7}│" ); self.write_center_border(&row)?; diff --git a/dust-lang/src/chunk/local.rs b/dust-lang/src/chunk/local.rs index 30cf47b..2bd15f8 100644 --- a/dust-lang/src/chunk/local.rs +++ b/dust-lang/src/chunk/local.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; -use crate::Scope; +use crate::{Scope, Type}; /// Scoped variable. #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)] @@ -13,6 +13,9 @@ pub struct Local { /// Index of the register where the variable's value is stored. pub register_index: u16, + /// Type of the variable's value. + pub r#type: Type, + /// Whether the local is mutable. pub is_mutable: bool, @@ -22,10 +25,17 @@ pub struct Local { impl Local { /// Creates a new Local instance. - pub fn new(identifier_index: u16, register_index: u16, is_mutable: bool, scope: Scope) -> Self { + pub fn new( + identifier_index: u16, + register_index: u16, + r#type: Type, + is_mutable: bool, + scope: Scope, + ) -> Self { Self { identifier_index, register_index, + r#type, is_mutable, scope, } diff --git a/dust-lang/src/compiler/mod.rs b/dust-lang/src/compiler/mod.rs index 61989a8..53f3491 100644 --- a/dust-lang/src/compiler/mod.rs +++ b/dust-lang/src/compiler/mod.rs @@ -89,7 +89,7 @@ pub struct Compiler<'src> { /// Block-local variables and their types. The locals are assigned to the chunk when /// [`Compiler::finish`] is called. The types are discarded after compilation. - locals: Vec<(Local, Type)>, + locals: Vec, /// Prototypes that have been compiled. These are assigned to the chunk when /// [`Compiler::finish`] is called. @@ -239,11 +239,6 @@ impl<'src> Compiler<'src> { .into_iter() .map(|(instruction, _, position)| (instruction, position)) .unzip(); - let locals = self - .locals - .into_iter() - .map(|(local, _)| local) - .collect::>(); Chunk { name: self.function_name, @@ -251,7 +246,7 @@ impl<'src> Compiler<'src> { instructions, positions, constants: self.constants, - locals, + locals: self.locals, prototypes: self.prototypes, boolean_register_count, byte_register_count, @@ -402,7 +397,7 @@ impl<'src> Compiler<'src> { Ok(()) } - fn get_local(&self, index: u16) -> Result<&(Local, Type), CompileError> { + fn get_local(&self, index: u16) -> Result<&Local, CompileError> { self.locals .get(index as usize) .ok_or(CompileError::UndeclaredVariable { @@ -416,7 +411,7 @@ impl<'src> Compiler<'src> { .iter() .enumerate() .rev() - .find_map(|(index, (local, _))| { + .find_map(|(index, local)| { let constant = self.constants.get(local.identifier_index as usize)?; let identifier = if let ConcreteValue::String(identifier) = constant { identifier @@ -450,22 +445,23 @@ impl<'src> Compiler<'src> { let identifier_index = self.push_or_get_constant(identifier); let local_index = self.locals.len() as u16; - self.locals.push(( - Local::new(identifier_index, register_index, is_mutable, scope), + self.locals.push(Local::new( + identifier_index, + register_index, r#type, + is_mutable, + scope, )); (local_index, identifier_index) } fn get_identifier(&self, local_index: u16) -> Option { - self.locals - .get(local_index as usize) - .and_then(|(local, _)| { - self.constants - .get(local.identifier_index as usize) - .map(|value| value.to_string()) - }) + self.locals.get(local_index as usize).and_then(|local| { + self.constants + .get(local.identifier_index as usize) + .map(|value| value.to_string()) + }) } fn push_or_get_constant(&mut self, value: ConcreteValue) -> u16 { @@ -535,12 +531,14 @@ impl<'src> Compiler<'src> { } fn get_register_type(&self, register_index: u16) -> Result { - if let Some((_, r#type)) = self - .locals - .iter() - .find(|(local, _)| local.register_index == register_index) - { - return Ok(r#type.clone()); + if let Some(r#type) = self.locals.iter().find_map(|local| { + if local.register_index == register_index { + Some(local.r#type.clone()) + } else { + None + } + }) { + return Ok(r#type); } for (instruction, r#type, _) in &self.instructions { @@ -852,7 +850,7 @@ impl<'src> Compiler<'src> { self.locals .get(to.index() as usize) - .map(|(local, _)| local.is_mutable) + .map(|local| local.is_mutable) .unwrap_or(false) } else { false @@ -1052,7 +1050,7 @@ impl<'src> Compiler<'src> { })?; let operand_register = if last_instruction.operation() == Operation::POINT { let Point { to, .. } = Point::from(last_instruction); - let (local, _) = self.get_local(to.index())?; + let local = self.get_local(to.index())?; local.register_index } else if last_instruction.yields_value() { @@ -1156,9 +1154,8 @@ impl<'src> Compiler<'src> { }); }; - let (local, r#type) = self - .get_local(local_index) - .map(|(local, r#type)| (local, r#type.clone()))?; + let local = self.get_local(local_index)?; + let local_type = local.r#type.clone(); let is_mutable = local.is_mutable; let local_register_index = local.register_index; @@ -1190,7 +1187,7 @@ impl<'src> Compiler<'src> { math_instruction.set_a_field(local_register_index); } else { - let register = match r#type { + let register = match local_type { Type::Boolean => self.next_boolean_register(), Type::Byte => self.next_byte_register(), Type::Character => self.next_character_register(), @@ -1201,16 +1198,16 @@ impl<'src> Compiler<'src> { }; let point = Instruction::point( local_register_index, - Operand::Register(register, r#type.type_code()), + Operand::Register(register, local_type.type_code()), ); - self.emit_instruction(point, r#type, start_position); + self.emit_instruction(point, local_type, start_position); } return Ok(()); } - let destination = match r#type { + let destination = match local_type { Type::Boolean => self.next_boolean_register(), Type::Byte => self.next_byte_register(), Type::Character => self.next_character_register(), @@ -1221,10 +1218,10 @@ impl<'src> Compiler<'src> { }; let point = Instruction::point( destination, - Operand::Register(local_register_index, r#type.type_code()), + Operand::Register(local_register_index, local_type.type_code()), ); - self.emit_instruction(point, r#type, self.previous_position); + self.emit_instruction(point, local_type, self.previous_position); Ok(()) }