diff --git a/resources/concept/assemblerconcept.md b/resources/concept/assemblerconcept.md deleted file mode 100644 index 72ebfec..0000000 --- a/resources/concept/assemblerconcept.md +++ /dev/null @@ -1,279 +0,0 @@ - - -```rust -// src/assembler/source.rs -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct SourcePosition { - pub line: u32, - pub column: u32, - pub offset: usize, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct SourceSpan { - pub start: SourcePosition, - pub end: SourcePosition, - pub file_id: u64, // Hash of the file path -} - -impl SourceSpan { - pub fn new(start: SourcePosition, end: SourcePosition, file_id: u64) -> Self { - Self { start, end, file_id } - } - - pub fn single_char(pos: SourcePosition, file_id: u64) -> Self { - Self { - start: pos, - end: pos, - file_id, - } - } -} -2. Enhanced Token with Source Information -Update the Token type to include source positions: - -```rust -// src/assembler/model.rs -pub struct Token { - pub kind: TokenKind, - pub span: SourceSpan, - pub raw: String, // Original source text -} - -pub enum TokenKind { - // ... existing variants ... -} -3. Enhanced CodeModule Structure -Enhance the -CodeModule - struct to track source information: - -```rust -// src/assembler/mod.rs -pub struct CodeModule { - pub path: PathBuf, - pub hash: u64, - pub source: String, - pub lines: Vec, // Line start offsets for quick lookup - pub tokens: Vec, - pub nodes: Vec, - pub dependencies: Vec, -} - -impl CodeModule { - pub fn new(path: PathBuf, source: String) -> Self { - let hash = quick_hash(&path); - let lines = source.lines() - .scan(0, |offset, line| { - let start = *offset; - *offset += line.len() + 1; // +1 for newline - Some(start) - }) - .collect(); - - Self { - path, - hash, - source, - lines, - tokens: Vec::new(), - nodes: Vec::new(), - dependencies: Vec::new(), - } - } - - pub fn position_from_offset(&self, offset: usize) -> (u32, u32) { - match self.lines.binary_search(&offset) { - Ok(line) => (line as u32 + 1, 1), - Err(0) => (1, offset as u32 + 1), - Err(line) => { - let line_start = self.lines[line - 1]; - (line as u32, (offset - line_start + 1) as u32) - } - } - } -} -4. Enhanced Lexer with Source Positions -Update the lexer to track source positions: - -```rust -// src/assembler/lexer.rs -pub fn lex(module: &mut CodeModule) -> Result<(), AssembleError> { - let source = &module.source; - let mut tokens = Vec::new(); - let mut pos = 0; - let mut line_start = 0; - let mut line = 1; - - while pos < source.len() { - let c = source[pos..].chars().next().unwrap(); - - if c == '\n' { - line += 1; - line_start = pos + 1; - pos += 1; - continue; - } - - if c.is_whitespace() { - pos += 1; - continue; - } - - let token_start = pos; - // ... existing token parsing logic ... - - // When creating a token: - let start_pos = SourcePosition { - line, - column: (token_start - line_start + 1) as u32, - offset: token_start, - }; - - // Update pos based on token length - let token_length = /* calculate token length */; - pos += token_length; - - let end_pos = SourcePosition { - line, - column: (pos - line_start + 1) as u32, - offset: pos, - }; - - tokens.push(Token { - kind: token_kind, - span: SourceSpan::new(start_pos, end_pos, module.hash), - raw: source[token_start..pos].to_string(), - }); - } - - module.tokens = tokens; - Ok(()) -} -5. Enhanced Error Reporting -Create a structured error type with source context: - -```rust -// src/assembler/error.rs -#[derive(Debug)] -pub struct AssemblerError { - pub kind: ErrorKind, - pub span: SourceSpan, - pub message: String, - pub context: Vec, -} - -impl AssemblerError { - pub fn new(kind: ErrorKind, span: SourceSpan, message: impl Into) -> Self { - Self { - kind, - span, - message: message.into(), - context: Vec::new(), - } - } - - pub fn with_context(mut self, context: impl Into) -> Self { - self.context.push(context.into()); - self - } - - pub fn format(&self, module: &CodeModule) -> String { - let (line, col) = module.position_from_offset(self.span.start.offset); - let line_content = module.source.lines().nth(line as usize - 1).unwrap_or(""); - - let mut output = format!( - "{}:{}:{}: {}\n", - module.path.display(), - line, - col, - self.message - ); - - // Add source line with caret - output.push_str(&format!("{}\n", line_content)); - output.push_str(&" ".repeat(col as usize - 1)); - output.push_str("^\n"); - - // Add context if any - for ctx in &self.context { - output.push_str(&format!(" = note: {}\n", ctx)); - } - - output - } -} -6. Integration with Compilation Pipeline -Update the compilation pipeline to use the enhanced types: - -```rust -// src/assembler/mod.rs -pub fn assemble(src: &Path) -> Result, AssemblerError> { - let source = std::fs::read_to_string(src) - .map_err(|e| AssemblerError::io_error(src, e))?; - - let mut module = CodeModule::new(src.to_path_buf(), source); - - // Lexing - lexer::lex(&mut module)?; - - // Parsing - parser::parse(&mut module)?; - - // Resolution - resolver::resolve(&mut module)?; - - // Code generation - codegen::generate(&module) -} -7. Logging Integration -Enhance the logging system to include source context: - -```rust -// src/util/logging.rs -pub trait Loggable { - fn log(&self, level: LogLevel, message: impl std::fmt::Display); - fn log_with_span(&self, level: LogLevel, span: &SourceSpan, message: impl std::fmt::Display); -} - -impl Loggable for CodeModule { - fn log_with_span(&self, level: LogLevel, span: &SourceSpan, message: impl std::fmt::Display) { - if span.file_id != self.hash { - if let Some(dep) = self.find_dependency(span.file_id) { - return dep.log_with_span(level, span, message); - } - } - - let (line, col) = self.position_from_offset(span.start.offset); - let line_content = self.source.lines().nth(line as usize - 1).unwrap_or(""); - - log::log!( - level, - "{}:{}:{}: {}\n {}\n {}{}", - self.path.display(), - line, - col, - message, - line_content, - " ".repeat(col as usize - 1), - "^" - ); - } -} -8. Usage Example -Here's how you'd use this in practice: - -```rust -// In your parser or code that needs to report errors -fn parse_token(&mut self, module: &CodeModule) -> Result { - // ... - if !is_valid_token(&token) { - return Err(AssemblerError::new( - ErrorKind::SyntaxError, - token.span, - "Invalid token" - ).with_context("Expected a valid instruction or directive")); - } - // ... -} -``` diff --git a/resources/dsa/bf.dsa b/resources/dsa/bf.dsa index d87d25f..57e39d9 100644 --- a/resources/dsa/bf.dsa +++ b/resources/dsa/bf.dsa @@ -2,7 +2,7 @@ // a simple brainf##k interpreter, // because I already wrote a compiler lol. -include print "./lib/print.dsa" +include print "./lib/io/print.dsa" // "print hello world" db program: "++++++++++++++++++++++++++++++++++++++++++++ diff --git a/resources/dsa/lib/error/handlers.dsa b/resources/dsa/lib/error/handlers.dsa new file mode 100644 index 0000000..418cef2 --- /dev/null +++ b/resources/dsa/lib/error/handlers.dsa @@ -0,0 +1,34 @@ +include print "../io/print.dsa" + +dw idt: 0xFFFF0000 + +setup_idt: + push bpr + mov spr, bpr + + // load the IDT into the IDR + ldw idt, idr + + mov bpr, spr + pop bpr + irt + +setup_hard_fault_handler: + push bpr + mov spr, bpr + + lwi handle_hard_fault, rg0 + stw rg0, idr, 4 + + mov bpr, spr + pop bpr + irt + +dw hard_fault_err: "FATAL: Illegal Instruction or Memory Access!" +handle_hard_fault: + call print::reset + lwi hard_fault_err, rg0 + push rg0 + call print::print + pop zero + hlt diff --git a/resources/dsa/lib/print.dsa b/resources/dsa/lib/io/print.dsa similarity index 66% rename from resources/dsa/lib/print.dsa rename to resources/dsa/lib/io/print.dsa index d6ad711..efa6325 100644 --- a/resources/dsa/lib/print.dsa +++ b/resources/dsa/lib/io/print.dsa @@ -4,7 +4,7 @@ // usage: // // include print """ -// +// // usage for print: // push (register containing address of string) // push pcx @@ -68,7 +68,7 @@ print_word: jmp _end // ------------------------------------------ -// prints the last byte of arg[0] to the screen. +// prints the last byte of arg[0] to the screen. print_byte: push bpr mov spr, bpr @@ -80,6 +80,58 @@ print_byte: addi rg1, 1 jmp _end +// ------------------------------------------ +// prints the value of arg[0] to the screen in hex. +print_hex_byte: + push bpr + mov spr, bpr + + // put arg byte in rg0 + ldw bpr, rg0, 8 + ldw current, rg1 + + // mask to get lower nibble + lli 0xF, rg2 + // save rg0 state + push rg0 + + shr rg0, 4 + and rg0, rg2, rg0 + call _print_hex_nibble + pop rg0 + + and rg0, rg2, rg0 + call _print_hex_nibble + jmp _end + +_print_hex_nibble: + lli 10, rg3 + cmp rg0, rg3 + jlt _print_hex_nibble_number + addi rg0, 0x37, rg0 + stb rg0, rg1 + addi rg1, 1 + jmp _end + +_print_hex_nibble_number: + addi rg0, 0x30, rg0 + stb rg0, rg1 + addi rg1, 1 + jmp _end + +// ------------------------------------------ +// prints the value of arg[0] to the screen in hex. +print_hex_word: + push bpr + mov spr, bpr + + ldw bpr, rg0, 8 + ldw current, rg1 + + stw rg0, rg1 + addi rg1, 4 + jmp _end + // ------------------------------------------ // resets the cursor position on the screen to 0x20000. (0,0) reset: @@ -109,7 +161,7 @@ _clear_loop: // return _end: stw rg1, current - + mov bpr, spr pop bpr - return \ No newline at end of file + return diff --git a/resources/dsa/lib/maths/core.dsa b/resources/dsa/lib/maths/core.dsa new file mode 100644 index 0000000..217c5dc --- /dev/null +++ b/resources/dsa/lib/maths/core.dsa @@ -0,0 +1,60 @@ +// 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 2 + ldw bpr, rg1, 12 // load op 1 + +_multiply_loop: + add rg2, rg0, rg2 + dec rg1 + + cmp rg1, zero + jgt _multiply_loop + +_multiply_end: + stw rg2, bpr, 8 + + mov bpr, spr + pop bpr + return + +divmod: + push bpr + mov spr, bpr + + ldw bpr, rg1, 8 // load op 2 + ldw bpr, rg0, 12 // load op 1 + + lli 0, rg3 + +_divmod_loop: + cmp rg0, rg1 + jlt _divmod_end + + sub rg0, rg1, rg0 + inc rg3 + + jmp _divmod_loop + +_divmod_end: + // store div in first arg + // store mod in second arg + stw rg3, bpr, 8 + stw rg0, bpr, 12 + + mov bpr, spr + pop bpr + return diff --git a/resources/dsa/lib/fib.dsa b/resources/dsa/lib/maths/fib.dsa similarity index 100% rename from resources/dsa/lib/fib.dsa rename to resources/dsa/lib/maths/fib.dsa diff --git a/resources/dsa/lib/multiply.dsa b/resources/dsa/lib/multiply.dsa deleted file mode 100644 index 0e6cc40..0000000 --- a/resources/dsa/lib/multiply.dsa +++ /dev/null @@ -1,30 +0,0 @@ -// 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 - -start: - add acc, rg0, acc - dec rg1 - - cmp rg1, zero - jgt start - -end: - mov bpr, spr - pop bpr - return diff --git a/resources/dsa/test.dsa b/resources/dsa/test.dsa index a64d8e5..4dcbf94 100644 --- a/resources/dsa/test.dsa +++ b/resources/dsa/test.dsa @@ -1,7 +1,8 @@ -include print "./lib/print.dsa" +include print "./lib/io/print.dsa" +dw idt: 0xFFFF0000 dw stack: 0x10000 -db string: "Hello world" +db interrupt: "INT: Hello world" init: // set up a stack. @@ -9,10 +10,24 @@ init: mov bpr, spr start: - lwi string, rg1 + ldw idt, idr - push rg1 - call print::print - pop rg1 + lwi handle_hard_fault, rg0 + stw rg0, idr, 4 + + lli 0x20, rg0 + push rg0 + call print::print_hex_byte + pop zero + hlt + + +dw hard_fault_err: "FATAL: Illegal Instruction or Memory Access!" +handle_hard_fault: + call print::reset + lwi hard_fault_err, rg0 + push rg0 + call print::print + pop zero hlt diff --git a/resources/dsb/fib.dsb b/resources/dsb/fib.dsb deleted file mode 100644 index e69de29..0000000