Sketching array-related things.

This commit is contained in:
Jesse Brault 2026-03-15 19:18:27 -05:00
parent 0dce883dbd
commit b4094bf570
6 changed files with 122 additions and 5 deletions

View File

@ -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()) {

View File

@ -477,11 +477,37 @@ impl<'a> Parser<'a> {
}
fn type_use(&mut self) -> Result<TypeUse, Vec<Diagnostic>> {
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(

View File

@ -56,4 +56,6 @@ pub enum TokenKind {
Public,
Mut,
Ctor,
LeftSquare,
RightSquare,
}

44
dvm-lib/src/vm/array.rs Normal file
View File

@ -0,0 +1,44 @@
use std::alloc::{Layout, alloc};
#[derive(Debug)]
#[repr(C)]
pub struct Array<T> {
header: ArrayHeader,
data: [T],
}
#[derive(Debug)]
pub struct ArrayHeader {
length: usize,
}
pub fn get_array<T: Clone>(length: usize, init: T) -> Box<Array<T>> {
let (layout, data_base) = Layout::array::<T>(length)
.and_then(|data_layout| Layout::new::<ArrayHeader>().extend(data_layout))
.unwrap();
let ptr = unsafe { alloc(layout) };
if ptr.is_null() {
panic!("failed to allocate memory");
}
unsafe {
ptr.cast::<ArrayHeader>().write(ArrayHeader { length });
let data_ptr = ptr.add(data_base).cast::<T>();
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<T>)
}
}
#[cfg(test)]
mod tests {
use crate::vm::array::get_array;
#[test]
fn int_array() {
let int_array = get_array::<i32>(5, 0);
assert_eq!(int_array.data.len(), 5);
assert_eq!(int_array.header.length, 5);
}
}

View File

@ -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;

View File

@ -0,0 +1,40 @@
fn main(args: [String])
println(args[0])
end
int Index<T, I>
op [](i: I) -> T
end
int Slice<T> : Index<T, ISize>, Iterable<T>
length: ISize
def fn iter() -> Iterator<T>
let mut i = 0
{
if i < length then
i++
Some(self[i - 1])
else
None
end
}
end
end
int Iterator<T>
fn next() -> Option<T>
end
int Iterable<T>
fn iter() -> Iterator<T>
end
extern class Array<T> : Index<T, ISize>, Slice<T>
extern length: ISize
extern op [](i: ISize) -> T
end
int List<T> : Index<T, ISize>, Slice<T>
end