Fix function parsing bug; Optimize strings
This commit is contained in:
parent
193653ff22
commit
358436c470
25
Cargo.lock
generated
25
Cargo.lock
generated
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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<Chunk, DustError> {
|
||||
/// See the [`compile`] function an example of how to create and use a Compiler.
|
||||
#[derive(Debug)]
|
||||
pub struct Compiler<'src> {
|
||||
self_name: Option<String>,
|
||||
self_name: Option<DustString>,
|
||||
instructions: Vec<(Instruction, Type, Span)>,
|
||||
constants: Vec<ConcreteValue>,
|
||||
locals: Vec<Local>,
|
||||
@ -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)? {
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
@ -59,7 +59,7 @@ pub fn to_string<'a>(vm: &'a Vm<'a>, instruction: Instruction) -> Result<Option<
|
||||
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> {
|
||||
@ -81,7 +81,7 @@ pub fn read_line<'a>(vm: &'a Vm<'a>, instruction: Instruction) -> Result<Option<
|
||||
Ok(_) => {
|
||||
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(),
|
||||
|
@ -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<LazyCompact>;
|
||||
|
||||
#[derive(Debug, PartialEq, PartialOrd, Serialize, Deserialize)]
|
||||
pub enum ConcreteValue {
|
||||
Boolean(bool),
|
||||
@ -16,7 +19,7 @@ pub enum ConcreteValue {
|
||||
Integer(i64),
|
||||
List(Vec<ConcreteValue>),
|
||||
Range(RangeValue),
|
||||
String(String),
|
||||
String(DustString),
|
||||
}
|
||||
|
||||
impl ConcreteValue {
|
||||
@ -36,11 +39,11 @@ impl ConcreteValue {
|
||||
ConcreteValue::List(into_list.into())
|
||||
}
|
||||
|
||||
pub fn string<T: ToString>(to_string: T) -> Self {
|
||||
ConcreteValue::String(to_string.to_string())
|
||||
pub fn string<T: Into<SmartString<LazyCompact>>>(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<ConcreteValue, ValueError> {
|
||||
use ConcreteValue::*;
|
||||
|
||||
|
@ -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};
|
||||
|
@ -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)]),
|
||||
|
@ -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![]
|
||||
))
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user