1
0

Fix function parsing bug; Optimize strings

This commit is contained in:
Jeff 2024-12-04 06:38:24 -05:00
parent 193653ff22
commit 358436c470
11 changed files with 75 additions and 55 deletions

25
Cargo.lock generated
View File

@ -197,6 +197,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"smallvec", "smallvec",
"smartstring",
] ]
[[package]] [[package]]
@ -496,6 +497,18 @@ dependencies = [
"serde", "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]] [[package]]
name = "spin" name = "spin"
version = "0.9.8" version = "0.9.8"
@ -511,6 +524,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.11.1" version = "0.11.1"
@ -546,6 +565,12 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"

View File

@ -19,6 +19,7 @@ getrandom = { version = "0.2", features = [
"js", "js",
] } # Indirect dependency, for wasm builds ] } # Indirect dependency, for wasm builds
smallvec = { version = "1.13.2", features = ["serde"] } smallvec = { version = "1.13.2", features = ["serde"] }
smartstring = { version = "1.0.1", features = ["serde"], default-features = false }
[dev-dependencies] [dev-dependencies]
env_logger = "0.11.5" env_logger = "0.11.5"

View File

@ -8,6 +8,7 @@ use std::fmt::{self, Debug, Display, Write};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use smallvec::SmallVec; use smallvec::SmallVec;
use smartstring::alias::String;
use crate::{ConcreteValue, Disassembler, FunctionType, Instruction, Scope, Span, Type}; use crate::{ConcreteValue, Disassembler, FunctionType, Instruction, Scope, Span, Type};

View File

@ -18,11 +18,9 @@ use crate::{
Call, CallNative, Close, DefineLocal, GetLocal, Jump, LoadBoolean, LoadConstant, LoadList, Call, CallNative, Close, DefineLocal, GetLocal, Jump, LoadBoolean, LoadConstant, LoadList,
LoadSelf, Move, Negate, Not, Return, SetLocal, Test, LoadSelf, Move, Negate, Not, Return, SetLocal, Test,
}, },
optimize_control_flow, optimize_set_local, optimize_control_flow, optimize_set_local, AnnotatedError, Argument, Chunk, ConcreteValue,
value::ConcreteValue, Destination, DustError, DustString, FunctionType, Instruction, LexError, Lexer, Local,
AnnotatedError, Argument, Chunk, Destination, DustError, FunctionType, Instruction, LexError, NativeFunction, Operation, Scope, Span, Token, TokenKind, TokenOwned, Type, TypeConflict,
Lexer, Local, NativeFunction, Operation, Scope, Span, Token, TokenKind, TokenOwned, Type,
TypeConflict,
}; };
/// Compiles the input and returns a chunk. /// Compiles the input and returns a chunk.
@ -55,7 +53,7 @@ pub fn compile(source: &str) -> Result<Chunk, DustError> {
/// See the [`compile`] function an example of how to create and use a Compiler. /// See the [`compile`] function an example of how to create and use a Compiler.
#[derive(Debug)] #[derive(Debug)]
pub struct Compiler<'src> { pub struct Compiler<'src> {
self_name: Option<String>, self_name: Option<DustString>,
instructions: Vec<(Instruction, Type, Span)>, instructions: Vec<(Instruction, Type, Span)>,
constants: Vec<ConcreteValue>, constants: Vec<ConcreteValue>,
locals: Vec<Local>, locals: Vec<Local>,
@ -1279,7 +1277,6 @@ impl<'src> Compiler<'src> {
let start = self.previous_position.0; let start = self.previous_position.0;
let start_register = self.next_register(); let start_register = self.next_register();
self.advance()?;
self.expect(Token::LeftParenthesis)?; self.expect(Token::LeftParenthesis)?;
while !self.allow(Token::RightParenthesis)? { while !self.allow(Token::RightParenthesis)? {
@ -1447,7 +1444,7 @@ impl<'src> Compiler<'src> {
function_compiler.advance()?; function_compiler.advance()?;
function_compiler.self_name = Some(text.to_string()); function_compiler.self_name = Some(text.into());
Some((text, position)) Some((text, position))
} else { } else {
@ -1518,13 +1515,14 @@ impl<'src> Compiler<'src> {
function_compiler.compile()?; function_compiler.compile()?;
function_compiler.expect(Token::RightBrace)?; function_compiler.expect(Token::RightBrace)?;
let function_end = function_compiler.previous_position.1;
self.previous_token = function_compiler.previous_token; self.previous_token = function_compiler.previous_token;
self.previous_position = function_compiler.previous_position; self.previous_position = function_compiler.previous_position;
self.current_token = function_compiler.current_token; self.current_token = function_compiler.current_token;
self.current_position = function_compiler.current_position; 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 = let function =
ConcreteValue::function(function_compiler.finish(None, value_parameters.clone())); ConcreteValue::function(function_compiler.finish(None, value_parameters.clone()));
let constant_index = self.push_or_get_constant(function); let constant_index = self.push_or_get_constant(function);
@ -1535,8 +1533,6 @@ impl<'src> Compiler<'src> {
return_type, return_type,
}; };
self.lexer.skip_to(function_end);
if let Some((identifier, position)) = identifier_info { if let Some((identifier, position)) = identifier_info {
let (local_index, _) = self.declare_local( let (local_index, _) = self.declare_local(
identifier, identifier,
@ -1614,8 +1610,12 @@ impl<'src> Compiler<'src> {
}; };
let start = self.current_position.0; let start = self.current_position.0;
println!("{} {}", self.previous_token, self.current_token);
self.advance()?; self.advance()?;
println!("{} {}", self.previous_token, self.current_token);
let mut argument_count = 0; let mut argument_count = 0;
while !self.allow(Token::RightParenthesis)? { while !self.allow(Token::RightParenthesis)? {

View File

@ -287,9 +287,27 @@ impl<'a> Disassembler<'a> {
pub fn disassemble(mut self) -> String { pub fn disassemble(mut self) -> String {
let width = Disassembler::default_width(); let width = Disassembler::default_width();
let top_border = "".to_string() + &"".repeat(width - 2) + ""; let top_border = {
let section_border = "".to_string() + &"".repeat(width - 2) + ""; let mut border = "".to_string();
let bottom_border = "".to_string() + &"".repeat(width - 2) + ""; 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 let name_display = self
.chunk .chunk
.name() .name()

View File

@ -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::r#type::{EnumType, FunctionType, StructType, Type, TypeConflict};
pub use crate::scope::Scope; pub use crate::scope::Scope;
pub use crate::token::{write_token_list, Token, TokenKind, TokenOwned}; 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}; pub use crate::vm::{run, Vm, VmError};
use std::fmt::Display; use std::fmt::Display;

View File

@ -59,7 +59,7 @@ pub fn to_string<'a>(vm: &'a Vm<'a>, instruction: Instruction) -> Result<Option<
string.push_str(&argument_string); string.push_str(&argument_string);
} }
Ok(Some(Value::Concrete(ConcreteValue::String(string)))) Ok(Some(Value::Concrete(ConcreteValue::string(string))))
} }
pub fn read_line<'a>(vm: &'a Vm<'a>, instruction: Instruction) -> Result<Option<Value>, VmError> { pub fn read_line<'a>(vm: &'a Vm<'a>, instruction: Instruction) -> Result<Option<Value>, VmError> {
@ -81,7 +81,7 @@ pub fn read_line<'a>(vm: &'a Vm<'a>, instruction: Instruction) -> Result<Option<
Ok(_) => { Ok(_) => {
buffer = buffer.trim_end_matches('\n').to_string(); 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 { Err(error) => Err(VmError::NativeFunction(NativeFunctionError::Io {
error: error.kind(), error: error.kind(),

View File

@ -1,11 +1,14 @@
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use smartstring::{LazyCompact, SmartString};
use crate::{Chunk, Type, Value, ValueError, ValueRef}; use crate::{Chunk, Type, Value, ValueError, ValueRef};
use super::RangeValue; use super::RangeValue;
pub type DustString = SmartString<LazyCompact>;
#[derive(Debug, PartialEq, PartialOrd, Serialize, Deserialize)] #[derive(Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
pub enum ConcreteValue { pub enum ConcreteValue {
Boolean(bool), Boolean(bool),
@ -16,7 +19,7 @@ pub enum ConcreteValue {
Integer(i64), Integer(i64),
List(Vec<ConcreteValue>), List(Vec<ConcreteValue>),
Range(RangeValue), Range(RangeValue),
String(String), String(DustString),
} }
impl ConcreteValue { impl ConcreteValue {
@ -36,11 +39,11 @@ impl ConcreteValue {
ConcreteValue::List(into_list.into()) ConcreteValue::List(into_list.into())
} }
pub fn string<T: ToString>(to_string: T) -> Self { pub fn string<T: Into<SmartString<LazyCompact>>>(to_string: T) -> Self {
ConcreteValue::String(to_string.to_string()) 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 { if let ConcreteValue::String(string) = self {
Some(string) Some(string)
} else { } else {
@ -91,33 +94,6 @@ impl ConcreteValue {
Ok(sum) 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<ConcreteValue, ValueError> { pub fn subtract(&self, other: &Self) -> Result<ConcreteValue, ValueError> {
use ConcreteValue::*; use ConcreteValue::*;

View File

@ -4,7 +4,7 @@ mod concrete_value;
mod range_value; mod range_value;
pub use abstract_value::AbstractValue; pub use abstract_value::AbstractValue;
pub use concrete_value::ConcreteValue; pub use concrete_value::{ConcreteValue, DustString};
pub use range_value::RangeValue; pub use range_value::RangeValue;
use std::fmt::{self, Debug, Display, Formatter}; use std::fmt::{self, Debug, Display, Formatter};

View File

@ -127,7 +127,7 @@ fn function_declaration() {
], ],
vec![ vec![
ConcreteValue::function(Chunk::with_data( ConcreteValue::function(Chunk::with_data(
Some("add".to_string()), Some("add".into()),
FunctionType { FunctionType {
type_parameters: None, type_parameters: None,
value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]), value_parameters: Some(vec![(0, Type::Integer), (1, Type::Integer)]),

View File

@ -316,10 +316,7 @@ fn add_string_and_character() {
), ),
(Instruction::r#return(true), Span(9, 9)) (Instruction::r#return(true), Span(9, 9))
], ],
vec![ vec![ConcreteValue::string("a"), ConcreteValue::Character('b')],
ConcreteValue::String("a".to_string()),
ConcreteValue::Character('b')
],
vec![] vec![]
)) ))
); );