5e575e2cd8
DSC that we can follow as a reference for implementation.
1224 lines
24 KiB
Markdown
1224 lines
24 KiB
Markdown
# DSC Language Specification v1.0
|
|
|
|
**Damn Simple C (DSC)** - A systems programming language for the DSA architecture
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [Introduction](#introduction)
|
|
2. [Lexical Structure](#lexical-structure)
|
|
3. [Types](#types)
|
|
4. [Variables and Declarations](#variables-and-declarations)
|
|
5. [Classes](#classes)
|
|
6. [Functions](#functions)
|
|
7. [Expressions](#expressions)
|
|
8. [Statements](#statements)
|
|
9. [Control Flow](#control-flow)
|
|
10. [Memory Management](#memory-management)
|
|
11. [Generics](#generics)
|
|
12. [Modules and Imports](#modules-and-imports)
|
|
13. [Keywords](#keywords)
|
|
14. [Operators](#operators)
|
|
15. [Complete Example Programs](#complete-example-programs)
|
|
16. [Grammar Summary](#grammar-summary)
|
|
17. [Appendix A: Differences from Rust](#appendix-a-differences-from-rust)
|
|
18. [Appendix B: Standard Library Conventions](#appendix-b-standard-library-conventions)
|
|
|
|
---
|
|
|
|
## 1. Introduction
|
|
|
|
DSC is a statically-typed systems programming language designed for the DSA (Damn Simple Architecture). It combines modern syntax with explicit memory management and direct assembly interoperability.
|
|
|
|
### Design Goals
|
|
|
|
- **Explicit**: No hidden control flow or implicit conversions
|
|
- **Simple**: Easy to understand what the compiler generates
|
|
- **Safe**: Scope-based resource management via `defer`
|
|
- **Interoperable**: Direct assembly library integration
|
|
|
|
---
|
|
|
|
## 2. Lexical Structure
|
|
|
|
### 2.1 Comments
|
|
|
|
```rust
|
|
// Single-line comment
|
|
|
|
/* Multi-line
|
|
comment */
|
|
```
|
|
|
|
### 2.2 Identifiers
|
|
|
|
Identifiers must start with a letter or underscore, followed by any number of letters, digits, or underscores.
|
|
|
|
```rust
|
|
valid_identifier
|
|
_private
|
|
MyClass
|
|
get_value_42
|
|
```
|
|
|
|
### 2.3 Reserved Keywords
|
|
|
|
```
|
|
as break class const continue
|
|
defer else false field fn
|
|
if impl include let loop
|
|
mut priv pub return self
|
|
static struct true void while
|
|
```
|
|
|
|
### 2.4 Literals
|
|
|
|
#### Integer Literals
|
|
```rust
|
|
42 // Decimal
|
|
0x2A // Hexadecimal
|
|
0b101010 // Binary
|
|
0o52 // Octal
|
|
```
|
|
|
|
#### String Literals
|
|
```rust
|
|
"Hello, world!"
|
|
"Escape sequences: \n \t \\ \""
|
|
```
|
|
|
|
#### Boolean Literals
|
|
```rust
|
|
true
|
|
false
|
|
```
|
|
|
|
---
|
|
|
|
## 3. Types
|
|
|
|
### 3.1 Primitive Types
|
|
|
|
#### Integer Types
|
|
```rust
|
|
i8 // Signed 8-bit integer
|
|
i16 // Signed 16-bit integer
|
|
i32 // Signed 32-bit integer
|
|
i64 // Signed 64-bit integer
|
|
|
|
u8 // Unsigned 8-bit integer
|
|
u16 // Unsigned 16-bit integer
|
|
u32 // Unsigned 32-bit integer
|
|
u64 // Unsigned 64-bit integer
|
|
```
|
|
|
|
#### Boolean Type
|
|
```rust
|
|
bool // true or false
|
|
```
|
|
|
|
#### String Type
|
|
```rust
|
|
str // String literal type (pointer to null-terminated byte array)
|
|
```
|
|
|
|
#### Void Type
|
|
```rust
|
|
void // Absence of a value (only valid as return type)
|
|
```
|
|
|
|
### 3.2 Pointer Types
|
|
|
|
Pointers are declared using the `&` prefix:
|
|
|
|
```rust
|
|
&u32 // Pointer to u32
|
|
&bool // Pointer to bool
|
|
&Point // Pointer to Point class
|
|
```
|
|
|
|
**Note**: Pointers in DSC are raw memory addresses (like C pointers), not Rust-style references with borrow checking.
|
|
|
|
### 3.3 Array Types
|
|
|
|
```rust
|
|
[u32; 10] // Fixed-size array of 10 u32 values
|
|
[bool; 256] // Fixed-size array of 256 bool values
|
|
```
|
|
|
|
### 3.4 Generic Types
|
|
|
|
```rust
|
|
Vec<u32> // Generic type with one type parameter
|
|
Map<str, i32> // Generic type with multiple type parameters
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Variables and Declarations
|
|
|
|
### 4.1 Variable Declaration
|
|
|
|
Variables are declared with `let` and are immutable by default:
|
|
|
|
```rust
|
|
let x: u32 = 42;
|
|
let name: str = "Alice";
|
|
let ptr: &u32 = &x;
|
|
```
|
|
|
|
### 4.2 Mutable Variables
|
|
|
|
Use `mut` to declare mutable variables:
|
|
|
|
```rust
|
|
let mut count: u32 = 0;
|
|
count = count + 1;
|
|
```
|
|
|
|
### 4.3 Type Inference
|
|
|
|
Type annotations can be omitted when the type can be inferred:
|
|
|
|
```rust
|
|
let x = 42; // Inferred as u32 (default integer type)
|
|
let name = "Bob"; // Inferred as str
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Classes
|
|
|
|
Classes are DSC's primary means of encapsulation, combining data and behavior.
|
|
|
|
### 5.1 Class Definition
|
|
|
|
```rust
|
|
class ClassName {
|
|
// Class body
|
|
}
|
|
```
|
|
|
|
### 5.2 Fields
|
|
|
|
Fields represent the data members of a class. They must be explicitly marked as `pub` or `priv`:
|
|
|
|
```rust
|
|
class Point {
|
|
pub field x: u32;
|
|
pub field y: u32;
|
|
priv field cached: bool;
|
|
}
|
|
```
|
|
|
|
**Syntax**: `[pub|priv] field <name>: <type>;`
|
|
|
|
### 5.3 Constants
|
|
|
|
Constants are compile-time values associated with a class:
|
|
|
|
```rust
|
|
class Math {
|
|
pub const PI: u32 = 3;
|
|
pub const E: u32 = 2;
|
|
priv const INTERNAL_CONSTANT: u32 = 42;
|
|
}
|
|
```
|
|
|
|
**Syntax**: `[pub|priv] const <NAME>: <type> = <value>;`
|
|
|
|
**Usage**: `Math::PI`
|
|
|
|
### 5.4 Static Fields
|
|
|
|
Static fields are global variables associated with a class:
|
|
|
|
```rust
|
|
class Logger {
|
|
pub static mut INSTANCE_COUNT: u32 = 0;
|
|
priv static mut INTERNAL_STATE: u32 = 0;
|
|
}
|
|
```
|
|
|
|
**Syntax**: `[pub|priv] static mut <name>: <type> = <value>;`
|
|
|
|
**Usage**:
|
|
```rust
|
|
Logger::INSTANCE_COUNT = Logger::INSTANCE_COUNT + 1;
|
|
```
|
|
|
|
**Note**: All static fields must be declared `mut` as they represent mutable global state.
|
|
|
|
### 5.5 Methods
|
|
|
|
Methods are functions associated with a class. Instance methods take a `self` parameter:
|
|
|
|
```rust
|
|
class Point {
|
|
pub field x: u32;
|
|
pub field y: u32;
|
|
|
|
// Constructor (static method)
|
|
pub fn new(x: u32, y: u32) -> Point {
|
|
return Point { x: x, y: y };
|
|
}
|
|
|
|
// Instance method
|
|
pub fn get_x(self: &Point) -> u32 {
|
|
return self.x;
|
|
}
|
|
|
|
// Mutable instance method
|
|
pub fn set_x(self: &Point, value: u32) {
|
|
self.x = value;
|
|
}
|
|
|
|
// Static method
|
|
pub fn zero() -> Point {
|
|
return Point { x: 0, y: 0 };
|
|
}
|
|
}
|
|
```
|
|
|
|
**Method Syntax**:
|
|
- Instance method: `[pub|priv] fn <name>(self: &<ClassName>, ...) -> <return_type>`
|
|
- Static method: `[pub|priv] fn <name>(...) -> <return_type>`
|
|
|
|
### 5.6 Class Instantiation
|
|
|
|
```rust
|
|
// Using constructor
|
|
let p1: Point = Point::new(10, 20);
|
|
|
|
// Using struct literal syntax
|
|
let p2: Point = Point { x: 5, y: 15 };
|
|
```
|
|
|
|
### 5.7 Method Calls
|
|
|
|
```rust
|
|
let p: Point = Point::new(10, 20);
|
|
|
|
// Method call syntax (preferred)
|
|
let x: u32 = p.get_x();
|
|
|
|
// Explicit syntax (equivalent)
|
|
let x: u32 = Point::get_x(&p);
|
|
|
|
// Static method call
|
|
let origin: Point = Point::zero();
|
|
```
|
|
|
|
### 5.8 Field Access
|
|
|
|
```rust
|
|
let p: Point = Point { x: 10, y: 20 };
|
|
|
|
// Read field
|
|
let x: u32 = p.x;
|
|
|
|
// Write field (if mutable)
|
|
let mut p2: Point = Point { x: 0, y: 0 };
|
|
p2.x = 42;
|
|
```
|
|
|
|
### 5.9 Complete Class Example
|
|
|
|
```rust
|
|
class Vec {
|
|
priv field data: &u32;
|
|
priv field len: u32;
|
|
priv field capacity: u32;
|
|
|
|
pub const DEFAULT_CAPACITY: u32 = 16;
|
|
pub static mut TOTAL_ALLOCATIONS: u32 = 0;
|
|
|
|
pub fn new(capacity: u32) -> Vec {
|
|
Vec::TOTAL_ALLOCATIONS = Vec::TOTAL_ALLOCATIONS + 1;
|
|
return Vec {
|
|
data: alloc::malloc(capacity * 4) as &u32,
|
|
len: 0,
|
|
capacity: capacity
|
|
};
|
|
}
|
|
|
|
pub fn with_default_capacity() -> Vec {
|
|
return Vec::new(Vec::DEFAULT_CAPACITY);
|
|
}
|
|
|
|
pub fn push(self: &Vec, item: u32) {
|
|
if self.len == self.capacity {
|
|
self.grow();
|
|
}
|
|
*(self.data + self.len) = item;
|
|
self.len = self.len + 1;
|
|
}
|
|
|
|
pub fn get(self: &Vec, index: u32) -> u32 {
|
|
return *(self.data + index);
|
|
}
|
|
|
|
priv fn grow(self: &Vec) {
|
|
let new_capacity: u32 = self.capacity * 2;
|
|
let new_data: &u32 = alloc::malloc(new_capacity * 4) as &u32;
|
|
|
|
// Copy old data
|
|
let mut i: u32 = 0;
|
|
while i < self.len {
|
|
*(new_data + i) = *(self.data + i);
|
|
i = i + 1;
|
|
}
|
|
|
|
alloc::free(self.data as u32);
|
|
self.data = new_data;
|
|
self.capacity = new_capacity;
|
|
}
|
|
|
|
pub fn drop(self: &Vec) {
|
|
alloc::free(self.data as u32);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 6. Functions
|
|
|
|
### 6.1 Function Declaration
|
|
|
|
```rust
|
|
fn function_name(param1: Type1, param2: Type2) -> ReturnType {
|
|
// Function body
|
|
}
|
|
```
|
|
|
|
### 6.2 Return Type
|
|
|
|
Functions without a return value use `void` or omit the return type:
|
|
|
|
```rust
|
|
fn print_message(msg: str) -> void {
|
|
// No return value
|
|
}
|
|
|
|
// Equivalent
|
|
fn print_message(msg: str) {
|
|
// No return value
|
|
}
|
|
```
|
|
|
|
### 6.3 Return Statement
|
|
|
|
```rust
|
|
fn add(a: u32, b: u32) -> u32 {
|
|
return a + b;
|
|
}
|
|
```
|
|
|
|
### 6.4 Function Parameters
|
|
|
|
```rust
|
|
fn process(value: u32, ptr: &u32, flag: bool) -> u32 {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Expressions
|
|
|
|
### 7.1 Literals
|
|
|
|
```rust
|
|
42 // Integer literal
|
|
0xFF // Hex literal
|
|
true // Boolean literal
|
|
"hello" // String literal
|
|
```
|
|
|
|
### 7.2 Binary Operations
|
|
|
|
```rust
|
|
a + b // Addition
|
|
a - b // Subtraction
|
|
a * b // Multiplication
|
|
a / b // Division
|
|
a % b // Modulo
|
|
```
|
|
|
|
### 7.3 Comparison Operations
|
|
|
|
```rust
|
|
a == b // Equal
|
|
a != b // Not equal
|
|
a < b // Less than
|
|
a > b // Greater than
|
|
a <= b // Less than or equal
|
|
a >= b // Greater than or equal
|
|
```
|
|
|
|
### 7.4 Logical Operations
|
|
|
|
```rust
|
|
a && b // Logical AND
|
|
a || b // Logical OR
|
|
!a // Logical NOT
|
|
```
|
|
|
|
### 7.5 Bitwise Operations
|
|
|
|
```rust
|
|
a & b // Bitwise AND
|
|
a | b // Bitwise OR
|
|
a ^ b // Bitwise XOR
|
|
~a // Bitwise NOT
|
|
a << b // Left shift
|
|
a >> b // Right shift
|
|
```
|
|
|
|
### 7.6 Address-of and Dereference
|
|
|
|
```rust
|
|
&x // Address-of (get pointer to x)
|
|
*ptr // Dereference (read/write through pointer)
|
|
```
|
|
|
|
### 7.7 Type Casting
|
|
|
|
```rust
|
|
value as u32 // Cast value to u32
|
|
ptr as &u8 // Cast pointer type
|
|
```
|
|
|
|
### 7.8 Field Access
|
|
|
|
```rust
|
|
obj.field // Access field of object
|
|
ptr.field // Access field through pointer (implicit dereference)
|
|
```
|
|
|
|
### 7.9 Method Call
|
|
|
|
```rust
|
|
obj.method(args) // Instance method call
|
|
Class::method(args) // Static method call
|
|
```
|
|
|
|
### 7.10 Array Indexing
|
|
|
|
```rust
|
|
arr[index] // Access array element
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Statements
|
|
|
|
### 8.1 Expression Statement
|
|
|
|
```rust
|
|
function_call();
|
|
x = y + 1;
|
|
```
|
|
|
|
### 8.2 Variable Declaration
|
|
|
|
```rust
|
|
let x: u32 = 42;
|
|
let mut y: u32 = 0;
|
|
```
|
|
|
|
### 8.3 Assignment
|
|
|
|
```rust
|
|
x = 10;
|
|
*ptr = 20;
|
|
obj.field = 30;
|
|
arr[0] = 40;
|
|
```
|
|
|
|
### 8.4 Compound Assignment
|
|
|
|
```rust
|
|
x += 5; // x = x + 5
|
|
x -= 3; // x = x - 3
|
|
x *= 2; // x = x * 2
|
|
x /= 4; // x = x / 4
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Control Flow
|
|
|
|
### 9.1 If Statement
|
|
|
|
```rust
|
|
if condition {
|
|
// then block
|
|
}
|
|
|
|
if condition {
|
|
// then block
|
|
} else {
|
|
// else block
|
|
}
|
|
|
|
if condition1 {
|
|
// block 1
|
|
} else if condition2 {
|
|
// block 2
|
|
} else {
|
|
// block 3
|
|
}
|
|
```
|
|
|
|
### 9.2 While Loop
|
|
|
|
```rust
|
|
while condition {
|
|
// loop body
|
|
}
|
|
```
|
|
|
|
### 9.3 Loop (Infinite Loop)
|
|
|
|
```rust
|
|
loop {
|
|
// infinite loop
|
|
if should_exit {
|
|
break;
|
|
}
|
|
}
|
|
```
|
|
|
|
### 9.4 Break and Continue
|
|
|
|
```rust
|
|
while condition {
|
|
if skip_condition {
|
|
continue; // Skip to next iteration
|
|
}
|
|
|
|
if exit_condition {
|
|
break; // Exit loop
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Memory Management
|
|
|
|
### 10.1 Defer Statement
|
|
|
|
The `defer` keyword schedules a statement to execute when the current scope exits.
|
|
|
|
```rust
|
|
fn example() {
|
|
let ptr: u32 = alloc::malloc(256);
|
|
defer alloc::free(ptr);
|
|
|
|
// Use ptr...
|
|
|
|
if error {
|
|
return; // defer runs here
|
|
}
|
|
|
|
// More work...
|
|
|
|
} // defer runs here
|
|
```
|
|
|
|
### 10.2 Defer Execution Rules
|
|
|
|
1. **Scope-based**: Defers execute when their enclosing scope exits
|
|
2. **LIFO order**: Multiple defers execute in reverse order of declaration
|
|
3. **All exit paths**: Defers run on return, break, continue, or natural scope end
|
|
|
|
```rust
|
|
fn nested_defers() {
|
|
let a: u32 = alloc::malloc(100);
|
|
defer alloc::free(a); // Runs second
|
|
|
|
if condition {
|
|
let b: u32 = alloc::malloc(200);
|
|
defer alloc::free(b); // Runs first (if in this scope)
|
|
|
|
// ... work ...
|
|
|
|
} // b's defer runs here
|
|
|
|
// ... more work ...
|
|
|
|
} // a's defer runs here
|
|
```
|
|
|
|
### 10.3 Defer with Methods
|
|
|
|
```rust
|
|
class Resource {
|
|
priv field handle: u32;
|
|
|
|
pub fn acquire() -> Resource {
|
|
return Resource { handle: alloc::malloc(1024) };
|
|
}
|
|
|
|
pub fn release(self: &Resource) {
|
|
alloc::free(self.handle);
|
|
}
|
|
}
|
|
|
|
fn use_resource() {
|
|
let res: Resource = Resource::acquire();
|
|
defer res.release();
|
|
|
|
// Use resource...
|
|
|
|
} // res.release() automatically called
|
|
```
|
|
|
|
---
|
|
|
|
## 11. Generics
|
|
|
|
### 11.1 Generic Classes
|
|
|
|
```rust
|
|
class Box<T> {
|
|
priv field value: T;
|
|
|
|
pub fn new(value: T) -> Box<T> {
|
|
return Box { value: value };
|
|
}
|
|
|
|
pub fn get(self: &Box<T>) -> T {
|
|
return self.value;
|
|
}
|
|
|
|
pub fn set(self: &Box<T>, value: T) {
|
|
self.value = value;
|
|
}
|
|
}
|
|
```
|
|
|
|
### 11.2 Generic Usage
|
|
|
|
```rust
|
|
let int_box: Box<u32> = Box::new(42);
|
|
let str_box: Box<str> = Box::new("hello");
|
|
|
|
let value: u32 = int_box.get();
|
|
```
|
|
|
|
### 11.3 Multiple Type Parameters
|
|
|
|
```rust
|
|
class Pair<T, U> {
|
|
pub field first: T;
|
|
pub field second: U;
|
|
|
|
pub fn new(first: T, second: U) -> Pair<T, U> {
|
|
return Pair { first: first, second: second };
|
|
}
|
|
}
|
|
|
|
let p: Pair<u32, str> = Pair::new(42, "answer");
|
|
```
|
|
|
|
### 11.4 Generic Functions
|
|
|
|
```rust
|
|
fn swap<T>(a: &T, b: &T) {
|
|
let temp: T = *a;
|
|
*a = *b;
|
|
*b = temp;
|
|
}
|
|
|
|
let mut x: u32 = 1;
|
|
let mut y: u32 = 2;
|
|
swap(&x, &y);
|
|
```
|
|
|
|
### 11.5 Generic Constraints
|
|
|
|
**Note**: DSC does not support trait bounds or where clauses. Generic types are instantiated via monomorphization without constraints.
|
|
|
|
---
|
|
|
|
## 12. Modules and Imports
|
|
|
|
### 12.1 Assembly Imports
|
|
|
|
DSC can import assembly modules for low-level operations:
|
|
|
|
```rust
|
|
include print: "./lib/io/print.dsa";
|
|
include alloc: "./lib/memory/alloc.dsa";
|
|
```
|
|
|
|
**Syntax**: `include <namespace>: "<path>";`
|
|
|
|
### 12.2 Using Imported Functions
|
|
|
|
```rust
|
|
print::println("Hello, world!");
|
|
let ptr: u32 = alloc::malloc(256);
|
|
```
|
|
|
|
---
|
|
|
|
## 13. Keywords
|
|
|
|
### 13.1 Complete Keyword List
|
|
|
|
| Keyword | Purpose |
|
|
|---------|---------|
|
|
| `as` | Type casting |
|
|
| `break` | Exit loop |
|
|
| `class` | Class definition |
|
|
| `const` | Constant declaration |
|
|
| `continue` | Next loop iteration |
|
|
| `defer` | Defer statement execution |
|
|
| `else` | Alternative branch |
|
|
| `false` | Boolean literal |
|
|
| `field` | Class field declaration |
|
|
| `fn` | Function declaration |
|
|
| `if` | Conditional statement |
|
|
| `impl` | *Reserved for future use* |
|
|
| `include` | Import assembly module |
|
|
| `let` | Variable declaration |
|
|
| `loop` | Infinite loop |
|
|
| `mut` | Mutable binding |
|
|
| `priv` | Private visibility |
|
|
| `pub` | Public visibility |
|
|
| `return` | Return from function |
|
|
| `self` | Instance reference |
|
|
| `static` | Static field declaration |
|
|
| `struct` | *Reserved for future use* |
|
|
| `true` | Boolean literal |
|
|
| `void` | No return type |
|
|
| `while` | While loop |
|
|
|
|
---
|
|
|
|
## 14. Operators
|
|
|
|
### 14.1 Operator Precedence (Highest to Lowest)
|
|
|
|
| Precedence | Operators | Associativity |
|
|
|------------|-----------|---------------|
|
|
| 1 | `()` `[]` `.` `::` | Left to right |
|
|
| 2 | `!` `~` `&` `*` (unary) `-` (unary) | Right to left |
|
|
| 3 | `as` | Left to right |
|
|
| 4 | `*` `/` `%` | Left to right |
|
|
| 5 | `+` `-` | Left to right |
|
|
| 6 | `<<` `>>` | Left to right |
|
|
| 7 | `&` | Left to right |
|
|
| 8 | `^` | Left to right |
|
|
| 9 | `|` | Left to right |
|
|
| 10 | `==` `!=` `<` `>` `<=` `>=` | Left to right |
|
|
| 11 | `&&` | Left to right |
|
|
| 12 | `||` | Left to right |
|
|
| 13 | `=` `+=` `-=` `*=` `/=` | Right to left |
|
|
|
|
### 14.2 Operator Summary
|
|
|
|
#### Arithmetic Operators
|
|
```rust
|
|
+ Addition
|
|
- Subtraction
|
|
* Multiplication
|
|
/ Division
|
|
% Modulo
|
|
```
|
|
|
|
#### Comparison Operators
|
|
```rust
|
|
== Equal
|
|
!= Not equal
|
|
< Less than
|
|
> Greater than
|
|
<= Less than or equal
|
|
>= Greater than or equal
|
|
```
|
|
|
|
#### Logical Operators
|
|
```rust
|
|
&& Logical AND
|
|
|| Logical OR
|
|
! Logical NOT
|
|
```
|
|
|
|
#### Bitwise Operators
|
|
```rust
|
|
& Bitwise AND
|
|
| Bitwise OR
|
|
^ Bitwise XOR
|
|
~ Bitwise NOT
|
|
<< Left shift
|
|
>> Right shift
|
|
```
|
|
|
|
#### Memory Operators
|
|
```rust
|
|
& Address-of
|
|
* Dereference
|
|
```
|
|
|
|
#### Assignment Operators
|
|
```rust
|
|
= Assignment
|
|
+= Add and assign
|
|
-= Subtract and assign
|
|
*= Multiply and assign
|
|
/= Divide and assign
|
|
```
|
|
|
|
---
|
|
|
|
## 15. Complete Example Programs
|
|
|
|
### 15.1 Hello World
|
|
|
|
```rust
|
|
include print: "./lib/io/print.dsa";
|
|
|
|
fn main() -> void {
|
|
print::println("Hello, world!");
|
|
}
|
|
```
|
|
|
|
### 15.2 Vector Implementation
|
|
|
|
```rust
|
|
include alloc: "./lib/memory/alloc.dsa";
|
|
|
|
class Vec<T> {
|
|
priv field data: &T;
|
|
priv field len: u32;
|
|
priv field capacity: u32;
|
|
|
|
pub const DEFAULT_CAPACITY: u32 = 16;
|
|
|
|
pub fn new(capacity: u32) -> Vec<T> {
|
|
let size: u32 = capacity * 4; // Assume sizeof(T) = 4
|
|
return Vec {
|
|
data: alloc::malloc(size) as &T,
|
|
len: 0,
|
|
capacity: capacity
|
|
};
|
|
}
|
|
|
|
pub fn push(self: &Vec<T>, item: T) {
|
|
if self.len >= self.capacity {
|
|
self.resize();
|
|
}
|
|
*(self.data + self.len) = item;
|
|
self.len = self.len + 1;
|
|
}
|
|
|
|
pub fn get(self: &Vec<T>, index: u32) -> T {
|
|
return *(self.data + index);
|
|
}
|
|
|
|
pub fn len(self: &Vec<T>) -> u32 {
|
|
return self.len;
|
|
}
|
|
|
|
priv fn resize(self: &Vec<T>) {
|
|
let new_capacity: u32 = self.capacity * 2;
|
|
let new_size: u32 = new_capacity * 4;
|
|
let new_data: &T = alloc::malloc(new_size) as &T;
|
|
|
|
let mut i: u32 = 0;
|
|
while i < self.len {
|
|
*(new_data + i) = *(self.data + i);
|
|
i = i + 1;
|
|
}
|
|
|
|
alloc::free(self.data as u32);
|
|
self.data = new_data;
|
|
self.capacity = new_capacity;
|
|
}
|
|
|
|
pub fn drop(self: &Vec<T>) {
|
|
alloc::free(self.data as u32);
|
|
}
|
|
}
|
|
|
|
fn main() -> void {
|
|
let vec: Vec<u32> = Vec::new(10);
|
|
defer vec.drop();
|
|
|
|
vec.push(1);
|
|
vec.push(2);
|
|
vec.push(3);
|
|
|
|
let mut i: u32 = 0;
|
|
while i < vec.len() {
|
|
let value: u32 = vec.get(i);
|
|
// Use value...
|
|
i = i + 1;
|
|
}
|
|
}
|
|
```
|
|
|
|
### 15.3 Resource Management Example
|
|
|
|
```rust
|
|
include alloc: "./lib/memory/alloc.dsa";
|
|
include print: "./lib/io/print.dsa";
|
|
|
|
class File {
|
|
priv field handle: u32;
|
|
priv field is_open: bool;
|
|
|
|
pub fn open(path: str) -> File {
|
|
let handle: u32 = 0; // Platform-specific open
|
|
return File { handle: handle, is_open: true };
|
|
}
|
|
|
|
pub fn write(self: &File, data: str) {
|
|
if !self.is_open {
|
|
return;
|
|
}
|
|
// Write implementation...
|
|
}
|
|
|
|
pub fn close(self: &File) {
|
|
if self.is_open {
|
|
// Platform-specific close
|
|
self.is_open = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
fn process_file(path: str) -> bool {
|
|
let file: File = File::open(path);
|
|
defer file.close(); // Ensures file is closed on all exit paths
|
|
|
|
let buffer: u32 = alloc::malloc(1024);
|
|
defer alloc::free(buffer);
|
|
|
|
if !file.is_open {
|
|
print::println("Failed to open file");
|
|
return false; // Defers run: free(buffer), file.close()
|
|
}
|
|
|
|
file.write("Hello, file!");
|
|
|
|
return true; // Defers run: free(buffer), file.close()
|
|
}
|
|
|
|
fn main() -> void {
|
|
let success: bool = process_file("output.txt");
|
|
|
|
if success {
|
|
print::println("File processed successfully");
|
|
} else {
|
|
print::println("File processing failed");
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 16. Grammar Summary
|
|
|
|
### 16.1 EBNF Grammar
|
|
|
|
```ebnf
|
|
program = { import_statement | class_definition | function_definition }
|
|
|
|
import_statement = "include" identifier ":" string_literal ";"
|
|
|
|
class_definition = "class" identifier [ generic_params ] "{" { class_member } "}"
|
|
|
|
class_member = field_declaration
|
|
| const_declaration
|
|
| static_declaration
|
|
| method_declaration
|
|
|
|
field_declaration = visibility "field" identifier ":" type ";"
|
|
|
|
const_declaration = visibility "const" IDENTIFIER ":" type "=" expression ";"
|
|
|
|
static_declaration = visibility "static" "mut" identifier ":" type "=" expression ";"
|
|
|
|
method_declaration = visibility "fn" identifier [ generic_params ] "(" parameters ")" [ "->" type ] block
|
|
|
|
function_definition = "fn" identifier [ generic_params ] "(" parameters ")" [ "->" type ] block
|
|
|
|
generic_params = "<" identifier { "," identifier } ">"
|
|
|
|
parameters = [ parameter { "," parameter } ]
|
|
|
|
parameter = identifier ":" type
|
|
|
|
visibility = "pub" | "priv"
|
|
|
|
type = primitive_type
|
|
| pointer_type
|
|
| array_type
|
|
| generic_type
|
|
| identifier
|
|
|
|
primitive_type = "u8" | "u16" | "u32" | "u64"
|
|
| "i8" | "i16" | "i32" | "i64"
|
|
| "bool" | "str" | "void"
|
|
|
|
pointer_type = "&" type
|
|
|
|
array_type = "[" type ";" integer_literal "]"
|
|
|
|
generic_type = identifier "<" type { "," type } ">"
|
|
|
|
block = "{" { statement } "}"
|
|
|
|
statement = let_statement
|
|
| expression_statement
|
|
| if_statement
|
|
| while_statement
|
|
| loop_statement
|
|
| return_statement
|
|
| defer_statement
|
|
| break_statement
|
|
| continue_statement
|
|
|
|
let_statement = "let" [ "mut" ] identifier ":" type "=" expression ";"
|
|
|
|
defer_statement = "defer" expression ";"
|
|
|
|
if_statement = "if" expression block [ "else" ( if_statement | block ) ]
|
|
|
|
while_statement = "while" expression block
|
|
|
|
loop_statement = "loop" block
|
|
|
|
return_statement = "return" [ expression ] ";"
|
|
|
|
break_statement = "break" ";"
|
|
|
|
continue_statement = "continue" ";"
|
|
|
|
expression_statement = expression ";"
|
|
|
|
expression = assignment_expression
|
|
|
|
assignment_expression = logical_or_expression [ assignment_operator assignment_expression ]
|
|
|
|
assignment_operator = "=" | "+=" | "-=" | "*=" | "/="
|
|
|
|
logical_or_expression = logical_and_expression { "||" logical_and_expression }
|
|
|
|
logical_and_expression = equality_expression { "&&" equality_expression }
|
|
|
|
equality_expression = relational_expression { equality_operator relational_expression }
|
|
|
|
equality_operator = "==" | "!="
|
|
|
|
relational_expression = bitwise_or_expression { relational_operator bitwise_or_expression }
|
|
|
|
relational_operator = "<" | ">" | "<=" | ">="
|
|
|
|
bitwise_or_expression = bitwise_xor_expression { "|" bitwise_xor_expression }
|
|
|
|
bitwise_xor_expression = bitwise_and_expression { "^" bitwise_and_expression }
|
|
|
|
bitwise_and_expression = shift_expression { "&" shift_expression }
|
|
|
|
shift_expression = additive_expression { shift_operator additive_expression }
|
|
|
|
shift_operator = "<<" | ">>"
|
|
|
|
additive_expression = multiplicative_expression { additive_operator multiplicative_expression }
|
|
|
|
additive_operator = "+" | "-"
|
|
|
|
multiplicative_expression = cast_expression { multiplicative_operator cast_expression }
|
|
|
|
multiplicative_operator = "*" | "/" | "%"
|
|
|
|
cast_expression = unary_expression [ "as" type ]
|
|
|
|
unary_expression = postfix_expression
|
|
| unary_operator unary_expression
|
|
|
|
unary_operator = "!" | "~" | "&" | "*" | "-"
|
|
|
|
postfix_expression = primary_expression { postfix_operator }
|
|
|
|
postfix_operator = "." identifier [ call_suffix ]
|
|
| "::" identifier [ call_suffix ]
|
|
| "[" expression "]"
|
|
| call_suffix
|
|
|
|
call_suffix = "(" [ arguments ] ")"
|
|
|
|
arguments = expression { "," expression }
|
|
|
|
primary_expression = identifier
|
|
| literal
|
|
| "(" expression ")"
|
|
| struct_literal
|
|
|
|
struct_literal = identifier "{" [ field_init { "," field_init } ] "}"
|
|
|
|
field_init = identifier ":" expression
|
|
|
|
literal = integer_literal
|
|
| string_literal
|
|
| boolean_literal
|
|
|
|
boolean_literal = "true" | "false"
|
|
```
|
|
|
|
---
|
|
|
|
## Appendix A: Differences from Rust
|
|
|
|
While DSC uses Rust-like syntax, there are key differences:
|
|
|
|
| Feature | Rust | DSC |
|
|
|---------|------|-----|
|
|
| **Encapsulation** | `struct` + `impl` | `class` |
|
|
| **Field syntax** | `field: Type` | `field field: Type;` |
|
|
| **References** | Borrow-checked `&T` | Raw pointers `&T` |
|
|
| **Ownership** | Compile-time borrow checker | Manual with `defer` |
|
|
| **Traits** | Supported | Not supported |
|
|
| **Lifetimes** | Supported | Not supported |
|
|
| **Pattern matching** | Supported | Not supported |
|
|
| **Enums** | Sum types with data | Not yet supported |
|
|
| **Modules** | Native | Assembly imports only |
|
|
|
|
---
|
|
|
|
## Appendix B: Standard Library Conventions
|
|
|
|
By convention, standard library modules should provide:
|
|
|
|
### Allocation Module (`alloc`)
|
|
```rust
|
|
include alloc: "./lib/memory/alloc.dsa";
|
|
|
|
// Functions:
|
|
// alloc::malloc(size: u32) -> u32
|
|
// alloc::free(ptr: u32) -> void
|
|
```
|
|
|
|
### Print Module (`print`)
|
|
```rust
|
|
include print: "./lib/io/print.dsa";
|
|
|
|
// Functions:
|
|
// print::print(msg: str) -> void
|
|
// print::println(msg: str) -> void
|
|
// print::print_num(n: u32) -> void
|
|
// print::print_hex(n: u32) -> void
|
|
```
|
|
|
|
---
|
|
|
|
*End of DSC Language Specification v1.0*
|