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",
|
||||||
"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"
|
||||||
|
@ -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"
|
||||||
|
@ -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};
|
||||||
|
|
||||||
|
@ -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)? {
|
||||||
|
@ -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()
|
||||||
|
@ -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;
|
||||||
|
@ -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(),
|
||||||
|
@ -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::*;
|
||||||
|
|
||||||
|
@ -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};
|
||||||
|
@ -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)]),
|
||||||
|
@ -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![]
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user