Add chunk names
This commit is contained in:
parent
f15cf84c4d
commit
6caae6c952
@ -1,6 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
|
env::current_exe,
|
||||||
fmt::{self, Debug, Display},
|
fmt::{self, Debug, Display},
|
||||||
path::PathBuf,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
@ -10,6 +10,7 @@ use crate::{AnnotatedError, Identifier, Instruction, Span, Type, Value};
|
|||||||
|
|
||||||
#[derive(Clone, PartialOrd, Ord, Serialize, Deserialize)]
|
#[derive(Clone, PartialOrd, Ord, Serialize, Deserialize)]
|
||||||
pub struct Chunk {
|
pub struct Chunk {
|
||||||
|
name: Option<Identifier>,
|
||||||
instructions: Vec<(Instruction, Span)>,
|
instructions: Vec<(Instruction, Span)>,
|
||||||
constants: Vec<Value>,
|
constants: Vec<Value>,
|
||||||
locals: Vec<Local>,
|
locals: Vec<Local>,
|
||||||
@ -17,8 +18,9 @@ pub struct Chunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Chunk {
|
impl Chunk {
|
||||||
pub fn new() -> Self {
|
pub fn new(name: Option<Identifier>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
name,
|
||||||
instructions: Vec::new(),
|
instructions: Vec::new(),
|
||||||
constants: Vec::new(),
|
constants: Vec::new(),
|
||||||
locals: Vec::new(),
|
locals: Vec::new(),
|
||||||
@ -27,11 +29,13 @@ impl Chunk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_data(
|
pub fn with_data(
|
||||||
|
name: Option<Identifier>,
|
||||||
instructions: Vec<(Instruction, Span)>,
|
instructions: Vec<(Instruction, Span)>,
|
||||||
constants: Vec<Value>,
|
constants: Vec<Value>,
|
||||||
locals: Vec<Local>,
|
locals: Vec<Local>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
name,
|
||||||
instructions,
|
instructions,
|
||||||
constants,
|
constants,
|
||||||
locals,
|
locals,
|
||||||
@ -39,6 +43,14 @@ impl Chunk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> Option<&Identifier> {
|
||||||
|
self.name.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_name(&mut self, name: Identifier) {
|
||||||
|
self.name = Some(name);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.instructions.len()
|
self.instructions.len()
|
||||||
}
|
}
|
||||||
@ -202,34 +214,20 @@ impl Chunk {
|
|||||||
self.scope_depth -= 1;
|
self.scope_depth -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disassembler<'a>(&'a self, name: &'a str) -> ChunkDisassembler<'a> {
|
pub fn disassembler(&self) -> ChunkDisassembler {
|
||||||
ChunkDisassembler::new(name, self)
|
ChunkDisassembler::new(self)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Chunk {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Chunk {
|
impl Display for Chunk {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(f, "{}", self.disassembler().styled(true).disassemble())
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
self.disassembler("Dust Program").styled(true).disassemble()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Chunk {
|
impl Debug for Chunk {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let executable = std::env::current_exe().unwrap_or_else(|_| PathBuf::new());
|
let disassembly = self.disassembler().styled(false).disassemble();
|
||||||
let disassembly = self
|
|
||||||
.disassembler(&executable.to_string_lossy())
|
|
||||||
.styled(false)
|
|
||||||
.disassemble();
|
|
||||||
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
write!(f, "\n{}", disassembly)
|
write!(f, "\n{}", disassembly)
|
||||||
@ -277,7 +275,6 @@ impl Local {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct ChunkDisassembler<'a> {
|
pub struct ChunkDisassembler<'a> {
|
||||||
name: &'a str,
|
|
||||||
chunk: &'a Chunk,
|
chunk: &'a Chunk,
|
||||||
source: Option<&'a str>,
|
source: Option<&'a str>,
|
||||||
width: usize,
|
width: usize,
|
||||||
@ -311,9 +308,8 @@ impl<'a> ChunkDisassembler<'a> {
|
|||||||
longest_line.chars().count().max(80)
|
longest_line.chars().count().max(80)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(name: &'a str, chunk: &'a Chunk) -> Self {
|
pub fn new(chunk: &'a Chunk) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
|
||||||
chunk,
|
chunk,
|
||||||
source: None,
|
source: None,
|
||||||
width: Self::default_width(),
|
width: Self::default_width(),
|
||||||
@ -465,9 +461,18 @@ impl<'a> ChunkDisassembler<'a> {
|
|||||||
let top_border = "┌".to_string() + &"─".repeat(self.width - 2) + "┐";
|
let top_border = "┌".to_string() + &"─".repeat(self.width - 2) + "┐";
|
||||||
let section_border = "│".to_string() + &"┈".repeat(self.width - 2) + "│";
|
let section_border = "│".to_string() + &"┈".repeat(self.width - 2) + "│";
|
||||||
let bottom_border = "└".to_string() + &"─".repeat(self.width - 2) + "┘";
|
let bottom_border = "└".to_string() + &"─".repeat(self.width - 2) + "┘";
|
||||||
|
let name_display = self
|
||||||
|
.chunk
|
||||||
|
.name()
|
||||||
|
.map(|identifier| identifier.to_string())
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
current_exe()
|
||||||
|
.map(|path| path.to_string_lossy().to_string())
|
||||||
|
.unwrap_or("Chunk Disassembly".to_string())
|
||||||
|
});
|
||||||
|
|
||||||
push_border(&top_border, &mut disassembly);
|
push_border(&top_border, &mut disassembly);
|
||||||
push_header(self.name, &mut disassembly);
|
push_header(&name_display, &mut disassembly);
|
||||||
|
|
||||||
let info_line = format!(
|
let info_line = format!(
|
||||||
"{} instructions, {} constants, {} locals",
|
"{} instructions, {} constants, {} locals",
|
||||||
@ -564,7 +569,7 @@ impl<'a> ChunkDisassembler<'a> {
|
|||||||
|
|
||||||
if let Some(function_disassembly) = match value {
|
if let Some(function_disassembly) = match value {
|
||||||
Value::Function(function) => Some({
|
Value::Function(function) => Some({
|
||||||
let mut disassembler = function.chunk().disassembler("function");
|
let mut disassembler = function.chunk().disassembler();
|
||||||
disassembler.indent = self.indent + 1;
|
disassembler.indent = self.indent + 1;
|
||||||
|
|
||||||
disassembler.styled(self.styled);
|
disassembler.styled(self.styled);
|
||||||
|
@ -9,8 +9,8 @@ use colored::Colorize;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
instruction, operation, AnnotatedError, Chunk, ChunkError, DustError, FunctionType, Identifier,
|
AnnotatedError, Chunk, ChunkError, DustError, FunctionType, Identifier, Instruction, LexError,
|
||||||
Instruction, LexError, Lexer, Operation, Span, Token, TokenKind, TokenOwned, Type, Value,
|
Lexer, Operation, Span, Token, TokenKind, TokenOwned, Type, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse(source: &str) -> Result<Chunk, DustError> {
|
pub fn parse(source: &str) -> Result<Chunk, DustError> {
|
||||||
@ -59,7 +59,7 @@ impl<'src> Parser<'src> {
|
|||||||
|
|
||||||
Ok(Parser {
|
Ok(Parser {
|
||||||
lexer,
|
lexer,
|
||||||
chunk: Chunk::new(),
|
chunk: Chunk::new(None),
|
||||||
current_statement: Vec::new(),
|
current_statement: Vec::new(),
|
||||||
minimum_register: 0,
|
minimum_register: 0,
|
||||||
current_token,
|
current_token,
|
||||||
@ -171,36 +171,6 @@ impl<'src> Parser<'src> {
|
|||||||
Some(operations)
|
Some(operations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_previous_jump_mut(&mut self) -> Option<&mut Instruction> {
|
|
||||||
let staged_jump = self
|
|
||||||
.current_statement
|
|
||||||
.iter_mut()
|
|
||||||
.rev()
|
|
||||||
.find_map(|(instruction, _)| {
|
|
||||||
if matches!(instruction.operation(), Operation::Jump) {
|
|
||||||
Some(instruction)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if staged_jump.is_some() {
|
|
||||||
staged_jump
|
|
||||||
} else {
|
|
||||||
self.chunk
|
|
||||||
.instructions_mut()
|
|
||||||
.iter_mut()
|
|
||||||
.rev()
|
|
||||||
.find_map(|(instruction, _)| {
|
|
||||||
if matches!(instruction.operation(), Operation::Jump) {
|
|
||||||
Some(instruction)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn emit_constant(&mut self, value: Value, position: Span) -> Result<(), ParseError> {
|
fn emit_constant(&mut self, value: Value, position: Span) -> Result<(), ParseError> {
|
||||||
let constant_index = self.chunk.push_constant(value, position)?;
|
let constant_index = self.chunk.push_constant(value, position)?;
|
||||||
let register = self.next_register();
|
let register = self.next_register();
|
||||||
@ -1104,10 +1074,12 @@ impl<'src> Parser<'src> {
|
|||||||
let mut function_parser = Parser::new(self.lexer)?;
|
let mut function_parser = Parser::new(self.lexer)?;
|
||||||
let identifier = if let Token::Identifier(text) = function_parser.current_token {
|
let identifier = if let Token::Identifier(text) = function_parser.current_token {
|
||||||
let position = function_parser.current_position;
|
let position = function_parser.current_position;
|
||||||
|
let identifier = Identifier::new(text);
|
||||||
|
|
||||||
function_parser.advance()?;
|
function_parser.advance()?;
|
||||||
|
function_parser.chunk.set_name(identifier.clone());
|
||||||
|
|
||||||
Some((Identifier::new(text), position))
|
Some((identifier, position))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -7,6 +7,7 @@ fn add() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::add(0, 0, 1)
|
*Instruction::add(0, 0, 1)
|
||||||
@ -31,6 +32,7 @@ fn add_assign() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(12, 13)),
|
(Instruction::load_constant(0, 0, false), Span(12, 13)),
|
||||||
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
||||||
@ -53,6 +55,7 @@ fn and() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
||||||
(Instruction::test(0, false), Span(5, 7)),
|
(Instruction::test(0, false), Span(5, 7)),
|
||||||
@ -85,6 +88,7 @@ fn block_scope() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(17, 18)),
|
(Instruction::load_constant(0, 0, false), Span(17, 18)),
|
||||||
(Instruction::define_local(0, 0, false), Span(13, 14)),
|
(Instruction::define_local(0, 0, false), Span(13, 14)),
|
||||||
@ -124,6 +128,7 @@ fn constant() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(0, 2)),
|
(Instruction::load_constant(0, 0, false), Span(0, 2)),
|
||||||
(Instruction::r#return(true), Span(2, 2))
|
(Instruction::r#return(true), Span(2, 2))
|
||||||
@ -143,6 +148,7 @@ fn define_local() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(8, 10)),
|
(Instruction::load_constant(0, 0, false), Span(8, 10)),
|
||||||
(Instruction::define_local(0, 0, false), Span(4, 5)),
|
(Instruction::define_local(0, 0, false), Span(4, 5)),
|
||||||
@ -162,6 +168,7 @@ fn divide() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::divide(0, 0, 1)
|
*Instruction::divide(0, 0, 1)
|
||||||
@ -186,6 +193,7 @@ fn divide_assign() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(12, 13)),
|
(Instruction::load_constant(0, 0, false), Span(12, 13)),
|
||||||
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
||||||
@ -208,7 +216,10 @@ fn divide_assign() {
|
|||||||
fn empty() {
|
fn empty() {
|
||||||
let source = "";
|
let source = "";
|
||||||
|
|
||||||
assert_eq!(parse(source), Ok(Chunk::with_data(vec![], vec![], vec![])),);
|
assert_eq!(
|
||||||
|
parse(source),
|
||||||
|
Ok(Chunk::with_data(None, vec![], vec![], vec![]))
|
||||||
|
);
|
||||||
assert_eq!(run(source), Ok(None));
|
assert_eq!(run(source), Ok(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,6 +230,7 @@ fn empty_list() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_list(0, 0, 0), Span(0, 2)),
|
(Instruction::load_list(0, 0, 0), Span(0, 2)),
|
||||||
(Instruction::r#return(true), Span(2, 2)),
|
(Instruction::r#return(true), Span(2, 2)),
|
||||||
@ -238,6 +250,7 @@ fn equal() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 1)
|
||||||
@ -265,6 +278,7 @@ fn equality_assignment_long() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 1)
|
||||||
@ -294,6 +308,7 @@ fn equality_assignment_short() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 1)
|
||||||
@ -324,6 +339,7 @@ fn function() {
|
|||||||
run(source),
|
run(source),
|
||||||
Ok(Some(Value::function(
|
Ok(Some(Value::function(
|
||||||
Chunk::with_data(
|
Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::add(2, 0, 1), Span(30, 31)),
|
(Instruction::add(2, 0, 1), Span(30, 31)),
|
||||||
(Instruction::r#return(true), Span(34, 35)),
|
(Instruction::r#return(true), Span(34, 35)),
|
||||||
@ -353,12 +369,14 @@ fn function_declaration() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(0, 40)),
|
(Instruction::load_constant(0, 0, false), Span(0, 40)),
|
||||||
(Instruction::define_local(0, 0, false), Span(3, 6)),
|
(Instruction::define_local(0, 0, false), Span(3, 6)),
|
||||||
],
|
],
|
||||||
vec![Value::function(
|
vec![Value::function(
|
||||||
Chunk::with_data(
|
Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::add(2, 0, 1), Span(35, 36)),
|
(Instruction::add(2, 0, 1), Span(35, 36)),
|
||||||
(Instruction::r#return(true), Span(39, 40)),
|
(Instruction::r#return(true), Span(39, 40)),
|
||||||
@ -405,6 +423,7 @@ fn function_call() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(0, 36)),
|
(Instruction::load_constant(0, 0, false), Span(0, 36)),
|
||||||
(Instruction::load_constant(1, 1, false), Span(36, 37)),
|
(Instruction::load_constant(1, 1, false), Span(36, 37)),
|
||||||
@ -415,6 +434,7 @@ fn function_call() {
|
|||||||
vec![
|
vec![
|
||||||
Value::function(
|
Value::function(
|
||||||
Chunk::with_data(
|
Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::add(2, 0, 1), Span(30, 31)),
|
(Instruction::add(2, 0, 1), Span(30, 31)),
|
||||||
(Instruction::r#return(true), Span(34, 35)),
|
(Instruction::r#return(true), Span(34, 35)),
|
||||||
@ -451,6 +471,7 @@ fn greater() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::less_equal(false, 0, 1)
|
*Instruction::less_equal(false, 0, 1)
|
||||||
@ -478,6 +499,7 @@ fn greater_than_or_equal() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::less(false, 0, 1)
|
*Instruction::less(false, 0, 1)
|
||||||
@ -505,6 +527,7 @@ fn if_else_expression() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 1)
|
||||||
@ -537,6 +560,7 @@ fn if_expression_false() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 1)
|
||||||
@ -562,6 +586,7 @@ fn if_expression_true() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(true, 0, 1)
|
*Instruction::equal(true, 0, 1)
|
||||||
@ -587,6 +612,7 @@ fn less_than() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::less(true, 0, 1)
|
*Instruction::less(true, 0, 1)
|
||||||
@ -614,6 +640,7 @@ fn less_than_or_equal() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::less_equal(true, 0, 1)
|
*Instruction::less_equal(true, 0, 1)
|
||||||
@ -641,6 +668,7 @@ fn list() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
||||||
(Instruction::load_constant(1, 1, false), Span(4, 5)),
|
(Instruction::load_constant(1, 1, false), Span(4, 5)),
|
||||||
@ -663,6 +691,7 @@ fn list_with_complex_expression() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
||||||
(
|
(
|
||||||
@ -703,6 +732,7 @@ fn list_with_simple_expression() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
(Instruction::load_constant(0, 0, false), Span(1, 2)),
|
||||||
(
|
(
|
||||||
@ -735,6 +765,7 @@ fn math_operator_precedence() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::add(0, 0, 1)
|
*Instruction::add(0, 0, 1)
|
||||||
@ -776,6 +807,7 @@ fn multiply() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::multiply(0, 0, 1)
|
*Instruction::multiply(0, 0, 1)
|
||||||
@ -800,6 +832,7 @@ fn multiply_assign() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(12, 13)),
|
(Instruction::load_constant(0, 0, false), Span(12, 13)),
|
||||||
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
||||||
@ -825,6 +858,7 @@ fn negate() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(*Instruction::negate(0, 0).set_b_is_constant(), Span(0, 1)),
|
(*Instruction::negate(0, 0).set_b_is_constant(), Span(0, 1)),
|
||||||
(Instruction::r#return(true), Span(5, 5)),
|
(Instruction::r#return(true), Span(5, 5)),
|
||||||
@ -844,6 +878,7 @@ fn not() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_boolean(0, true, false), Span(1, 5)),
|
(Instruction::load_boolean(0, true, false), Span(1, 5)),
|
||||||
(Instruction::not(1, 0), Span(0, 1)),
|
(Instruction::not(1, 0), Span(0, 1)),
|
||||||
@ -864,6 +899,7 @@ fn not_equal() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::equal(false, 0, 1)
|
*Instruction::equal(false, 0, 1)
|
||||||
@ -891,6 +927,7 @@ fn or() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
(Instruction::load_boolean(0, true, false), Span(0, 4)),
|
||||||
(Instruction::test(0, true), Span(5, 7)),
|
(Instruction::test(0, true), Span(5, 7)),
|
||||||
@ -913,6 +950,7 @@ fn parentheses_precedence() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::add(0, 0, 1)
|
*Instruction::add(0, 0, 1)
|
||||||
@ -941,6 +979,7 @@ fn set_local() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(12, 14)),
|
(Instruction::load_constant(0, 0, false), Span(12, 14)),
|
||||||
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
||||||
@ -964,6 +1003,7 @@ fn subtract() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
*Instruction::subtract(0, 0, 1)
|
*Instruction::subtract(0, 0, 1)
|
||||||
@ -988,6 +1028,7 @@ fn subtract_assign() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(12, 14)),
|
(Instruction::load_constant(0, 0, false), Span(12, 14)),
|
||||||
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
||||||
@ -1013,6 +1054,7 @@ fn variable_and() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_boolean(0, true, false), Span(8, 12)),
|
(Instruction::load_boolean(0, true, false), Span(8, 12)),
|
||||||
(Instruction::define_local(0, 0, false), Span(4, 5)),
|
(Instruction::define_local(0, 0, false), Span(4, 5)),
|
||||||
@ -1042,6 +1084,7 @@ fn r#while() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse(source),
|
parse(source),
|
||||||
Ok(Chunk::with_data(
|
Ok(Chunk::with_data(
|
||||||
|
None,
|
||||||
vec![
|
vec![
|
||||||
(Instruction::load_constant(0, 0, false), Span(12, 13)),
|
(Instruction::load_constant(0, 0, false), Span(12, 13)),
|
||||||
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
(Instruction::define_local(0, 0, true), Span(8, 9)),
|
||||||
|
@ -111,7 +111,7 @@ fn parse_source(source: &str, styled: bool) {
|
|||||||
match parse(source) {
|
match parse(source) {
|
||||||
Ok(chunk) => {
|
Ok(chunk) => {
|
||||||
let disassembly = chunk
|
let disassembly = chunk
|
||||||
.disassembler("Dust CLI Input")
|
.disassembler()
|
||||||
.source(source)
|
.source(source)
|
||||||
.styled(styled)
|
.styled(styled)
|
||||||
.disassemble();
|
.disassemble();
|
||||||
|
5
examples/assets/count.js
Normal file
5
examples/assets/count.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
var i = 0;
|
||||||
|
|
||||||
|
while (i < 10000) {
|
||||||
|
i++;
|
||||||
|
}
|
5
examples/count.ds
Normal file
5
examples/count.ds
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
let mut i = 0;
|
||||||
|
|
||||||
|
while i < 10000 {
|
||||||
|
i += 1;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user