added custom syntax for DSA, minor changes to doc formatting

This commit is contained in:
2025-06-27 22:45:39 +01:00
parent afb2761a2b
commit 790bc597d3
12 changed files with 2900 additions and 110 deletions
+2 -1
View File
@@ -1,2 +1,3 @@
/target
**/*.env
book book
target
+15
View File
@@ -0,0 +1,15 @@
{
"rust-analyzer.check.command": "clippy",
"editor.formatOnSave": true,
"rust-analyzer.cargo.features": "all",
"files.eol": "\n",
"files.insertFinalNewline": true,
"files.trimFinalNewlines": true,
"files.trimTrailingWhitespace": true,
"gitea.owner": "LowLevelDevs",
"gitea.repo": "damn_simple_architecture",
"[markdown]": {
"editor.formatOnSave": true,
"editor.formatOnPaste": true
}
}
+1 -1
View File
@@ -29,4 +29,4 @@
- [DSC - Damn Simple Code](dsc.md) - [DSC - Damn Simple Code](dsc.md)
- [Functions](dsc/functions.md) - [Functions](dsc/functions.md)
- [Other Language Support](misc_languages.md) - [Other Language Support](misc_languages.md)
- [Brainf*](misc_languages/brainf.md) - [Brainf##k](misc_languages/brainf__k.md)
-1
View File
@@ -1,6 +1,5 @@
# Examples # Examples
## Library Examples ## Library Examples
### Multiplication Library (multiply.dsa) ### Multiplication Library (multiply.dsa)
+9 -5
View File
@@ -1,6 +1,6 @@
# Data Directives # Data Directives
### Data Definition ## Data Definition
| Mnemonic | Syntax | Description | | Mnemonic | Syntax | Description |
|----------|--------|-------------| |----------|--------|-------------|
@@ -9,6 +9,7 @@
| **DW** | `name: value1 [, value2, ...]` | Define words</br>*(4 byte aligned)*| | **DW** | `name: value1 [, value2, ...]` | Define words</br>*(4 byte aligned)*|
**Examples:** **Examples:**
```dsa ```dsa
db message: "Hello World", 0, 0x20, 231 db message: "Hello World", 0, 0x20, 231
dh numbers: 1000, 2000, 3000 dh numbers: 1000, 2000, 3000
@@ -16,10 +17,10 @@ dw stack: 0x10000
``` ```
**Notes:** **Notes:**
- All string literals are automatically *null-terminated*
-
### Memory Reservation - All string literals are automatically *null-terminated*
## Memory Reservation
| Mnemonic | Syntax | Description | | Mnemonic | Syntax | Description |
|----------|--------|-------------| |----------|--------|-------------|
@@ -28,14 +29,17 @@ dw stack: 0x10000
| **RESW** | `name: size` | Reserve words | | **RESW** | `name: size` | Reserve words |
**Examples:** **Examples:**
```dsa ```dsa
resb buffer: 256 ; Reserve 256 bytes resb buffer: 256 ; Reserve 256 bytes
resh array: 100 ; Reserve space for 100 half-words resh array: 100 ; Reserve space for 100 half-words
resw heap: 1024 ; Reserve space for 1024 words resw heap: 1024 ; Reserve space for 1024 words
``` ```
### Imports ## Imports
| Mnemonic | Syntax | Description | | Mnemonic | Syntax | Description |
|----------|--------|-------------| |----------|--------|-------------|
| **INCLUDE** | `module_name "path"` | Include module symbols | | **INCLUDE** | `module_name "path"` | Include module symbols |
[More details on the module System](../imports.md) [More details on the module System](../imports.md)
+94 -72
View File
@@ -1,6 +1,6 @@
# Hardware Instructions # Hardware Instructions
### Data Movement Instructions ## Data Movement Instructions
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
|----------|----------|-------------| |----------|----------|-------------|
@@ -10,96 +10,105 @@
**Examples:** **Examples:**
```dsa ```dsa
mov rg0, rg1 ; Copy rg0 to rg1 mov rg0, rg1 // Copy rg0 to rg1
movs rg0, rg1 ; Copy rg0 to rg1 with sign extension movs rg0, rg1 // Copy rg0 to rg1 with sign extension
``` ```
### Memory Access Instructions ## Memory Access Instructions
#### Load Instructions ### Load Instructions
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
|----------|----------|-------------| |----------|----------|-------------|
| **LDB** | `base_reg, dest_reg [, offset]`<br>`label, dest_reg [, offset]` | Load byte from memory | | **LDB** | `base_reg, dest_reg [, offset]`</br>`label, dest_reg [, offset]` | Load byte from memory |
| **LDBS** | `base_reg, dest_reg [, offset]`<br>`label, dest_reg [, offset]` | Load byte with sign extension | | **LDBS** | `base_reg, dest_reg [, offset]`</br>`label, dest_reg [, offset]` | Load byte with sign extension |
| **LDH** | `base_reg, dest_reg [, offset]`<br>`label, dest_reg [, offset]` | Load half-word (16-bit) | | **LDH** | `base_reg, dest_reg [, offset]`</br>`label, dest_reg [, offset]` | Load half-word (16-bit) |
| **LDHS** | `base_reg, dest_reg [, offset]`<br>`label, dest_reg [, offset]` | Load half-word with sign extension | | **LDHS** | `base_reg, dest_reg [, offset]`</br>`label, dest_reg [, offset]` | Load half-word with sign extension |
| **LDW** | `base_reg, dest_reg [, offset]`<br>`label, dest_reg [, offset]` | Load word (32-bit) | | **LDW** | `base_reg, dest_reg [, offset]`</br>`label, dest_reg [, offset]` | Load word (32-bit) |
**Examples:** **Examples:**
```dsa ```dsa
; Direct register addressing // Direct register addressing
ldb rg0, rg1 ; Load byte from address in rg0 ldb rg0, rg1 // Load byte from address in rg0
ldw rg0, rg1, 8 ; Load word from (rg0 + 8) ldw rg0, rg1, 8 // Load word from (rg0 + 8)
; Label addressing // Label addressing
ldb buffer, rg2 ; Load byte from label 'buffer' ldb buffer, rg2 // Load byte from label 'buffer'
ldw stack, bpr ; Load stack address into base pointer ldw stack, bpr // Load stack address into base pointer
``` ```
**Label Expansions:** **Label Expansions:**
```dsa
; 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: ```dsa
lli stack, bpr ; Load lower 16 bits of stack address // ldb buffer, rg2 expands to:
lui stack, bpr ; Load upper 16 bits of stack address lli buffer, rg2 // Load lower 16 bits of buffer address
ldw bpr, bpr ; Load word from address in bpr 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
### Store Instructions
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
|----------|----------|-------------| |----------|----------|-------------|
| **STB** | `src_reg, base_reg [, offset]`<br>`src_reg, label [, offset]` | Store byte to memory | | **STB** | `src_reg, base_reg [, offset]`</br>`src_reg, label [, offset]` | Store byte to memory |
| **STH** | `src_reg, base_reg [, offset]`<br>`src_reg, label [, offset]` | Store half-word to memory | | **STH** | `src_reg, base_reg [, offset]`</br>`src_reg, label [, offset]` | Store half-word to memory |
| **STW** | `src_reg, base_reg [, offset]`<br>`src_reg, label [, offset]` | Store word to memory | | **STW** | `src_reg, base_reg [, offset]`</br>`src_reg, label [, offset]` | Store word to memory |
**Examples:** **Examples:**
```dsa
; 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 ```dsa
stb acc, buffer ; Store byte from accumulator to 'buffer' // Direct register addressing
stw rg1, current ; Store word to 'current' variable 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:** **Label Expansions:**
```dsa
; 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: ```dsa
lli current, rgf ; Load lower 16 bits of current address // stb acc, buffer expands to:
lui current, rgf ; Load upper 16 bits of current address lli buffer, rgf // Load lower 16 bits of buffer address
stw rg1, rgf ; Store word from rg1 to address in rgf 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 ### Immediate Load Instructions
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
|----------|----------|------------------------------------------------------------------------| |----------|----------|------------------------------------------------------------------------|
| **LLI** | `imm, dest_reg` | Load 16-bit immediate into lower 16 bits<br/>**Clears upper 16 bits!** | | **LLI** | `imm, dest_reg` | Load 16-bit immediate into lower 16 bits</br>**Clears upper 16 bits!** |
| **LUI** | `imm, dest_reg` | Load 16-bit immediate into upper 16 bits | | **LUI** | `imm, dest_reg` | Load 16-bit immediate into upper 16 bits |
**Usage** **Usage:**
ensure that you always run **Lli** before **Lui** as **Lli** clears the upper 16 bits. Ensure that you always run **Lli** before **Lui** as **Lli** clears the upper 16 bits.
**Examples:** **Examples:**
```dsa ```dsa
lli 0x1234, rg0 ; Load 0x1234 into lower 16 bits of rg0 lli 0x1234, rg0 // Load 0x1234 into lower 16 bits of rg0
lui 0xABCD, rg0 ; Load 0xABCD into upper 16 bits of rg0 lui 0xABCD, rg0 // Load 0xABCD into upper 16 bits of rg0
``` ```
### Jump Instructions ### Jump Instructions
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
|----------|----------|-------------| |----------|----------|-------------|
| **JMP** | `addr [, offset_reg]`<br>`imm, offset_reg` | Unconditional jump | | **JMP** | `addr [, offset_reg]`</br>`imm, offset_reg` | Unconditional jump |
| **JEQ** | `addr [, offset_reg]` | Jump if equal flag set | | **JEQ** | `addr [, offset_reg]` | Jump if equal flag set |
| **JNE** | `addr [, offset_reg]` | Jump if not equal flag set | | **JNE** | `addr [, offset_reg]` | Jump if not equal flag set |
| **JGT** | `addr [, offset_reg]` | Jump if greater than flag set | | **JGT** | `addr [, offset_reg]` | Jump if greater than flag set |
@@ -108,13 +117,17 @@ lui 0xABCD, rg0 ; Load 0xABCD into upper 16 bits of rg0
| **JLE** | `addr [, offset_reg]` | Jump if less or equal flags set | | **JLE** | `addr [, offset_reg]` | Jump if less or equal flags set |
**Examples:** **Examples:**
```dsa ```dsa
jmp start ; Jump to label 'start' jmp start // Jump to label 'start'
jmp 4, ret ; Jump to address (4 + ret register) jmp 4, ret // Jump to address (4 + ret register)
jeq end ; Jump to 'end' if equal flag set jeq end // Jump to 'end' if equal flag set
jgt loop ; Jump to 'loop' if greater than flag set jgt loop // Jump to 'loop' if greater than flag set
``` ```
### Arithmetic Instructions
### Arithmetic & Logical Instructions
## Arithmetic Instructions
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
|----------|----------|-------------| |----------|----------|-------------|
@@ -126,15 +139,17 @@ jgt loop ; Jump to 'loop' if greater than flag set
| **DEC** | `reg` | Decrement register by 1 | | **DEC** | `reg` | Decrement register by 1 |
**Examples:** **Examples:**
```dsa ```dsa
add rg0, rg1, rg2 ; rg2 = rg0 + rg1 add rg0, rg1, rg2 // rg2 = rg0 + rg1
sub rg0, rg1, rg2 ; rg2 = rg0 - rg1 sub rg0, rg1, rg2 // rg2 = rg0 - rg1
iadd rg0, 10 ; rg0 = rg0 + 10 iadd rg0, 10 // rg0 = rg0 + 10
// or using alternate syntax // or using alternate syntax
addi rg0, 1 ; rg0 = rg0 + 1 addi rg0, 1 // rg0 = rg0 + 1
inc rg0 ; rg0 = rg0 + 1 inc rg0 // rg0 = rg0 + 1
``` ```
### Bitwise Operations
## Bitwise Operations
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
|----------|----------|-------------| |----------|----------|-------------|
@@ -147,11 +162,13 @@ inc rg0 ; rg0 = rg0 + 1
| **XNOR** | `src1_reg, src2_reg, dest_reg` | Bitwise XNOR | | **XNOR** | `src1_reg, src2_reg, dest_reg` | Bitwise XNOR |
**Examples:** **Examples:**
```dsa ```dsa
and rg0, rg1, rg2 ; rg2 = rg0 & rg1 and rg0, rg1, rg2 // rg2 = rg0 & rg1
not rg0, rg1 ; rg1 = ~rg0 not rg0, rg1 // rg1 = ~rg0
``` ```
### Shift Operations
## Shift Operations
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
|----------|----------|-------------| |----------|----------|-------------|
@@ -159,21 +176,25 @@ not rg0, rg1 ; rg1 = ~rg0
| **SHR** | `reg, shift_amount` | Shift right | | **SHR** | `reg, shift_amount` | Shift right |
**Examples:** **Examples:**
```dsa ```dsa
shl rg0, 2 ; Shift rg0 left by 2 bits shl rg0, 2 // Shift rg0 left by 2 bits
shr rg0, 3 ; Shift rg0 right by 3 bits shr rg0, 3 // Shift rg0 right by 3 bits
``` ```
### Comparison and Control
## Comparison and Control
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
|----------|----------|-------------| |----------|----------|-------------|
| **CMP** | `reg1, reg2` | Compare registers and set flags | | **CMP** | `reg1, reg2` | Compare registers and set flags |
**Examples:** **Examples:**
```dsa ```dsa
cmp rg0, zero ; Compare rg0 with zero register cmp rg0, zero // Compare rg0 with zero register
cmp rg1, rg2 ; Compare rg1 with rg2 cmp rg1, rg2 // Compare rg1 with rg2
``` ```
### System Instructions ### System Instructions
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
@@ -184,7 +205,8 @@ cmp rg1, rg2 ; Compare rg1 with rg2
| **IRT** | - | Return from interrupt | | **IRT** | - | Return from interrupt |
**Examples:** **Examples:**
```dsa ```dsa
hlt ; Stop processor execution hlt // Stop processor execution
int 0x21 ; Trigger interrupt 0x21 int 0x21 // Trigger interrupt 0x21
``` ```
+5 -2
View File
@@ -1,6 +1,6 @@
# Pseudo Instructions # Pseudo Instructions
### Stack Operations ## Stack Operations
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
|----------|----------|-------------| |----------|----------|-------------|
@@ -8,17 +8,20 @@
| **POP** | `reg` | Pop stack value into register | | **POP** | `reg` | Pop stack value into register |
**Examples:** **Examples:**
```dsa ```dsa
push rg0 ; Push rg0 value onto stack push rg0 ; Push rg0 value onto stack
pop ret ; Pop return address pop ret ; Pop return address
``` ```
### Memory Access Shortcuts
## Memory Access Shortcuts
| Mnemonic | Operands | Description | | Mnemonic | Operands | Description |
|----------|----------|-------------| |----------|----------|-------------|
| **LWI** | `name, reg` | Load address into register | | **LWI** | `name, reg` | Load address into register |
**Examples:** **Examples:**
```dsa ```dsa
lwi string, rg1 ; Load address of 'string' into rg1 lwi string, rg1 ; Load address of 'string' into rg1
``` ```
+11 -1
View File
@@ -3,10 +3,20 @@
## Tooling Options ## Tooling Options
### Assembler ### Assembler
- The assembler is the program that translates assembly code into machine code. - The assembler is the program that translates assembly code into machine code.
- It is the only tool required to build DSA assembly language programs. - It is the only tool required to build DSA assembly language programs.
- The assembler also works as a library that can be called from applications such as the emulator - The assembler also works as a library that can be called from applications such as the emulator
### Our Tooling: ### Our Tooling
- [Assembler](assembler.md) - [Assembler](assembler.md)
- [Syntax Tooling](syntax_tooling.md) - [Syntax Tooling](syntax_tooling.md)
```rust
fn main() {
println!("Hello, world!");
}
```
+10 -14
View File
@@ -1,20 +1,16 @@
# DSC - Damn Simple Code # DSC - Damn Simple Code</br>(This document is a work in progress</br>Nothing is final)
# This document is a work in progress!
# Nothing is final!
## Syntax ## Syntax
- we aim to make the syntax simple and easy to understand, this has the following benefits - we aim to make the syntax simple and easy to understand, this has the following benefits
- easy to write - easy to write
- easy to parse - easy to parse
- little variation in syntax means we have to handle less cases in semantic analysis, meaning we will be able to create a working compiler quicker. - little variation in syntax means we have to handle less cases in semantic analysis, meaning we will be able to create a working compiler quicker.
## Types ## Types
- we should support the following types - we should support the following types
- unsigned integer types (U8, U16, U32) - unsigned integer types (U8, U16, U32)
- signed integer types (I8, I16, I32) - signed integer types (I8, I16, I32)
- boolean type (Bool) - boolean type (Bool)
- struct types (Struct) - custom struct & dynamic types (Struct)
- dynamic types *(Dyn)
-
@@ -1,8 +1,8 @@
# Brainf* # Brainf##k
## Language overview ## Language overview
- Brainf* instructions are as follows: - Brainf##k instructions are as follows:
| Instruction | Description | | Instruction | Description |
| --- | --- | | --- | --- |
@@ -16,21 +16,28 @@
| `]` | Jump to the instruction after the matching `[` if the value in the current memory cell is non-zero | | `]` | Jump to the instruction after the matching `[` if the value in the current memory cell is non-zero |
## Implementations ## Implementations
we currently have two implementations of the brainf* esoteric programming language:
we currently have two implementations of the brainf##k esoteric programming language:
### Compiler ### Compiler
- this is the most efficient way to run brainf* programs on the DSA architecture, but of course, still terribly inefficient due to the nature of the language.
- compiling allows us to calculate the jump addresses at compile time, therefore making each brainf* instruction take at maximum three DSA instructions to execute - this is the most efficient way to run brainf##k programs on the DSA architecture, but of course, still terribly inefficient due to the nature of the language.
- compiling allows us to calculate the jump addresses at compile time, therefore making each brainf##k instruction take at maximum three DSA instructions to execute
### Interpreter ### Interpreter
- this method is much slower, with even jumping to the start of a loop having an O(n) time complexity, which depending on the complexity of the program can up to double the running time. - this method is much slower, with even jumping to the start of a loop having an O(n) time complexity, which depending on the complexity of the program can up to double the running time.
- additionally, interpreting the language means much more logic is required at runtime relative to compiling. - additionally, interpreting the language means much more logic is required at runtime relative to compiling.
- from our testing on a few example programs such as a fibonacci sequence generator, the interpreter is several orders of magnitude slower, with the fibonacci generator beingabout 10 times slower than it's compiled equivalent, at around 3.8 million instructions to generate and pretty-print the first 16 fibonacci numbers, compared to around 350,000 for the compiled version, which we estimate is about as efficient as brainf* can be on our architecture without writing an optimiser. - from our testing on a few example programs such as a fibonacci sequence generator, the interpreter is several orders of magnitude slower, with the fibonacci generator beingabout 10 times slower than it's compiled equivalent, at around 3.8 million instructions to generate and pretty-print the first 16 fibonacci numbers, compared to around 350,000 for the compiled version, which we estimate is about as efficient as brainf##k can be on our architecture without writing an optimiser.
## Usage ## Usage
### Compiling ### Compiling
- currently [The DSA Assembler](../dsa/tooling/assembler.md) supports compiling brainf* programs, with the following command:
- currently [The DSA Assembler](../dsa/tooling/assembler.md) supports compiling brainf##k programs, with the following command:
```bash ```bash
<assembler binary name> -brainf <assembler binary name> -brainf
``` ```
test
+3
View File
@@ -0,0 +1,3 @@
.hljs-keyword {
color: #1eff00;
}
+2730
View File
File diff suppressed because it is too large Load Diff