From b4094bf57008200ec9f47c14f18a64310baf0162 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Sun, 15 Mar 2026 19:18:27 -0500 Subject: [PATCH] Sketching array-related things. --- dmc-lib/src/lexer.rs | 4 ++++ dmc-lib/src/parser.rs | 36 ++++++++++++++++++++++++---- dmc-lib/src/token.rs | 2 ++ dvm-lib/src/vm/array.rs | 44 +++++++++++++++++++++++++++++++++++ dvm-lib/src/vm/mod.rs | 1 + sketching/march_2026/array.dm | 40 +++++++++++++++++++++++++++++++ 6 files changed, 122 insertions(+), 5 deletions(-) create mode 100644 dvm-lib/src/vm/array.rs create mode 100644 sketching/march_2026/array.dm diff --git a/dmc-lib/src/lexer.rs b/dmc-lib/src/lexer.rs index 0433c3e..423c148 100644 --- a/dmc-lib/src/lexer.rs +++ b/dmc-lib/src/lexer.rs @@ -72,6 +72,10 @@ impl<'a> Lexer<'a> { Token::new(self.position, self.position + 1, TokenKind::Colon) } else if chunk.starts_with(".") { Token::new(self.position, self.position + 1, TokenKind::Dot) + } else if chunk.starts_with("[") { + Token::new(self.position, self.position + 1, TokenKind::LeftSquare) + } else if chunk.starts_with("]") { + Token::new(self.position, self.position + 1, TokenKind::RightSquare) } else { // more than one char token if chunk.starts_with(|c: char| c.is_ascii_digit()) { diff --git a/dmc-lib/src/parser.rs b/dmc-lib/src/parser.rs index 259135a..4b81164 100644 --- a/dmc-lib/src/parser.rs +++ b/dmc-lib/src/parser.rs @@ -477,11 +477,37 @@ impl<'a> Parser<'a> { } fn type_use(&mut self) -> Result> { - let identifier_token = self.expect_advance(TokenKind::Identifier)?; - Ok(TypeUse::new( - self.token_text(&identifier_token), - SourceRange::new(identifier_token.start(), identifier_token.end()), - )) + if self.current.is_some() { + let current = self.get_current(); + return match current.kind() { + TokenKind::LeftSquare => { + self.advance(); // [ + let inner_type_use = self.type_use()?; + self.expect_advance(TokenKind::RightSquare)?; + todo!() + } + TokenKind::Identifier => { + let identifier_token = self.expect_advance(TokenKind::Identifier)?; + Ok(TypeUse::new( + self.token_text(&identifier_token), + SourceRange::new(identifier_token.start(), identifier_token.end()), + )) + } + _ => Err(vec![Diagnostic::new( + &format!( + "Expected LeftSquare or Identifier; found: {:?}", + current.kind() + ), + current.start(), + current.end(), + )]), + }; + } + Err(vec![Diagnostic::new( + "Expected LeftSquare or Identifier; found end of input.", + self.input.len(), + self.input.len(), + )]) } fn public_class_member( diff --git a/dmc-lib/src/token.rs b/dmc-lib/src/token.rs index 5e0084a..be7bef6 100644 --- a/dmc-lib/src/token.rs +++ b/dmc-lib/src/token.rs @@ -56,4 +56,6 @@ pub enum TokenKind { Public, Mut, Ctor, + LeftSquare, + RightSquare, } diff --git a/dvm-lib/src/vm/array.rs b/dvm-lib/src/vm/array.rs new file mode 100644 index 0000000..3714e8c --- /dev/null +++ b/dvm-lib/src/vm/array.rs @@ -0,0 +1,44 @@ +use std::alloc::{Layout, alloc}; + +#[derive(Debug)] +#[repr(C)] +pub struct Array { + header: ArrayHeader, + data: [T], +} + +#[derive(Debug)] +pub struct ArrayHeader { + length: usize, +} + +pub fn get_array(length: usize, init: T) -> Box> { + let (layout, data_base) = Layout::array::(length) + .and_then(|data_layout| Layout::new::().extend(data_layout)) + .unwrap(); + let ptr = unsafe { alloc(layout) }; + if ptr.is_null() { + panic!("failed to allocate memory"); + } + unsafe { + ptr.cast::().write(ArrayHeader { length }); + let data_ptr = ptr.add(data_base).cast::(); + for i in 0..length { + data_ptr.add(i).write(init.clone()); + } + + Box::from_raw(std::ptr::slice_from_raw_parts(ptr as *mut T, length) as *mut Array) + } +} + +#[cfg(test)] +mod tests { + use crate::vm::array::get_array; + + #[test] + fn int_array() { + let int_array = get_array::(5, 0); + assert_eq!(int_array.data.len(), 5); + assert_eq!(int_array.header.length, 5); + } +} diff --git a/dvm-lib/src/vm/mod.rs b/dvm-lib/src/vm/mod.rs index abc36ff..7350159 100644 --- a/dvm-lib/src/vm/mod.rs +++ b/dvm-lib/src/vm/mod.rs @@ -17,6 +17,7 @@ use std::collections::HashMap; use std::ptr; use std::rc::Rc; +pub mod array; pub mod class; pub mod constant; pub mod function; diff --git a/sketching/march_2026/array.dm b/sketching/march_2026/array.dm new file mode 100644 index 0000000..179232b --- /dev/null +++ b/sketching/march_2026/array.dm @@ -0,0 +1,40 @@ +fn main(args: [String]) + println(args[0]) +end + +int Index + op [](i: I) -> T +end + +int Slice : Index, Iterable + length: ISize + + def fn iter() -> Iterator + let mut i = 0 + { + if i < length then + i++ + Some(self[i - 1]) + else + None + end + } + end +end + +int Iterator + fn next() -> Option +end + +int Iterable + fn iter() -> Iterator +end + +extern class Array : Index, Slice + extern length: ISize + extern op [](i: ISize) -> T +end + +int List : Index, Slice + +end \ No newline at end of file