diff --git a/dust-lang/src/token.rs b/dust-lang/src/token.rs index 936be11..bb7e1ae 100644 --- a/dust-lang/src/token.rs +++ b/dust-lang/src/token.rs @@ -57,6 +57,7 @@ pub enum Token<'src> { Minus, MinusEqual, Percent, + PercentEqual, Plus, PlusEqual, RightCurlyBrace, @@ -116,6 +117,7 @@ impl<'src> Token<'src> { Token::Minus => 1, Token::MinusEqual => 2, Token::Percent => 1, + Token::PercentEqual => 2, Token::Plus => 1, Token::PlusEqual => 2, Token::Return => 6, @@ -171,6 +173,7 @@ impl<'src> Token<'src> { Token::MinusEqual => TokenOwned::MinusEqual, Token::Mut => TokenOwned::Mut, Token::Percent => TokenOwned::Percent, + Token::PercentEqual => TokenOwned::PercentEqual, Token::Plus => TokenOwned::Plus, Token::PlusEqual => TokenOwned::PlusEqual, Token::Return => TokenOwned::Return, @@ -230,6 +233,7 @@ impl<'src> Token<'src> { Token::MinusEqual => TokenKind::MinusEqual, Token::Mut => TokenKind::Mut, Token::Percent => TokenKind::Percent, + Token::PercentEqual => TokenKind::PercentEqual, Token::Plus => TokenKind::Plus, Token::PlusEqual => TokenKind::PlusEqual, Token::Return => TokenKind::Return, @@ -291,6 +295,7 @@ impl<'src> Display for Token<'src> { Token::MinusEqual => write!(f, "-="), Token::Mut => write!(f, "mut"), Token::Percent => write!(f, "%"), + Token::PercentEqual => write!(f, "%="), Token::Plus => write!(f, "+"), Token::PlusEqual => write!(f, "+="), Token::Return => write!(f, "return"), @@ -365,6 +370,7 @@ pub enum TokenOwned { Minus, MinusEqual, Percent, + PercentEqual, Plus, PlusEqual, RightCurlyBrace, @@ -420,6 +426,7 @@ impl Display for TokenOwned { TokenOwned::MinusEqual => Token::MinusEqual.fmt(f), TokenOwned::Mut => Token::Mut.fmt(f), TokenOwned::Percent => Token::Percent.fmt(f), + TokenOwned::PercentEqual => Token::PercentEqual.fmt(f), TokenOwned::Plus => Token::Plus.fmt(f), TokenOwned::PlusEqual => Token::PlusEqual.fmt(f), TokenOwned::Return => Token::Return.fmt(f), @@ -492,6 +499,7 @@ pub enum TokenKind { MinusEqual, Mut, Percent, + PercentEqual, Plus, PlusEqual, RightCurlyBrace, @@ -547,6 +555,7 @@ impl Display for TokenKind { TokenKind::MinusEqual => Token::MinusEqual.fmt(f), TokenKind::Mut => Token::Mut.fmt(f), TokenKind::Percent => Token::Percent.fmt(f), + TokenKind::PercentEqual => Token::PercentEqual.fmt(f), TokenKind::Plus => Token::Plus.fmt(f), TokenKind::PlusEqual => Token::PlusEqual.fmt(f), TokenKind::Return => Token::Return.fmt(f), diff --git a/dust-lang/src/value.rs b/dust-lang/src/value.rs index c348f36..4cd5c79 100644 --- a/dust-lang/src/value.rs +++ b/dust-lang/src/value.rs @@ -67,8 +67,12 @@ impl Value { Value::Primitive(Primitive::Integer(into_i64.into())) } - pub fn list(start: u8, end: u8) -> Self { - Value::Object(Object::List { start, end }) + pub fn list(start: u8, end: u8, item_type: Type) -> Self { + Value::Object(Object::List { + start, + end, + item_type, + }) } pub fn string(to_string: T) -> Self { @@ -78,7 +82,18 @@ impl Value { pub fn r#type(&self) -> Type { match self { Value::Primitive(data) => data.r#type(), - Value::Object(object) => todo!(), + Value::Object(Object::List { + start, + end, + item_type, + }) => { + let length = (end - start + 1) as usize; + + Type::List { + length, + item_type: Box::new(item_type.clone()), + } + } } } @@ -843,13 +858,13 @@ impl Ord for RangeValue { #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub enum Object { - List { start: u8, end: u8 }, + List { start: u8, end: u8, item_type: Type }, } impl Object { fn display(&self, vm: &Vm, position: Span) -> Result { match self { - Object::List { start, end } => { + Object::List { start, end, .. } => { let mut display = String::from("["); let (start, end) = (*start, *end); diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index 24b24e2..a4642c3 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -116,7 +116,8 @@ impl Vm { let to_register = instruction.a(); let first_register = instruction.b(); let last_register = instruction.c(); - let value = Value::list(first_register, last_register); + let item_type = self.get(first_register, position)?.r#type(); + let value = Value::list(first_register, last_register, item_type); self.set(to_register, value, position)?; } @@ -137,7 +138,6 @@ impl Vm { identifier: local.identifier.clone(), position, })?; - let value = self.take(from_register, to_register, position)?; self.set(to_register, value, position)?; diff --git a/dust-lang/tests/expressions.rs b/dust-lang/tests/expressions.rs index e6ae59c..72aee78 100644 --- a/dust-lang/tests/expressions.rs +++ b/dust-lang/tests/expressions.rs @@ -506,7 +506,7 @@ fn list() { )), ); - assert_eq!(run(source), Ok(Some(Value::list(0, 2)))); + assert_eq!(run(source), Ok(Some(Value::list(0, 2, Type::Integer)))); } #[test] @@ -546,7 +546,7 @@ fn list_with_complex_expression() { )), ); - assert_eq!(run(source), Ok(Some(Value::list(0, 3)))); + assert_eq!(run(source), Ok(Some(Value::list(0, 3, Type::Integer)))); } #[test] @@ -578,7 +578,7 @@ fn list_with_simple_expression() { )), ); - assert_eq!(run(source), Ok(Some(Value::list(0, 2)))); + assert_eq!(run(source), Ok(Some(Value::list(0, 2, Type::Integer)))); } #[test] diff --git a/dust-shell/src/main.rs b/dust-shell/src/main.rs index 5d5be04..161c4d8 100644 --- a/dust-shell/src/main.rs +++ b/dust-shell/src/main.rs @@ -45,22 +45,22 @@ fn main() { if let Some(command) = &args.command { if args.parse { - parse_and_display_errors(command, args.styled); + parse_and_display(command, args.styled); } else { - run_and_display_errors(command); + run_and_display(command); } } else if let Some(path) = &args.path { let source = read_to_string(path).expect("Failed to read file"); if args.parse { - parse_and_display_errors(&source, args.styled); + parse_and_display(&source, args.styled); } else { - run_and_display_errors(&source); + run_and_display(&source); } } } -fn parse_and_display_errors(source: &str, pretty_print: bool) { +fn parse_and_display(source: &str, pretty_print: bool) { match parse(source) { Ok(chunk) => println!( "{}", @@ -75,7 +75,7 @@ fn parse_and_display_errors(source: &str, pretty_print: bool) { } } -fn run_and_display_errors(source: &str) { +fn run_and_display(source: &str) { match run(source) { Ok(Some(value)) => println!("{}", value), Ok(_) => {}