From 358436c47086fc7bc69a77f3e480c2e089aee81d Mon Sep 17 00:00:00 2001 From: Jeff Date: Wed, 4 Dec 2024 06:38:24 -0500 Subject: [PATCH] Fix function parsing bug; Optimize strings --- Cargo.lock | 25 +++++++++++++++++ dust-lang/Cargo.toml | 1 + dust-lang/src/chunk.rs | 1 + dust-lang/src/compiler.rs | 24 ++++++++-------- dust-lang/src/disassembler.rs | 24 ++++++++++++++-- dust-lang/src/lib.rs | 4 ++- dust-lang/src/native_function/logic.rs | 4 +-- dust-lang/src/value/concrete_value.rs | 38 +++++--------------------- dust-lang/src/value/mod.rs | 2 +- dust-lang/tests/functions.rs | 2 +- dust-lang/tests/math_add.rs | 5 +--- 11 files changed, 75 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee62af3..104f336 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,6 +197,7 @@ dependencies = [ "serde", "serde_json", "smallvec", + "smartstring", ] [[package]] @@ -496,6 +497,18 @@ dependencies = [ "serde", ] +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "serde", + "static_assertions", + "version_check", +] + [[package]] name = "spin" version = "0.9.8" @@ -511,6 +524,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "strsim" version = "0.11.1" @@ -546,6 +565,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/dust-lang/Cargo.toml b/dust-lang/Cargo.toml index e983b81..09ca4f6 100644 --- a/dust-lang/Cargo.toml +++ b/dust-lang/Cargo.toml @@ -19,6 +19,7 @@ getrandom = { version = "0.2", features = [ "js", ] } # Indirect dependency, for wasm builds smallvec = { version = "1.13.2", features = ["serde"] } +smartstring = { version = "1.0.1", features = ["serde"], default-features = false } [dev-dependencies] env_logger = "0.11.5" diff --git a/dust-lang/src/chunk.rs b/dust-lang/src/chunk.rs index add03c5..b32c1ad 100644 --- a/dust-lang/src/chunk.rs +++ b/dust-lang/src/chunk.rs @@ -8,6 +8,7 @@ use std::fmt::{self, Debug, Display, Write}; use serde::{Deserialize, Serialize}; use smallvec::SmallVec; +use smartstring::alias::String; use crate::{ConcreteValue, Disassembler, FunctionType, Instruction, Scope, Span, Type}; diff --git a/dust-lang/src/compiler.rs b/dust-lang/src/compiler.rs index 8684de9..4f95d1c 100644 --- a/dust-lang/src/compiler.rs +++ b/dust-lang/src/compiler.rs @@ -18,11 +18,9 @@ use crate::{ Call, CallNative, Close, DefineLocal, GetLocal, Jump, LoadBoolean, LoadConstant, LoadList, LoadSelf, Move, Negate, Not, Return, SetLocal, Test, }, - optimize_control_flow, optimize_set_local, - value::ConcreteValue, - AnnotatedError, Argument, Chunk, Destination, DustError, FunctionType, Instruction, LexError, - Lexer, Local, NativeFunction, Operation, Scope, Span, Token, TokenKind, TokenOwned, Type, - TypeConflict, + optimize_control_flow, optimize_set_local, AnnotatedError, Argument, Chunk, ConcreteValue, + Destination, DustError, DustString, FunctionType, Instruction, LexError, Lexer, Local, + NativeFunction, Operation, Scope, Span, Token, TokenKind, TokenOwned, Type, TypeConflict, }; /// Compiles the input and returns a chunk. @@ -55,7 +53,7 @@ pub fn compile(source: &str) -> Result { /// See the [`compile`] function an example of how to create and use a Compiler. #[derive(Debug)] pub struct Compiler<'src> { - self_name: Option, + self_name: Option, instructions: Vec<(Instruction, Type, Span)>, constants: Vec, locals: Vec, @@ -1279,7 +1277,6 @@ impl<'src> Compiler<'src> { let start = self.previous_position.0; let start_register = self.next_register(); - self.advance()?; self.expect(Token::LeftParenthesis)?; while !self.allow(Token::RightParenthesis)? { @@ -1447,7 +1444,7 @@ impl<'src> Compiler<'src> { function_compiler.advance()?; - function_compiler.self_name = Some(text.to_string()); + function_compiler.self_name = Some(text.into()); Some((text, position)) } else { @@ -1518,13 +1515,14 @@ impl<'src> Compiler<'src> { function_compiler.compile()?; function_compiler.expect(Token::RightBrace)?; - let function_end = function_compiler.previous_position.1; - self.previous_token = function_compiler.previous_token; self.previous_position = function_compiler.previous_position; self.current_token = function_compiler.current_token; self.current_position = function_compiler.current_position; + self.lexer.skip_to(self.current_position.1); + + let function_end = function_compiler.previous_position.1; let function = ConcreteValue::function(function_compiler.finish(None, value_parameters.clone())); let constant_index = self.push_or_get_constant(function); @@ -1535,8 +1533,6 @@ impl<'src> Compiler<'src> { return_type, }; - self.lexer.skip_to(function_end); - if let Some((identifier, position)) = identifier_info { let (local_index, _) = self.declare_local( identifier, @@ -1614,8 +1610,12 @@ impl<'src> Compiler<'src> { }; let start = self.current_position.0; + println!("{} {}", self.previous_token, self.current_token); + self.advance()?; + println!("{} {}", self.previous_token, self.current_token); + let mut argument_count = 0; while !self.allow(Token::RightParenthesis)? { diff --git a/dust-lang/src/disassembler.rs b/dust-lang/src/disassembler.rs index 02105a3..a73edcc 100644 --- a/dust-lang/src/disassembler.rs +++ b/dust-lang/src/disassembler.rs @@ -287,9 +287,27 @@ impl<'a> Disassembler<'a> { pub fn disassemble(mut self) -> String { let width = Disassembler::default_width(); - let top_border = "┌".to_string() + &"─".repeat(width - 2) + "┐"; - let section_border = "│".to_string() + &"┈".repeat(width - 2) + "│"; - let bottom_border = "└".to_string() + &"─".repeat(width - 2) + "┘"; + let top_border = { + let mut border = "┌".to_string(); + border += &"─".repeat(width - 2); + border += "┐"; + + border + }; + let section_border = { + let mut border = "│".to_string(); + border += &"┈".repeat(width - 2); + border += "│"; + + border + }; + let bottom_border = { + let mut border = "└".to_string(); + border += &"─".repeat(width - 2); + border += "┘"; + + border + }; let name_display = self .chunk .name() diff --git a/dust-lang/src/lib.rs b/dust-lang/src/lib.rs index 4bea669..1edd043 100644 --- a/dust-lang/src/lib.rs +++ b/dust-lang/src/lib.rs @@ -55,7 +55,9 @@ pub use crate::optimize::{optimize_control_flow, optimize_set_local}; pub use crate::r#type::{EnumType, FunctionType, StructType, Type, TypeConflict}; pub use crate::scope::Scope; pub use crate::token::{write_token_list, Token, TokenKind, TokenOwned}; -pub use crate::value::{AbstractValue, ConcreteValue, RangeValue, Value, ValueError, ValueRef}; +pub use crate::value::{ + AbstractValue, ConcreteValue, DustString, RangeValue, Value, ValueError, ValueRef, +}; pub use crate::vm::{run, Vm, VmError}; use std::fmt::Display; diff --git a/dust-lang/src/native_function/logic.rs b/dust-lang/src/native_function/logic.rs index 1dae66d..d0c055d 100644 --- a/dust-lang/src/native_function/logic.rs +++ b/dust-lang/src/native_function/logic.rs @@ -59,7 +59,7 @@ pub fn to_string<'a>(vm: &'a Vm<'a>, instruction: Instruction) -> Result(vm: &'a Vm<'a>, instruction: Instruction) -> Result, VmError> { @@ -81,7 +81,7 @@ pub fn read_line<'a>(vm: &'a Vm<'a>, instruction: Instruction) -> Result { buffer = buffer.trim_end_matches('\n').to_string(); - Ok(Some(Value::Concrete(ConcreteValue::String(buffer)))) + Ok(Some(Value::Concrete(ConcreteValue::string(buffer)))) } Err(error) => Err(VmError::NativeFunction(NativeFunctionError::Io { error: error.kind(), diff --git a/dust-lang/src/value/concrete_value.rs b/dust-lang/src/value/concrete_value.rs index 7951362..59a1a7e 100644 --- a/dust-lang/src/value/concrete_value.rs +++ b/dust-lang/src/value/concrete_value.rs @@ -1,11 +1,14 @@ use std::fmt::{self, Display, Formatter}; use serde::{Deserialize, Serialize}; +use smartstring::{LazyCompact, SmartString}; use crate::{Chunk, Type, Value, ValueError, ValueRef}; use super::RangeValue; +pub type DustString = SmartString; + #[derive(Debug, PartialEq, PartialOrd, Serialize, Deserialize)] pub enum ConcreteValue { Boolean(bool), @@ -16,7 +19,7 @@ pub enum ConcreteValue { Integer(i64), List(Vec), Range(RangeValue), - String(String), + String(DustString), } impl ConcreteValue { @@ -36,11 +39,11 @@ impl ConcreteValue { ConcreteValue::List(into_list.into()) } - pub fn string(to_string: T) -> Self { - ConcreteValue::String(to_string.to_string()) + pub fn string>>(to_string: T) -> Self { + ConcreteValue::String(to_string.into()) } - pub fn as_string(&self) -> Option<&String> { + pub fn as_string(&self) -> Option<&DustString> { if let ConcreteValue::String(string) = self { Some(string) } else { @@ -91,33 +94,6 @@ impl ConcreteValue { Ok(sum) } - pub fn add_assign(&mut self, other: &Self) -> Result<(), ValueError> { - use ConcreteValue::*; - - match (self, other) { - (Integer(left), Integer(right)) => { - *left += right; - } - (Float(left), Float(right)) => { - *left += right; - } - (String(left), String(right)) => { - *left += right; - } - (String(left), Character(right)) => { - *left += &right.to_string(); - } - (left, right) => { - return Err(ValueError::CannotAdd( - left.clone().to_value(), - right.clone().to_value(), - )) - } - } - - Ok(()) - } - pub fn subtract(&self, other: &Self) -> Result { use ConcreteValue::*; diff --git a/dust-lang/src/value/mod.rs b/dust-lang/src/value/mod.rs index 08469b8..3472687 100644 --- a/dust-lang/src/value/mod.rs +++ b/dust-lang/src/value/mod.rs @@ -4,7 +4,7 @@ mod concrete_value; mod range_value; pub use abstract_value::AbstractValue; -pub use concrete_value::ConcreteValue; +pub use concrete_value::{ConcreteValue, DustString}; pub use range_value::RangeValue; use std::fmt::{self, Debug, Display, Formatter}; diff --git a/dust-lang/tests/functions.rs b/dust-lang/tests/functions.rs index 5002201..419361b 100644 --- a/dust-lang/tests/functions.rs +++ b/dust-lang/tests/functions.rs @@ -127,7 +127,7 @@ fn function_declaration() { ], vec![ ConcreteValue::function(Chunk::with_data( - Some("add".to_string()), + Some("add".into()), FunctionType { type_parameters: None, value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), diff --git a/dust-lang/tests/math_add.rs b/dust-lang/tests/math_add.rs index a95ea81..8006e3a 100644 --- a/dust-lang/tests/math_add.rs +++ b/dust-lang/tests/math_add.rs @@ -316,10 +316,7 @@ fn add_string_and_character() { ), (Instruction::r#return(true), Span(9, 9)) ], - vec![ - ConcreteValue::String("a".to_string()), - ConcreteValue::Character('b') - ], + vec![ConcreteValue::string("a"), ConcreteValue::Character('b')], vec![] )) );