diff options
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/sloth/Cargo.toml | 8 | ||||
| -rw-r--r-- | crates/sloth/src/lexer.rs | 153 | ||||
| -rw-r--r-- | crates/sloth/src/main.rs | 32 | ||||
| -rw-r--r-- | crates/sloth_bytecode/Cargo.toml | 4 | ||||
| -rw-r--r-- | crates/sloth_bytecode/src/lib.rs | 63 | ||||
| -rw-r--r-- | crates/sloth_vm/Cargo.toml | 6 | ||||
| -rw-r--r-- | crates/sloth_vm/src/lib.rs | 21 |
7 files changed, 287 insertions, 0 deletions
diff --git a/crates/sloth/Cargo.toml b/crates/sloth/Cargo.toml new file mode 100644 index 0000000..65b4859 --- /dev/null +++ b/crates/sloth/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "sloth" +version = "0.1.0" +edition = "2021" + +[dependencies] +itertools = "0.10.5" +thiserror = "1.0.40" diff --git a/crates/sloth/src/lexer.rs b/crates/sloth/src/lexer.rs new file mode 100644 index 0000000..8631eef --- /dev/null +++ b/crates/sloth/src/lexer.rs @@ -0,0 +1,153 @@ +#![allow(dead_code)] + +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum LexerError { + #[error("Unexpected token")] + UnexpectedToken, +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum TokenType { + // Meta + DocComment, + Comment, + + // Brackets + OpeningParen, // ( + ClosingParen, // ) + OpeningBracket, // [ + ClosingBracket, // ] + OpeningBrace, // { + ClosingBrace, // } + + // Operators + Plus, // + + PlusPlus, // ++ + Minus, // - + Star, // * + StarStar, // ** + Slash, // / + Perc, // % + Tilde, // ~ + + PlusEq, // += + PlusPlusEq, // ++= + MinusEq, // -= + StarEq, // *= + StarStarEq, // **= + SlashEq, // /= + PercEq, // %= + + Amp, // & + AmpAmp, // && + Pipe, // | + PipePipe, // || + + Eq, // = + EqEq, // == + Bang, // ! + BangBang, // !! + BangEq, // != + + Lt, // < + LtLt, // << + LtEq, // <= + Gt, // > + GtGt, // >> + GtEq, // >= + + Comma, + + Question, // ? + QuestionDot, // ?. + QuestionQuestion, // ?? + Dot, // . + DotDot, // .. + + Colon, // : + ColonColon, // :: + SemiColon, // ; + + Arrow, // -> + + // Keywords + Val, + Var, + + Fn, + + If, + Else, + + While, + For, + In, + + Loop, + Break, + Continue, + + As, + + // Misc + Literal(Literal), +} + +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum Literal { + Numeric, + Boolean, + Character, + String, + Regex, +} + +#[derive(Debug, Default)] +pub struct Location { + row: u32, + column: u32, +} + +#[derive(Debug)] +pub struct Token<'a> { + pub tt: TokenType, + pub lexeme: &'a str, + + start: Location, + end: Location, +} + +pub struct Lexer<'a> { + source: &'a [u8], + + start: Location, + end: Location, +} + +impl<'a> Lexer<'a> { + fn new(source: &'a str) -> Self { + Self { + source: source.as_bytes(), + start: Default::default(), + end: Default::default(), + } + } +} + +impl<'a> Iterator for Lexer<'a> { + type Item = Token<'a>; + + fn next(&mut self) -> Option<Self::Item> { + unimplemented!() + } +} + +#[cfg(test)] +mod tests { + #[test] + fn basic_test_a() { + // + } +} diff --git a/crates/sloth/src/main.rs b/crates/sloth/src/main.rs new file mode 100644 index 0000000..89ce7f9 --- /dev/null +++ b/crates/sloth/src/main.rs @@ -0,0 +1,32 @@ +#![feature(test, let_chains)] +#![warn( + clippy::wildcard_imports, + clippy::string_add, + clippy::string_add_assign, + clippy::manual_ok_or, + unused_lifetimes +)] + +pub mod lexer; + +use std::{env, fs}; + +use itertools::Itertools; + +fn main() { + let args = env::args().collect_vec(); + + if args.len() < 2 { + println!("Sloth programming language interpreter\n"); + println!("Usage: sloth <file>"); + return; + } + + let source_path = &args[1]; + let Ok(_source) = fs::read_to_string(source_path) else { + println!("Error while reading '{source_path}'"); + return; + }; + + // TODO: +} diff --git a/crates/sloth_bytecode/Cargo.toml b/crates/sloth_bytecode/Cargo.toml new file mode 100644 index 0000000..a302c81 --- /dev/null +++ b/crates/sloth_bytecode/Cargo.toml @@ -0,0 +1,4 @@ +[package] +name = "sloth_bytecode" +version = "0.1.0" +edition = "2021" diff --git a/crates/sloth_bytecode/src/lib.rs b/crates/sloth_bytecode/src/lib.rs new file mode 100644 index 0000000..f814f86 --- /dev/null +++ b/crates/sloth_bytecode/src/lib.rs @@ -0,0 +1,63 @@ +#![feature(macro_metavar_expr)] +#![allow(dead_code)] +#![warn( + clippy::wildcard_imports, + clippy::string_add, + clippy::string_add_assign, + clippy::manual_ok_or, + unused_lifetimes +)] + +macro_rules! instructions { + ( $( $opcode:literal $name:ident [ $( $v_type:ident ),* ] $doc:literal ),* ) => { + #[repr(u8)] + enum Instruction { + $( + #[doc = $doc] + $name ( $( $v_type ),* ) = $opcode + ),* + } + + impl Instruction { + fn opcode(&self) -> u8 { + match self { + $( + Self::$name ( $( _ ${ignore(v_type)} ),* ) => $opcode + ),* + } + } + + fn from_bytecode(bytecode: &[u8]) -> Option<Self> { + if bytecode.is_empty() { + return None; + } + + let opcode = bytecode[0]; + let instruction = match opcode { + $( + $opcode => { + // TODO: Get the actual values + Some(Self::$name ( $( 0 ${ignore(v_type)} ),* )) + } + ),*, + _ => None, + }; + + instruction + } + } + } +} + +instructions! { + 0x00 Constant [u64] "Push a constant value onto the stack", + + 0x01 Pop [] "Pop a value from the stack", + 0x02 Dup [] "Duplicate a value on the stack", + + 0x10 Add [] "Add the last 2 values on the stack", + 0x11 Sub [] "Subtract the last 2 values on the stack", + 0x12 Mul [] "Multiply the last 2 values on the stack", + 0x13 Div [] "Divide the last 2 values on the stack", + 0x14 Mod [] "Modulo the last 2 values on the stack" +} diff --git a/crates/sloth_vm/Cargo.toml b/crates/sloth_vm/Cargo.toml new file mode 100644 index 0000000..d27b6d2 --- /dev/null +++ b/crates/sloth_vm/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "sloth_vm" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/crates/sloth_vm/src/lib.rs b/crates/sloth_vm/src/lib.rs new file mode 100644 index 0000000..2210a57 --- /dev/null +++ b/crates/sloth_vm/src/lib.rs @@ -0,0 +1,21 @@ +#![allow(dead_code)] +#![warn( + clippy::wildcard_imports, + clippy::string_add, + clippy::string_add_assign, + clippy::manual_ok_or, + unused_lifetimes +)] + +const STACK_SIZE: usize = 1024; + +pub struct VM { + stack: [u8; STACK_SIZE], + constants: Vec<u8>, +} + +#[cfg(test)] +mod tests { + #[test] + fn add_program() {} +} |
