diff --git a/compiler/src/lexer.rs b/compiler/src/lexer.rs index e616b93..e76e131 100644 --- a/compiler/src/lexer.rs +++ b/compiler/src/lexer.rs @@ -4,12 +4,15 @@ use std::str::Chars; #[derive(Debug, PartialEq, Clone)] pub enum Token { // Keywords + Fn, + Let, If, Else, Loop, Break, Return, Continue, + Include, // Identifiers and literals Identifier(String), @@ -24,7 +27,7 @@ pub enum Token { Semicolon, // ; Colon, // : Comma, // , - Pipe, // | + // Pipe, // | // Operators Plus, // + @@ -39,6 +42,7 @@ pub enum Token { LessEqual, // <= Greater, // > GreaterEqual, // >= + RightArrow, // -> // Special Eof, @@ -47,7 +51,10 @@ pub enum Token { impl Token { pub fn tt(&self) -> &str { match self { + Token::Include => "Include", + Token::Fn => "Fn", Token::If => "If", + Token::Let => "Let", Token::Else => "Else", Token::Loop => "Loop", Token::Break => "Break", @@ -63,7 +70,8 @@ impl Token { Token::Semicolon => "Semicolon", Token::Colon => "Colon", Token::Comma => "Comma", - Token::Pipe => "Pipe", + Token::RightArrow => "RightArrow", + // Token::Pipe => "Pipe", Token::Plus => "Plus", Token::Minus => "Minus", Token::Star => "Star", @@ -168,11 +176,17 @@ impl<'a> Lexer<'a> { Some(';') => Token::Semicolon, Some(':') => Token::Colon, Some(',') => Token::Comma, - Some('|') => Token::Pipe, + // Some('|') => Token::Pipe, Some('+') => Token::Plus, - Some('-') => Token::Minus, Some('*') => Token::Star, Some('/') => Token::Slash, + Some('-') => { + if self.match_next('>') { + Token::RightArrow + } else { + Token::Minus + } + } Some('!') => { if self.match_next('=') { Token::BangEqual @@ -218,12 +232,14 @@ impl<'a> Lexer<'a> { let mut ident = c.to_string(); ident.push_str(&self.read_identifier()); match ident.as_str() { + "fn" => Token::Fn, "if" => Token::If, "else" => Token::Else, "loop" => Token::Loop, "break" => Token::Break, "return" => Token::Return, "continue" => Token::Continue, + "include" => Token::Include, _ => Token::Identifier(ident), } } else if c.is_ascii_digit() { @@ -331,7 +347,7 @@ mod tests { assert_eq!(lexer.next_token(), Token::Colon); assert_eq!(lexer.next_token(), Token::Identifier("Func".to_string())); assert_eq!(lexer.next_token(), Token::Assign); - assert_eq!(lexer.next_token(), Token::Pipe); + // assert_eq!(lexer.next_token(), Token::Pipe); assert_eq!(lexer.next_token(), Token::Identifier("x".to_string())); assert_eq!(lexer.next_token(), Token::Colon); assert_eq!(lexer.next_token(), Token::Identifier("U32".to_string())); diff --git a/compiler/src/main.rs b/compiler/src/main.rs index 031ecc8..b1a127c 100644 --- a/compiler/src/main.rs +++ b/compiler/src/main.rs @@ -1,7 +1,12 @@ +#![feature(try_trait_v2)] + use std::{fs, path::Path}; pub mod lexer; -pub mod parser; +pub mod parserprototype; +use parserprototype::Parser; + +use crate::parserprototype::ParseResult; fn main() { println!("Hello, world!"); @@ -13,13 +18,16 @@ fn main() { let tokens = lexer.collect::>(); println!("{tokens:?}"); - let mut parser = parser::Parser::new(tokens); + let mut parser = Parser::new(tokens); let ast = match parser.parse() { - Ok(ast) => ast, - Err(e) => { + ParseResult::Accept(ast) => ast, + ParseResult::Reject(e) => { eprintln!("Error: {e:?}"); return; } + ParseResult::Deny => { + panic!("Parser denied parsing") + } }; println!("{ast:?}"); } diff --git a/compiler/src/parserprototype.rs b/compiler/src/parserprototype.rs new file mode 100644 index 0000000..72c3441 --- /dev/null +++ b/compiler/src/parserprototype.rs @@ -0,0 +1,435 @@ +use crate::lexer::Token; +use crate::{expect_tt, expect_value}; +use core::fmt; +use std::ops::{ControlFlow, FromResidual, Try}; + +#[derive(Debug, Clone)] +pub enum ParseResult { + Accept(T), + Deny, + Reject(E), +} + +#[derive(Debug, Clone)] +pub enum CompilerError { + UnexpectedToken(Token), + UnexpectedEndOfInput, + UnexpectedCharacter(char), + InvalidSyntax(String), + Generic(String), +} + +pub struct Parser { + tokens: Vec, + idx: usize, +} + +impl Parser { + pub fn new(tokens: Vec) -> Self { + Self { tokens, idx: 0 } + } + + pub fn parse(&mut self) -> ParseResult { + let mut declarations = Vec::new(); + + while let ParseResult::Accept(_) = self.peek_next() { + declarations.push(self.parse_declaration()?); + } + + ParseResult::Accept(Program { + imports: vec![], + declarations, + }) + } + + fn parse_declaration(&mut self) -> ParseResult { + if expect_tt!(self.peek_next()?, Fn).accepted() { + let x = self.parse_func(); + println!("function {:?}", x); + return x; + } + + println!("{:?}", self.peek_next()?); + + ParseResult::Reject(CompilerError::UnexpectedEndOfInput) + } + + fn parse_func(&mut self) -> ParseResult { + // expect function keyword + // + println!("pre name! {:?}", self.peek_next()?); + + let _ = expect_tt!(self.next()?, Fn); + + println!("this is the name! {:?}", self.peek_next()?); + + // expect function name + let name = match self.next()? { + Token::Identifier(name) => name, + id => return ParseResult::Reject(CompilerError::UnexpectedToken(id)), + }; + + // expect left paren + let _ = expect_tt!(self.next()?, LParen); + + let mut params = Vec::new(); + while expect_tt!(self.peek_next()?, Identifier).accepted() { + let arg = self.parse_var_decl()?; + params.push(arg); + } + + // expect right paren + let _ = expect_tt!(self.next()?, RParen); + + // see if we can parse the return type! + let mut return_type = TypeId::Void; + + if expect_tt!(self.peek_next()?, RightArrow).accepted() { + let _ = self.next(); + return_type = self.parse_type()?; + } + + // expect left brace + let _ = expect_tt!(self.next()?, LBrace); + + let mut body = Vec::new(); + + // expect right brace + let _ = expect_tt!(self.next()?, RBrace); + + ParseResult::Accept(Declaration::Function { + name, + params, + return_type, + body, + }) + } + + fn parse_var_decl(&mut self) -> ParseResult { + let name = match self.next()? { + Token::Identifier(name) => name, + id => return ParseResult::Reject(CompilerError::UnexpectedToken(id)), + }; + + let _ = expect_tt!(self.next()?, Colon); + + let type_ = self.parse_type()?; + + ParseResult::Accept(Variable { + name, + param_type: Some(type_), + }) + } + + fn parse_type(&mut self) -> ParseResult { + // get the type name incl namespace + let typename = self.parse_identifier()?; + + match typename.name.as_str() { + "u32" => ParseResult::Accept(TypeId::U32), + "u16" => ParseResult::Accept(TypeId::U16), + "u8" => ParseResult::Accept(TypeId::U8), + "i32" => ParseResult::Accept(TypeId::I32), + "i16" => ParseResult::Accept(TypeId::I16), + "i8" => ParseResult::Accept(TypeId::I8), + "void" => ParseResult::Accept(TypeId::Void), + "char" => ParseResult::Accept(TypeId::Char), + _ => todo!("Implement parsing for other types!!"), + } + } + + fn parse_identifier(&mut self) -> ParseResult { + let primary = match self.next()? { + Token::Identifier(namespace) => namespace, + id => return ParseResult::Reject(CompilerError::UnexpectedToken(id)), + }; + + if expect_tt!(self.peek_next()?, Colon).accepted() { + let _ = expect_tt!(self.next()?, Colon); + let _ = expect_tt!(self.next()?, Colon); + + let secondary = match self.next()? { + Token::Identifier(name) => name, + id => return ParseResult::Reject(CompilerError::UnexpectedToken(id)), + }; + + ParseResult::Accept(Name { + namespace: Some(primary), + name: secondary, + }) + } else { + ParseResult::Accept(Name { + namespace: None, + name: primary, + }) + } + } + + fn next(&mut self) -> ParseResult { + if self.idx >= self.tokens.len() { + ParseResult::Reject(CompilerError::UnexpectedEndOfInput) + } else { + let token = self.tokens[self.idx].clone(); + println!("NEXT {:?}", token); + self.idx += 1; + ParseResult::Accept(token) + } + } + + fn peek_next(&self) -> ParseResult { + if self.idx >= self.tokens.len() { + ParseResult::Reject(CompilerError::UnexpectedEndOfInput) + } else { + ParseResult::Accept(self.tokens[self.idx].clone()) + } + } +} + +#[derive(Debug, Clone)] +pub struct Program { + pub imports: Vec, + pub declarations: Vec, +} + +#[derive(Debug, Clone)] +pub enum Declaration { + Function { + name: String, + return_type: TypeId, + params: Vec, + body: Block, + }, + Variable { + name: String, + init: Option, + }, +} + +#[derive(Debug, Clone)] +pub struct Dependency { + pub name: String, + pub path: String, +} + +#[derive(Debug, Clone)] +pub struct Variable { + pub name: String, + pub param_type: Option, +} + +#[derive(Debug, Clone)] +pub struct Name { + pub name: String, + pub namespace: Option, +} + +#[derive(Debug, Clone)] +pub enum TypeId { + U8, + U16, + U32, + I8, + I16, + I32, + Char, + Void, + Ptr(Box), + Ref(Box), + Array(Box, usize), + Struct { + name: Name, + fields: Vec<(String, TypeId)>, + }, +} + +pub type Block = Vec; + +#[derive(Debug, Clone)] +pub enum Statement { + Block(Block), + Assign { + var: Variable, + value: Option>, + }, + Expression { + expr: Expression, + }, + If { + condition: Expression, + then_stmt: Block, + else_stmt: Block, + }, + While { + condition: Expression, + body: Vec, + }, + Loop(Block), + Break, + Continue, + Return(Option), +} + +#[derive(Debug, Clone)] +pub enum ConstExpr { + Number(i32), + String(String), +} + +impl fmt::Display for ConstExpr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + ConstExpr::Number(n) => write!(f, "{}", n), + ConstExpr::String(s) => write!(f, "\"{}\"", s), + } + } +} + +#[derive(Debug, Clone)] +pub enum Expression { + Empty, + Binary { + op: BinaryOperator, + left: Box, + right: Box, + }, + Unary { + op: UnaryOperator, + operand: Box, + }, + Variable { + name: Name, + expr_type: Option, + }, + Number { + value: i32, + }, + Call { + name: Name, + args: Vec, + }, +} + +#[derive(Debug, Clone, PartialEq)] +pub enum BinaryOperator { + Add, + Sub, + Mul, + Div, + Eq, + Ne, + Lt, + Gt, + Le, + Ge, +} + +impl fmt::Display for BinaryOperator { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + BinaryOperator::Add => write!(f, "+"), + BinaryOperator::Sub => write!(f, "-"), + BinaryOperator::Mul => write!(f, "*"), + BinaryOperator::Div => write!(f, "/"), + BinaryOperator::Eq => write!(f, "=="), + BinaryOperator::Ne => write!(f, "!="), + BinaryOperator::Lt => write!(f, "<"), + BinaryOperator::Gt => write!(f, ">"), + BinaryOperator::Le => write!(f, "<="), + BinaryOperator::Ge => write!(f, ">="), + } + } +} + +#[derive(Debug, Clone, PartialEq)] +pub enum UnaryOperator { + Plus, + Minus, +} + +impl fmt::Display for UnaryOperator { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + UnaryOperator::Plus => write!(f, "+"), + UnaryOperator::Minus => write!(f, "-"), + } + } +} + +impl ParseResult { + pub fn accepted(&self) -> bool { + matches!(self, ParseResult::Accept(_)) + } +} + +pub enum ParseResultResidual { + Deny, + Reject(T), +} + +impl Try for ParseResult { + type Output = T; + type Residual = ParseResultResidual; + + fn from_output(output: T) -> Self { + ParseResult::Accept(output) + } + + fn branch(self) -> ControlFlow { + match self { + ParseResult::Accept(v) => ControlFlow::Continue(v), + ParseResult::Deny => ControlFlow::Break(ParseResultResidual::Deny), + ParseResult::Reject(e) => ControlFlow::Break(ParseResultResidual::Reject(e)), + } + } +} + +impl FromResidual for ParseResult { + fn from_residual(residual: ParseResultResidual) -> Self { + match residual { + ParseResultResidual::Deny => ParseResult::Deny, + ParseResultResidual::Reject(e) => ParseResult::Reject(e), + } + } +} + +#[macro_export] +macro_rules! expect_tt { + ($token:expr, $($variant:ident),+) => {{ + let tt = $token.tt().to_string(); + + // for some reason the code trips tf out without this line + + println!("token {:?}", $token); + + let mut vs = String::new(); + $( + let s = stringify!($variant); + vs.push_str(s); + vs.push_str("|"); + )+ + + match tt.as_str() { + $( + stringify!($variant) => ParseResult::Accept($token.clone()), + )+ + _ => { + println!("EXPECTED!! {} [{}]", tt, vs); + // let expected = format!("[{}]", vec![$(stringify!($variant)),+].join(" | ")); + ParseResult::Reject(CompilerError::UnexpectedToken($token.clone())) + } + } + }}; +} + +#[macro_export] +macro_rules! expect_value { + ($token:expr, $variant:expr) => {{ + match $token { + $variant(x) => ParseResult::Accept(x), + _ => { + let expected = format!("[{}]") + ParseResult::Reject(CompilerError::UnexpectedToken($token.clone())) + } + } + }}; +} diff --git a/resources/dsc/example.dsc b/resources/dsc/example.dsc index 550a707..0f09703 100644 --- a/resources/dsc/example.dsc +++ b/resources/dsc/example.dsc @@ -1,8 +1,2 @@ -main: Func = | x: U32, y: U32 | { - res = add(x, y); - print(res); - - if res > 10 { - print("res is greater than 10"); - } -} +fn factorial(n: u32) -> u32 {} +fn main(x: u32, y: u32) -> u32 {} diff --git a/resources/ideas/DSA_Project_Roadmap.md b/resources/ideas/DSA_Project_Roadmap.md new file mode 100644 index 0000000..563498e --- /dev/null +++ b/resources/ideas/DSA_Project_Roadmap.md @@ -0,0 +1,843 @@ +# DSA Project Roadmap & Task Breakdown + +> **Damn Simple Architecture** — Full ecosystem development plan including emulator, assembler, compiler, debugger, and tooling infrastructure. + +--- + +## Table of Contents + +1. [Phase 1: Foundation & Core Infrastructure](#phase-1-foundation--core-infrastructure) + - [1.1 Binary Format & Linking System](#11-binary-format--linking-system) + - [1.2 Assembler Rewrite](#12-assembler-rewrite) + - [1.3 Documentation Updates](#13-documentation-updates) +2. [Phase 2: Compiler Development](#phase-2-compiler-development) + - [2.1 Language Design & Implementation](#21-language-design--implementation) + - [2.2 Standard Library](#22-standard-library) +3. [Phase 3: Build System & Package Management](#phase-3-build-system--package-management) + - [3.1 Build System](#31-build-system) + - [3.2 Package Management System](#32-package-management-system) +4. [Phase 4: Debugger & Development Tools](#phase-4-debugger--development-tools) + - [4.1 Debug Symbol System](#41-debug-symbol-system) + - [4.2 Debugger Implementation](#42-debugger-implementation) + - [4.3 Enhanced Editor Integration](#43-enhanced-editor-integration) +5. [Phase 5: Integration & Polish](#phase-5-integration--polish) +6. [Phase 6: Future Enhancements (NTH)](#phase-6-future-enhancements-nth) +7. [Summary Timeline](#summary-timeline) +8. [Critical Path](#critical-path) +9. [Recommended Work Order](#recommended-work-order) + +--- + +## Phase 1: Foundation & Core Infrastructure + +**Estimated Duration: 3–4 weeks** + +--- + +### 1.1 Binary Format & Linking System + +> **Priority: CRITICAL** — Everything depends on this. +> **Total Estimate: 1.5 weeks** + +--- + +#### 1.1.1 Design New Binary Format Specification + +**Estimate: 2 days** +**Dependencies:** None +**Deliverable:** `docs/binary-format-spec.md` + +- [ ] Research existing object file formats (ELF, COFF, Mach-O) for inspiration +- [ ] Design `.dsb` object file format specification + - [ ] Symbol table structure + - [ ] Relocation table format + - [ ] Section definitions (code, data, rodata, bss) + - [ ] Debug information structure + - [ ] Metadata headers +- [ ] Design `.dse` executable format specification + - [ ] Entry point definition + - [ ] Memory layout requirements + - [ ] Linking metadata +- [ ] Document format specifications in markdown +- [ ] Create format version strategy for future compatibility + +--- + +#### 1.1.2 Implement DSB Object File Writer + +**Estimate: 3 days** +**Dependencies:** 1.1.1 +**Deliverable:** `dsa-binary-format` crate v0.1.0 + +- [ ] Create new crate: `dsa-binary-format` +- [ ] Implement object file structures + - [ ] Header structure + - [ ] Symbol table builder + - [ ] Section manager + - [ ] Relocation entry creator +- [ ] Write serialization logic +- [ ] Add validation and error handling +- [ ] Write unit tests for each structure +- [ ] Integration tests for complete object files + +--- + +#### 1.1.3 Build Linker Program + +**Estimate: 4 days** +**Dependencies:** 1.1.2 +**Deliverable:** `dsa-link` executable + +- [ ] Create new crate: `dsa-linker` +- [ ] Implement symbol resolution + - [ ] Global symbol table + - [ ] Symbol conflict detection + - [ ] Weak symbol handling +- [ ] Implement relocation processing + - [ ] Address calculation + - [ ] Patch generation + - [ ] Cross-section references +- [ ] Build executable generator + - [ ] Combine sections + - [ ] Generate final memory layout + - [ ] Write `.dse` output +- [ ] Add linker script support (basic) +- [ ] Comprehensive error messages +- [ ] Test suite with complex linking scenarios + +--- + +### 1.2 Assembler Rewrite + +> **Priority: HIGH** — Required for all compiled code. +> **Total Estimate: 1.5 weeks** + +--- + +#### 1.2.1 Assembler Architecture Design + +**Estimate: 1 day** +**Dependencies:** 1.1.1 +**Deliverable:** `docs/assembler-architecture.md` + +- [ ] Design multi-pass architecture + - [ ] Pass 1: Symbol collection + - [ ] Pass 2: Macro expansion + - [ ] Pass 3: Code generation + - [ ] Pass 4: Relocation generation +- [ ] Plan error handling strategy +- [ ] Design threading model for parallel file processing +- [ ] Define module/import resolution system +- [ ] Plan integration points with DSC compiler + +--- + +#### 1.2.2 Implement Core Assembler + +**Estimate: 5 days** +**Dependencies:** 1.1.2, 1.2.1 +**Deliverable:** `dsa-asm` executable v2.0.0 + +- [ ] Create new crate: `dsa-assembler-ng` (next-gen) +- [ ] Implement lexer with better error recovery +- [ ] Build parser with detailed error messages + - [ ] Instruction parsing + - [ ] Directive handling + - [ ] Macro system + - [ ] Include resolution +- [ ] Symbol table management +- [ ] Code generator outputting to DSB format +- [ ] Multi-threading for file parsing +- [ ] Comprehensive test suite +- [ ] Error message testing + +--- + +#### 1.2.3 Import System & DSC Integration + +**Estimate: 2 days** +**Dependencies:** 1.2.2, 2.1.2 +**Deliverable:** Working import system + +- [ ] Design import protocol between DSC and assembler +- [ ] Implement symbol table merging +- [ ] Handle pre-compiled object imports +- [ ] Test DSC → Assembly → Object pipeline +- [ ] Document integration process + +--- + +### 1.3 Documentation Updates + +> **Priority: MEDIUM** — Can be done alongside development. +> **Total Estimate: 3 days (distributed)** + +--- + +#### 1.3.1 Update Assembly Documentation + +**Estimate: 1 day** +**Dependencies:** 1.2.2 +**Deliverable:** Updated `docs/dsa-assembly-reference.md` + +- [ ] Review all instruction documentation +- [ ] Document new pseudo-instructions +- [ ] Update calling convention docs +- [ ] Add examples for new features +- [ ] Document assembler directives +- [ ] Macro system documentation + +--- + +#### 1.3.2 Architecture Documentation + +**Estimate: 1 day** +**Dependencies:** None (can start anytime) +**Deliverable:** `docs/dsa-architecture.md` + +- [ ] Document ISA specification +- [ ] Memory model documentation +- [ ] Interrupt handling +- [ ] Hardware peripheral specs +- [ ] Timing/performance characteristics + +--- + +#### 1.3.3 Build Tools Documentation + +**Estimate: 1 day** +**Dependencies:** 1.2.2, 1.1.3, 3.1.2 +**Deliverable:** `docs/build-tools-guide.md` + +- [ ] Assembler usage guide +- [ ] Linker usage guide +- [ ] Build system guide +- [ ] Tutorial: Building a simple program +- [ ] Tutorial: Multi-file projects + +--- + +## Phase 2: Compiler Development + +**Estimated Duration: 3–4 weeks** + +--- + +### 2.1 Language Design & Implementation + +> **Priority: HIGH** — Core functionality. +> **Total Estimate: 2.5 weeks** + +--- + +#### 2.1.1 Language Syntax Design + +**Estimate: 2 days** +**Dependencies:** None +**Deliverable:** `docs/language-spec.md` + +- [ ] Define syntax goals (simplicity, systems programming) +- [ ] Design type system + - [ ] Primitive types + - [ ] Pointers/references + - [ ] Structs + - [ ] Arrays + - [ ] Function types +- [ ] Control flow syntax +- [ ] Function declaration syntax +- [ ] Module/import system +- [ ] Operator precedence +- [ ] Write EBNF grammar +- [ ] Create example programs + +--- + +#### 2.1.2 Lexer & Parser Implementation + +**Estimate: 4 days** +**Dependencies:** 2.1.1 +**Deliverable:** Parser in `dsc-compiler` crate + +- [ ] Adapt existing C lexer to new syntax +- [ ] Implement new parser for designed syntax +- [ ] AST node definitions +- [ ] Error recovery mechanisms +- [ ] Comprehensive parser tests +- [ ] Syntax error message quality testing + +--- + +#### 2.1.3 Code Generation Improvements + +**Estimate: 5 days** +**Dependencies:** 2.1.2, 1.2.2 +**Deliverable:** Working code generator + +- [ ] Review and fix existing codegen issues +- [ ] Implement missing language features + - [ ] Structs + - [ ] Arrays + - [ ] Pointers/memory operations + - [ ] For loops + - [ ] Switch statements + - [ ] Break/continue +- [ ] Optimize register allocation further +- [ ] Implement proper function calling conventions +- [ ] Add constant folding optimization +- [ ] Dead code elimination +- [ ] Test each feature thoroughly + +--- + +#### 2.1.4 Type Checking & Semantic Analysis + +**Estimate: 3 days** +**Dependencies:** 2.1.2 +**Deliverable:** Type checker integrated in compiler + +- [ ] Implement type checker +- [ ] Symbol table for scoping +- [ ] Type inference where applicable +- [ ] Const checking +- [ ] Definite assignment analysis +- [ ] Comprehensive semantic error messages +- [ ] Test suite for type errors + +--- + +### 2.2 Standard Library + +> **Priority: MEDIUM** — Needed for useful programs. +> **Total Estimate: 1 week** + +--- + +#### 2.2.1 Core Runtime Library (in Assembly) + +**Estimate: 3 days** +**Dependencies:** 1.2.2 +**Deliverable:** `lib/runtime/` directory + +- [ ] Memory allocation (malloc/free) +- [ ] String operations +- [ ] Math functions +- [ ] I/O functions (improved print, read) +- [ ] System call interface +- [ ] Tests for each function + +--- + +#### 2.2.2 Standard Library (in DSC) + +**Estimate: 2 days** +**Dependencies:** 2.1.3, 2.2.1 +**Deliverable:** `lib/std/` directory + +- [ ] String module +- [ ] Collections (array utilities, maybe simple list) +- [ ] File I/O module +- [ ] Math utilities +- [ ] Tests and examples + +--- + +## Phase 3: Build System & Package Management + +**Estimated Duration: 2–3 weeks** + +--- + +### 3.1 Build System + +> **Priority: HIGH** — Required for complex projects. +> **Total Estimate: 1.5 weeks** + +--- + +#### 3.1.1 Build System Design + +**Estimate: 1 day** +**Dependencies:** None +**Deliverable:** `docs/build-system-design.md` + +- [ ] Define project structure conventions +- [ ] Design build manifest format (`dsa-project.toml` or similar) +- [ ] Dependency resolution strategy +- [ ] Build cache design +- [ ] Incremental build strategy +- [ ] Multi-target support + +--- + +#### 3.1.2 Build Tool Implementation + +**Estimate: 5 days** +**Dependencies:** 3.1.1, 1.2.2, 1.1.3, 2.1.3 +**Deliverable:** `dsa-build` executable + +- [ ] Create crate: `dsa-build` +- [ ] Manifest parser +- [ ] Dependency graph builder +- [ ] Task orchestrator + - [ ] Compilation tasks + - [ ] Assembly tasks + - [ ] Linking tasks +- [ ] Build cache implementation +- [ ] Parallel build support +- [ ] Clean, rebuild commands +- [ ] Watch mode for development +- [ ] Comprehensive tests + +--- + +#### 3.1.3 Project Management Commands + +**Estimate: 2 days** +**Dependencies:** 3.1.2 +**Deliverable:** Enhanced `dsa-build` with project management + +- [ ] `dsa new ` — Create new project +- [ ] `dsa init` — Initialize in existing directory +- [ ] `dsa add ` — Add dependency +- [ ] Binary vs library project types +- [ ] Template system for project scaffolding +- [ ] Documentation for each command + +--- + +### 3.2 Package Management System + +> **Priority: MEDIUM** — Enables code sharing. +> **Total Estimate: 1.5 weeks** + +--- + +#### 3.2.1 Package Registry Design + +**Estimate: 2 days** +**Dependencies:** 3.1.1 +**Deliverable:** `docs/package-registry-design.md` + +- [ ] Decide: Git monorepo vs custom hosting +- [ ] Design package naming conventions +- [ ] Version resolution strategy (semver) +- [ ] Package manifest format +- [ ] Security considerations +- [ ] Package storage format (source/binary/both) +- [ ] API design for registry server + +--- + +#### 3.2.2 Local Package Manager Tool + +**Estimate: 4 days** +**Dependencies:** 3.2.1, 3.1.2 +**Deliverable:** `dsa-pkg` tool integrated with `dsa-build` + +- [ ] Create crate: `dsa-pkg` +- [ ] Package index synchronization +- [ ] Dependency resolver +- [ ] Package download/cache system +- [ ] Integration with build system +- [ ] Commands: + - [ ] `dsa install ` + - [ ] `dsa publish` + - [ ] `dsa search ` + - [ ] `dsa update` +- [ ] Lock file generation +- [ ] Test with mock registry + +--- + +#### 3.2.3 Package Registry Implementation + +**Estimate: 3 days** +**Dependencies:** 3.2.1 +**Deliverable:** Package registry (URL or repo) + +- [ ] If **Git monorepo** approach: + - [ ] Set up repository structure + - [ ] CI/CD for validation + - [ ] Submission process + - [ ] Package browser website +- [ ] If **custom hosting**: + - [ ] Simple web server (Rust + Axum/Actix) + - [ ] Package upload API + - [ ] Package search API + - [ ] Basic web UI + - [ ] Database for metadata +- [ ] Documentation for publishing + +--- + +## Phase 4: Debugger & Development Tools + +**Estimated Duration: 3–4 weeks** + +--- + +### 4.1 Debug Symbol System + +> **Priority: HIGH** — Foundation for debugging. +> **Total Estimate: 1 week** + +--- + +#### 4.1.1 Debug Symbol Format Design + +**Estimate: 1 day** +**Dependencies:** 1.1.1 +**Deliverable:** `docs/debug-symbol-format.md` + +- [ ] Design symbol table format + - [ ] Function addresses → names + - [ ] Line number → address mapping + - [ ] Variable location information + - [ ] Type information +- [ ] Define symbol table file format +- [ ] Plan for embedding in DSE/DSB files + +--- + +#### 4.1.2 Symbol Generation in Tools + +**Estimate: 3 days** +**Dependencies:** 4.1.1, 1.2.2, 2.1.3 +**Deliverable:** Debug symbols in build output + +- [ ] Modify assembler to emit debug symbols +- [ ] Modify compiler to emit debug symbols + - [ ] Source file/line tracking + - [ ] Variable scope tracking +- [ ] Linker merges debug symbols +- [ ] Test symbol generation pipeline + +--- + +#### 4.1.3 Symbol Table Loader in Emulator + +**Estimate: 2 days** +**Dependencies:** 4.1.2 +**Deliverable:** Symbol loading in emulator crate + +- [ ] Implement symbol table parser +- [ ] Build address → symbol lookup (HashMap) +- [ ] Build symbol → address lookup +- [ ] Memory efficient storage +- [ ] Tests for symbol resolution + +--- + +### 4.2 Debugger Implementation + +> **Priority: HIGH** — Major productivity boost. +> **Total Estimate: 2 weeks** + +--- + +#### 4.2.1 Core Debugger Features + +**Estimate: 5 days** +**Dependencies:** 4.1.3 +**Deliverable:** Debugger backend + +- [ ] Execution control + - [ ] Step instruction + - [ ] Step over function calls + - [ ] Continue to breakpoint + - [ ] Run to cursor +- [ ] Breakpoint system + - [ ] Address breakpoints + - [ ] Conditional breakpoints + - [ ] Watchpoints (memory access) +- [ ] Register inspection +- [ ] Memory inspection +- [ ] Stack trace generation +- [ ] Test debugger commands + +--- + +#### 4.2.2 Disassembler with Symbol Resolution + +**Estimate: 3 days** +**Dependencies:** 4.1.3 +**Deliverable:** Enhanced disassembler + +- [ ] Instruction decoder +- [ ] Format with labels instead of addresses +- [ ] Show function names at call sites +- [ ] Inline comments with variable names +- [ ] Color coding for instruction types +- [ ] Tests for disassembly output + +--- + +#### 4.2.3 Pseudo-Instruction Decompiler + +> ⚠️ **COMPLEX TASK** — Separate pass to decompile assembly into readable pseudo-instructions. + +**Estimate: 4 days** +**Dependencies:** 4.2.2 +**Deliverable:** Pseudo-instruction view mode + +- [ ] Pattern recognition for common sequences + - [ ] Function prologue/epilogue + - [ ] Multiplication using shifts/adds + - [ ] Division + - [ ] Conditional moves +- [ ] Control flow reconstruction + - [ ] If/else detection + - [ ] Loop detection + - [ ] Switch statement detection +- [ ] Expression reconstruction +- [ ] Format as higher-level pseudo-code +- [ ] Extensive pattern testing + +--- + +#### 4.2.4 Execution History Tracking + +**Estimate: 2 days** +**Dependencies:** 4.2.1 +**Deliverable:** Execution trace feature + +- [ ] Circular buffer for instruction history +- [ ] Register state snapshots over time +- [ ] Configurable history depth +- [ ] Efficient memory usage +- [ ] Playback/reverse debugging (basic) +- [ ] Export trace to file + +--- + +### 4.3 Enhanced Editor Integration + +> **Priority: MEDIUM** — UX improvement. +> **Total Estimate: 1 week** + +--- + +#### 4.3.1 Tiling Window System + +**Estimate: 2 days** +**Dependencies:** None (UI work) +**Deliverable:** Panel system in emulator + +- [ ] Research Rust tiling libraries (`egui_tiles`, or custom) +- [ ] Design panel layout system + - [ ] Code editor panel + - [ ] Disassembly panel + - [ ] Register panel + - [ ] Memory panel + - [ ] Console panel +- [ ] Implement drag-and-drop panel management +- [ ] Save/load layouts + +--- + +#### 4.3.2 Assembly Editor Improvements + +**Estimate: 2 days** +**Dependencies:** 4.3.1 +**Deliverable:** Enhanced assembly editor + +- [ ] Syntax highlighting for DSA assembly +- [ ] Auto-completion for instructions +- [ ] Label/symbol auto-completion +- [ ] Error highlighting +- [ ] Inline documentation tooltips +- [ ] Jump-to-definition for labels + +--- + +#### 4.3.3 High-Level Language Editor + +**Estimate: 2 days** +**Dependencies:** 4.3.1, 2.1.4 +**Deliverable:** DSC language editor + +- [ ] Syntax highlighting for DSC language +- [ ] Basic auto-completion +- [ ] Bracket matching +- [ ] Error highlighting from compiler +- [ ] Go-to-definition (using debug symbols) +- [ ] Inline type hints + +--- + +#### 4.3.4 Integrate Build Tools in Editor + +**Estimate: 1 day** +**Dependencies:** 4.3.1, 3.1.2 +**Deliverable:** Integrated build experience + +- [ ] Build button/command in UI +- [ ] Show build output in console panel +- [ ] Error navigation (click to jump to source) +- [ ] Hot reload on successful build +- [ ] Build status indicator + +--- + +## Phase 5: Integration & Polish + +**Estimated Duration: 1–2 weeks** + +--- + +### 5.1 Tool Integration + +> **Priority: HIGH** — Everything works together. +> **Total Estimate: 1 week** + +--- + +#### 5.1.1 Unified Toolchain + +**Estimate: 3 days** +**Dependencies:** All previous phases +**Deliverable:** `dsa` unified command-line tool + +- [ ] Create meta-crate: `dsa-tools` +- [ ] Unified CLI with subcommands + - [ ] `dsa build` + - [ ] `dsa run` + - [ ] `dsa debug` + - [ ] `dsa test` + - [ ] `dsa pkg` +- [ ] Shared configuration system +- [ ] Tool interop testing +- [ ] Documentation for workflow + +--- + +#### 5.1.2 Emulator Integration + +**Estimate: 2 days** +**Dependencies:** 5.1.1, 4.3.4 +**Deliverable:** Fully integrated development environment + +- [ ] Add build tools as emulator dependencies +- [ ] In-editor build triggered from emulator +- [ ] Debugger uses build output directly +- [ ] Source-level debugging with line mapping +- [ ] Test full edit → build → debug cycle + +--- + +#### 5.1.3 Documentation & Tutorials + +**Estimate: 2 days** +**Dependencies:** 5.1.2 +**Deliverable:** Complete documentation suite + +- [ ] Getting started guide +- [ ] Full tutorial: Building a simple game +- [ ] Debugger usage guide +- [ ] Best practices document +- [ ] Troubleshooting guide + +--- + +## Phase 6: Future Enhancements (NTH) + +> **Priority: LOW** — Nice to have, long-term goal. +> **Estimated Duration: 4+ weeks** + +--- + +### 6.1 Command-Line Emulator + +> ⚠️ **COMPLEX LONG-TERM GOAL** — Requires significant design and UX consideration. + +--- + +#### 6.1.1 Design Phase + +**Estimate: 1 week** +**Dependencies:** None +**Deliverable:** `docs/cli-emulator-design.md` + +- [ ] UX research for terminal-based debuggers +- [ ] Design TUI layout (using `ratatui` or similar) +- [ ] Command syntax design +- [ ] Scripting support design +- [ ] Accessibility considerations + +--- + +#### 6.1.2 Implementation + +**Estimate: 3+ weeks** +**Dependencies:** 6.1.1, Phase 4 complete +**Deliverable:** `dsa-emu-cli` executable + +- [ ] TUI framework setup +- [ ] Core emulator integration +- [ ] Command parser +- [ ] Panel rendering (code, registers, memory, etc.) +- [ ] Keyboard shortcuts +- [ ] Mouse support +- [ ] Configuration system +- [ ] Extensive usability testing + +--- + +## Summary Timeline + +| Phase | Duration | Key Dependencies | +|---|---|---| +| Phase 1: Foundation | 3–4 weeks | None | +| Phase 2: Compiler | 3–4 weeks | Phase 1 complete | +| Phase 3: Build System | 2–3 weeks | Phases 1–2 complete | +| Phase 4: Debugger | 3–4 weeks | Phases 1–3 complete | +| Phase 5: Integration | 1–2 weeks | Phases 1–4 complete | +| Phase 6: CLI Emulator *(NTH)* | 4+ weeks | Phase 4 complete | + +**Total Estimated Time: 12–17 weeks (3–4 months) for Phases 1–5** + +--- + +## Critical Path + +The following tasks are on the critical path and will block other work if delayed: + +``` +1.1.1 Binary format design + └── 1.1.2 Object file writer + └── 1.1.3 Linker + └── 1.2.2 Assembler rewrite + └── 2.1.3 Compiler codegen + └── 3.1.2 Build system + └── 4.1.2 Debug symbols + └── 4.2.1 Debugger +``` + +--- + +## Recommended Work Order + +| Weeks | Focus | Tasks | +|---|---|---| +| 1–2 | Binary Format & Linker | 1.1.1 → 1.1.2 → 1.1.3 | +| 3–4 | Assembler Rewrite | 1.2.1 → 1.2.2 | +| 5–6 | Compiler Syntax & Parser | 2.1.1 → 2.1.2 *(start 1.3 docs in parallel)* | +| 7–9 | Compiler Codegen & Types | 2.1.3 → 2.1.4 *(start 2.2.1 runtime in parallel)* | +| 10–11 | Build System | 3.1.1 → 3.1.2 → 3.1.3 | +| 12–13 | Package Management *(if desired now)* | 3.2.1 → 3.2.2 → 3.2.3 | +| 14–15 | Debug Symbols | 4.1.1 → 4.1.2 → 4.1.3 | +| 16–18 | Core Debugger | 4.2.1 → 4.2.2 → 4.2.4 | +| 19–20 | Editor Enhancements | 4.3.1 → 4.3.2 → 4.3.3 → 4.3.4 | +| 21–22 | Integration & Polish | 5.1.1 → 5.1.2 → 5.1.3 | + +--- + +## Notes + +- Time estimates assume ~6–8 productive hours per day. +- Add **20–30% buffer** for unexpected issues. +- Testing time is included in each estimate. +- Documentation is distributed throughout rather than batched at the end. +- Package management (3.2) can be deferred if time-constrained. +- Pseudo-instruction decompiler (4.2.3) can be a stretch goal. +- CLI emulator (Phase 6) is explicitly a "nice to have" and should not block other work. diff --git a/resources/ideas/DSA_Project_Roadmap.pdf b/resources/ideas/DSA_Project_Roadmap.pdf new file mode 100644 index 0000000..ba50e5c Binary files /dev/null and b/resources/ideas/DSA_Project_Roadmap.pdf differ diff --git a/resources/ideas/TODOS.md b/resources/ideas/TODOS.md deleted file mode 100644 index e69de29..0000000 diff --git a/resources/ideas/dsa_assembly_reference.md b/resources/ideas/dsa_assembly_reference.md new file mode 100644 index 0000000..cfdee16 --- /dev/null +++ b/resources/ideas/dsa_assembly_reference.md @@ -0,0 +1,427 @@ +# DSA Assembly Language Instruction Reference + +## Overview + +This document provides a comprehensive reference for the DSA (Damn Simple Architecture) assembly language, including all hardware instructions and pseudo-instructions with their syntax variations and usage examples. + +## Calling Convention + +| Step | Responsibility | Action | Description | +|------|----------------|--------|-------------| +| 1 | **Caller** | Push arguments | Push exactly n arguments to the stack (in order, last argument pushed first) | +| 2 | **Caller** | Call function | Execute `call namespace::function` - this automatically pushes the return address (pcx) and jumps to the function | +| 3 | **Function** | Set up stack frame | Execute `push bpr; mov spr, bpr` to establish new stack frame | +| 4 | **Function** | Access arguments | Read arguments starting at `spr+8` (first 3 args at offsets 8, 12, 16) | +| 5 | **Function** | Execute function | Perform the function's operations using the arguments | +| 6 | **Function** | Store return value | Write return value (if any) to `spr+8` | +| 7 | **Function** | Restore stack frame | Execute `mov bpr, spr; pop bpr` to restore previous stack frame | +| 8 | **Function** | Return | Execute `return` pseudo-instruction to return to caller | +| 9 | **Caller** | Clean up stack | Pop exactly n arguments from the stack to clean up | +| 10 | **Caller** | Handle unused values | Use `pop zero` to discard any unused stack values if needed | + +**Notes:** +- The namespace in step 2 is the name assigned in the `include` statement +- The `call` pseudo-instruction automatically handles return address management so long as the callee does not mess with the stack +- Arguments are accessed by the callee using offsets from the base pointer (bpr) + +## Registers + +| Register | Type | Description | +|----------|------|---------------------------------------------------------------------------------------------------| +| `rg0-rgf` | General Purpose | General-purpose registers. | +| `acc` | Special | Accumulator for calculations and temporary storage - don't use this for variables as pseudo instructions may overwrite this implicitly! | +| `spr` | Special | Stack pointer | +| `bpr` | Special | Base pointer for stack frames | +| `ret` | Special | Return address register | +| `idr` | Privileged | Interrupt descriptor table address
**on-read/write: protection fault (unless in kernel mode)** | +| `mmr` | Privileged | Hardware memory map table address
**on-read/write: protection fault (unless in kernel mode)** | +| `zero` | Read-only | Always contains zero
**on-read: always returns zero**
**on-write: value is voided** | +| `pcx` | Read-only | Program counter
**on-write: protection fault** | +| `noreg` | Placeholder | Indicates absence of register argument
**on-read/write: illegal instruction fault** | + +## Hardware Instructions + +### Data Movement Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **MOV** | `src_reg, dest_reg` | Copy value from source to destination register | +| **MOVS** | `src_reg, dest_reg` | Copy with sign extension | + +**Examples:** +```asm +mov rg0, rg1 ; Copy rg0 to rg1 +movs rg0, rg1 ; Copy rg0 to rg1 with sign extension +``` +### Memory Access Instructions + +#### Load Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **LDB** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load byte from memory | +| **LDBS** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load byte with sign extension | +| **LDH** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load half-word (16-bit) | +| **LDHS** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load half-word with sign extension | +| **LDW** | `base_reg, dest_reg [, offset]`
`label, dest_reg [, offset]` | Load word (32-bit) | + +**Examples:** +```asm +; Direct register addressing +ldb rg0, rg1 ; Load byte from address in rg0 +ldw rg0, rg1, 8 ; Load word from (rg0 + 8) + +; Label addressing +ldb buffer, rg2 ; Load byte from label 'buffer' +ldw stack, bpr ; Load stack address into base pointer +``` +**Label Expansions:** +```asm +; ldb buffer, rg2 expands to: +lli buffer, rg2 ; Load lower 16 bits of buffer address +lui buffer, rg2 ; Load upper 16 bits of buffer address +ldb rg2, rg2 ; Load byte from address in rg2 + +; ldw stack, bpr expands to: +lli stack, bpr ; Load lower 16 bits of stack address +lui stack, bpr ; Load upper 16 bits of stack address +ldw bpr, bpr ; Load word from address in bpr +``` +#### Store Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **STB** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store byte to memory | +| **STH** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store half-word to memory | +| **STW** | `src_reg, base_reg [, offset]`
`src_reg, label [, offset]` | Store word to memory | + +**Examples:** +```asm +; Direct register addressing +stb rg0, rg1 ; Store byte from rg0 to address in rg1 +stw rg0, rg1, 12 ; Store word to (rg1 + 12) + +; Label addressing +stb acc, buffer ; Store byte from accumulator to 'buffer' +stw rg1, current ; Store word to 'current' variable +``` +**Label Expansions:** +```asm +; stb acc, buffer expands to: +lli buffer, rgf ; Load lower 16 bits of buffer address +lui buffer, rgf ; Load upper 16 bits of buffer address +stb acc, rgf ; Store byte from acc to address in rgf + +; stw rg1, current expands to: +lli current, rgf ; Load lower 16 bits of current address +lui current, rgf ; Load upper 16 bits of current address +stw rg1, rgf ; Store word from rg1 to address in rgf +``` +### Immediate Load Instructions + +| Mnemonic | Operands | Description | +|----------|----------|------------------------------------------------------------------------| +| **LLI** | `imm, dest_reg` | Load 16-bit immediate into lower 16 bits
**Clears upper 16 bits!** | +| **LUI** | `imm, dest_reg` | Load 16-bit immediate into upper 16 bits | + +**Usage** + +ensure that you always run **Lli** before **Lui** as **Lli** clears the upper 16 bits. + +**Examples:** +```asm +lli 0x1234, rg0 ; Load 0x1234 into lower 16 bits of rg0 +lui 0xABCD, rg0 ; Load 0xABCD into upper 16 bits of rg0 +``` +### Jump Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **JMP** | `addr [, offset_reg]`
`imm, offset_reg` | Unconditional jump | +| **JEQ** | `addr [, offset_reg]` | Jump if equal flag set | +| **JNE** | `addr [, offset_reg]` | Jump if not equal flag set | +| **JGT** | `addr [, offset_reg]` | Jump if greater than flag set | +| **JGE** | `addr [, offset_reg]` | Jump if greater or equal flags set | +| **JLT** | `addr [, offset_reg]` | Jump if less than flag set | +| **JLE** | `addr [, offset_reg]` | Jump if less or equal flags set | + +**Examples:** +```asm +jmp start ; Jump to label 'start' +jmp 4, ret ; Jump to address (4 + ret register) +jeq end ; Jump to 'end' if equal flag set +jgt loop ; Jump to 'loop' if greater than flag set +``` +### Arithmetic Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **ADD** | `src1_reg, src2_reg, dest_reg` | Addition | +| **SUB** | `src1_reg, src2_reg, dest_reg` | Subtraction | +| **IADD** | `src_reg, imm [, dest_reg]` | Immediate addition | +| **ISUB** | `src_reg, imm [, dest_reg]` | Immediate subtraction | +| **INC** | `reg` | Increment register by 1 | +| **DEC** | `reg` | Decrement register by 1 | + +**Examples:** +```asm +add rg0, rg1, rg2 ; rg2 = rg0 + rg1 +sub rg0, rg1, rg2 ; rg2 = rg0 - rg1 +iadd rg0, 10 ; rg0 = rg0 + 10 +// or using alternate syntax +addi rg0, 1 ; rg0 = rg0 + 1 +inc rg0 ; rg0 = rg0 + 1 +``` +### Bitwise Operations + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **AND** | `src1_reg, src2_reg, dest_reg` | Bitwise AND | +| **OR** | `src1_reg, src2_reg, dest_reg` | Bitwise OR | +| **XOR** | `src1_reg, src2_reg, dest_reg` | Bitwise XOR | +| **NOT** | `src_reg, dest_reg` | Bitwise NOT | +| **NAND** | `src1_reg, src2_reg, dest_reg` | Bitwise NAND | +| **NOR** | `src1_reg, src2_reg, dest_reg` | Bitwise NOR | +| **XNOR** | `src1_reg, src2_reg, dest_reg` | Bitwise XNOR | + +**Examples:** +```asm +and rg0, rg1, rg2 ; rg2 = rg0 & rg1 +not rg0, rg1 ; rg1 = ~rg0 +``` +### Shift Operations + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **SHL** | `reg, shift_amount` | Shift left | +| **SHR** | `reg, shift_amount` | Shift right | + +**Examples:** +```asm +shl rg0, 2 ; Shift rg0 left by 2 bits +shr rg0, 3 ; Shift rg0 right by 3 bits +``` +### Comparison and Control + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **CMP** | `reg1, reg2` | Compare registers and set flags | + +**Examples:** +```asm +cmp rg0, zero ; Compare rg0 with zero register +cmp rg1, rg2 ; Compare rg1 with rg2 +``` +### System Instructions + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **HLT** | - | Halt processor execution | +| **NOP** | - | No operation | +| **INT** | `interrupt_code` | Trigger interrupt | +| **IRT** | - | Return from interrupt | + +**Examples:** +```asm +hlt ; Stop processor execution +int 0x21 ; Trigger interrupt 0x21 +``` +## Pseudo-Instructions + +### Data Definition + +| Mnemonic | Syntax | Description | +|----------|--------|-------------| +| **DB** | `name: value1 [, value2, ...]` | Define bytes | +| **DH** | `name: value1 [, value2, ...]` | Define half-words | +| **DW** | `name: value1 [, value2, ...]` | Define words | + +**Examples:** +```asm +db message: "Hello World", 0 +dh numbers: 1000, 2000, 3000 +dw stack: 0x10000 +``` +### Memory Reservation + +| Mnemonic | Syntax | Description | +|----------|--------|-------------| +| **RESB** | `name: size` | Reserve bytes | +| **RESH** | `name: size` | Reserve half-words | +| **RESW** | `name: size` | Reserve words | + +**Examples:** +```asm +resb buffer: 256 ; Reserve 256 bytes +resh array: 100 ; Reserve space for 100 half-words +resw heap: 1024 ; Reserve space for 1024 words +``` +### Stack Operations + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **PUSH** | `reg` | Push register value onto stack | +| **POP** | `reg` | Pop stack value into register | + +**Examples:** +```asm +push rg0 ; Push rg0 value onto stack +pop ret ; Pop return address +``` +### Memory Access Shortcuts + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **LWI** | `name, reg` | Load address into register | + +**Examples:** +```asm +lwi string, rg1 ; Load address of 'string' into rg1 +``` + +### Function Control + +| Mnemonic | Operands | Description | +|----------|----------|-------------| +| **CALL** | `namespace::function` | Call a function with automatic return address management | +| **RETURN** | - | Return from a function to the caller | + +**Examples:** +```asm +call print::print ; Call the print function from the print namespace +return ; Return from the current function +``` + +### Module System + +| Mnemonic | Syntax | Description | +|----------|--------|-------------| +| **INCLUDE** | `module_name "path"` | Include module | + +**Examples:** +```asm +include print "print.dsa" +include fib "fib.dsa" +``` +## Library Examples + +### Multiplication Library (multiply.dsa) + +```asm +// multiply.dsa +// usage: +// +// include multiply "" +// +// usage for multiply: +// push (arg1) +// push (arg0) +// call multiply::multiply +// pop (arg0) +// pop (arg1) + +multiply: + push bpr + mov spr, bpr + + ldw bpr, rg0, 8 // load op 1 + ldw bpr, rg1, 12 // load op 2 + + lli 0, acc // initialize accumulator + +start: + add acc, rg0, acc + dec rg1 + + cmp rg1, zero + jgt start + +end: + stw acc, bpr, 8 // store result for caller + mov bpr, spr + pop bpr + return +``` + +### Print Library (print.dsa) + +```asm +// print.dsa +// usage: +// +// include print "" +// +// usage for print: +// push (register containing address of string) +// call print::print +// pop zero +// +// usage for reset: +// call print::reset + +dw display: 0x20000 +dw current: 0x20000 + +// prints the given text to the screen. +print: + push bpr + mov spr, bpr + + ldw bpr, rg0, 8 // get string address argument + ldw current, rg1 // get current display position + +print_loop: + ldb rg0, acc + stb acc, rg1 + + iadd rg0, 1 + iadd rg1, 1 + + cmp acc, zero + jne print_loop + jmp end + +// return +end: + stw rg1, current + + mov bpr, spr + pop bpr + return + +// resets the cursor position on the screen +reset: + push bpr + mov spr, bpr + ldw display, rg1 + stw rg1, current + mov bpr, spr + pop bpr + return +``` + +### Example Program (main.dsa) + +```asm +include print "./print.dsa" + +dw stack: 0x10000 +db string: "'To confuse your enemy, you must first confuse yourself' - Probably Sun Tzu." + +init: + // set up a stack. + ldw stack, bpr + mov bpr, spr + +start: + lwi string, rg1 + + // push string address argument + push rg1 + // call print function + call print::print + // clean up stack + pop rg1 + + hlt +``` \ No newline at end of file diff --git a/resources/ideas/dsa_binary_format.md b/resources/ideas/dsa_binary_format.md new file mode 100644 index 0000000..3a372ad --- /dev/null +++ b/resources/ideas/dsa_binary_format.md @@ -0,0 +1,10 @@ +# DSA File formatting specification. + +First, a clarification on what formats this document references. + +- .dsb: DSA Binary object, similar to a .o object file +- .dse: DSA Executable file, similar to a .exe/ELF binary + +## Format Specification + +### DSB binary format