AutoLang Standard Library File Organization Convention
Overview
As of Plan 036 implementation, AutoLang standard library uses file-based separation instead of section markers within files. This provides cleaner organization and better support for different compilation targets.
Status: ✅ ACTIVE (as of 2025-01-17)
Migration: Section markers (# AUTO, # VM, # C) have been removed from all split files
File Naming Convention
File Types
| Extension | Purpose | Loaded By | Example |
|---|---|---|---|
.at |
Common Auto code | All targets | io.at |
.vm.at |
VM-specific code | Interpreter only | io.vm.at |
.c.at |
C-specific code | C transpiler only | io.c.at |
Naming Pattern
For a module named module:
module.at- Common Auto code (business logic, types, methods)module.vm.at- VM-specific code (VM function declarations)module.c.at- C-specific code (C external functions, headers)
Loading Order
Critical: Files are loaded in a specific order to maintain dependency relationships.
Interpreter Mode
use io
// Loading order:
1. io.vm.at (bottom - VM function declarations)
2. io.at (top - business logic using VM functions)
C Transpiler Mode
use io
// Loading order:
1. io.c.at (bottom - C external function declarations)
2. io.at (top - business logic using C functions)
Why this order?
- Bottom files provide interfaces (function declarations)
- Top files implement features using those interfaces
- Follows "define bottom first, call from top" dependency pattern
File Content Guidelines
.at Files (Common Code)
Purpose: Business logic, algorithms, type declarations Loaded by: All compilation targets
What goes here:
- ✅ Type declarations
- ✅ Method implementations (Auto code)
- ✅ Helper functions
- ✅ Algorithms and business logic
- ✅
extstatements (adding methods to types)
What does NOT go here:
- ❌
fn.vmfunction declarations (use.vm.at) - ❌
fn.cexternal function declarations (use.c.at) - ❌
use.cC header imports (use.c.at) - ❌ Section markers (e.g.,
# AUTO,# VM,# C)
Example:
/// Common I/O functions and types
fn say(msg str) {
printf(c"%s\n", msg)
}
type File {
path str
file *FILE
// Auto-implemented method
fn read_all() str {
var result = ""
loop {
if .is_eof() {
break
}
let line = .read_line()
if line == "" {
break
}
if result != "" {
result = result.append(c"\n")
}
result = result.append(line)
}
result
}
// VM method declarations only
fn.vm read_line() str
fn.vm is_eof() bool
}
.vm.at Files (VM-Specific)
Purpose: VM function declarations (implemented in Rust) Loaded by: Interpreter only
What goes here:
- ✅
fn.vmfunction declarations - ✅ VM-specific type declarations (if any)
What does NOT go here:
- ❌ Business logic implementations (use
.at) - ❌ C function declarations (use
.c.at) - ❌ Section markers
Example:
// VM function declarations for I/O operations
// These are implemented in Rust in crates/auto-lang/src/libs/file.rs
fn.vm open(path str) File
fn.vm open_read(path str) File
fn.vm open_write(path str) File
fn.vm open_append(path str) File
.c.at Files (C-Specific)
Purpose: C external function declarations and C headers Loaded by: C transpiler only
What goes here:
- ✅
fn.cexternal function declarations - ✅
use.cC header imports - ✅ C-specific type declarations (if any)
What does NOT go here:
- ❌ Business logic implementations (use
.at) - ❌
fn.vmfunction declarations (use.vm.at) - ❌ Section markers
Example:
// C external function declarations for I/O operations
use.c <stdlib.h>
fn.c exit(status int) void
use.c <stdio.h>
fn.c printf(fmt cstr, arg cstr)
type.c FILE
fn.c fopen(path cstr, mode cstr) *FILE
fn.c fclose(stream *FILE) int
Legacy Section Markers (Deprecated)
❌ DO NOT Use Section Markers
Old approach (deprecated):
# io.at
# AUTO
fn add(a int, b int) int { a + b }
# VM
fn.vm subtract(a int, b int) int
# C
fn.c subtract(a int, b int) int
New approach (recommended):
// io.at (common code only)
fn add(a int, b int) int { a + b }
// io.vm.at (VM only)
fn.vm subtract(a int, b int) int
// io.c.at (C only)
fn.c subtract(a int, b int) int
Migration Status
✅ COMPLETED (2025-01-17):
- All section markers removed from split files
- No
# AUTO,# VM, or# Cmarkers in.at,.vm.at, or.c.atfiles - Documentation updated to reflect new convention
Current Standard Library Structure
stdlib/auto/
├── io.at # Common I/O types and methods
├── io.vm.at # VM function declarations for I/O
├── io.c.at # C external function declarations for I/O
├── math.at # Pure Auto math functions (no split needed)
├── str.at # String extension methods (ext statements)
├── sys.at # Common system functions
└── sys.c.at # C external function declarations for system
Notes
math.atandstr.atdon't have.vm.ator.c.atfiles because they're pure Auto code- Pure Auto modules don't need platform-specific implementations
- They use
fn.vmfor methods that need VM implementation, but don't need separate files
Best Practices
1. File Separation
When to split files:
- ✅ Module has both Auto and VM implementations → Create
.vm.at - ✅ Module has both Auto and C declarations → Create
.c.at - ✅ Module is pure Auto → Single
.atfile only
When NOT to split:
- ❌ Pure Auto modules (like
math.at,str.at) - ❌ Simple modules with no platform-specific code
2. Content Organization
Keep in .at files:
- Type declarations
- Auto method implementations
- Business logic
- Algorithms
Move to .vm.at:
fn.vmfunction declarations- VM-specific helper types
Move to .c.at:
fn.cexternal function declarationsuse.cheader imports- C-specific types
3. Documentation
- ✅ Document file purpose at the top of each file
- ✅ Use comments to explain non-obvious code
- ✅ Include examples for public APIs
- ❌ Don't use section markers (they're redundant)
Examples
Example 1: Simple Module (No Split)
File: math.at (single file)
/// Pure Auto math functions
/// No platform-specific code needed
fn abs(x int) int {
if x < 0 {
-x
} else {
x
}
}
fn min(a int, b int) int {
if a < b { a } else { b }
}
fn max(a int, b int) int {
if a > b { a } else { b }
}
Example 2: Module with VM Functions
Files: str.at (single file with fn.vm)
/// String extension methods
ext str {
// VM method (implemented in Rust)
fn.vm split(delimiter str) []str
// Auto method using VM method
fn word_count() int {
.words().len()
}
// Auto method with simple logic
fn is_empty() bool {
.size == 0
}
}
Note: Even though str.at has fn.vm declarations, it doesn't need a separate .vm.at file because all methods are logically grouped in the ext block.
Example 3: Module with Split Files
File: io.at (common code)
/// Common I/O functions and File type
fn say(msg str) {
printf(c"%s\n", msg)
}
type File {
path str
file *FILE
// Auto-implemented method
fn read_all() str {
// ... implementation using VM methods
}
// VM method declarations
fn.vm read_line() str
fn.vm is_eof() bool
}
File: io.vm.at (VM declarations)
/// VM function declarations for I/O
fn.vm open(path str) File
fn.vm open_read(path str) File
fn.vm open_write(path str) File
fn.vm open_append(path str) File
File: io.c.at (C declarations)
/// C external function declarations for I/O
use.c <stdlib.h>
fn.c exit(status int) void
use.c <stdio.h>
fn.c printf(fmt cstr, arg cstr)
type.c FILE
fn.c fopen(path cstr, mode cstr) *FILE
Migration Guide for New Modules
Step 1: Determine if Split is Needed
Ask yourself:
- Does this module need VM function declarations?
- Does this module need C external function declarations?
If both answers are "no": Create single module.at file
If either answer is "yes": Consider split files
Step 2: Create Files
If splitting:
- Create
module.atfor common Auto code - Create
module.vm.atif needed (VM declarations) - Create
module.c.atif needed (C declarations)
Step 3: Organize Content
In module.at:
- Add type declarations
- Add Auto method implementations
- Add helper functions
In module.vm.at (if exists):
- Add
fn.vmfunction declarations - Group related functions together
In module.c.at (if exists):
- Add
use.cheader imports - Add
fn.cexternal function declarations - Group related functions together
Step 4: Document
- Add file-level documentation
- Comment on non-obvious code
- Include usage examples
Step 5: Test
- Run interpreter:
auto run test.at - Run C transpiler:
auto c test.at - Verify both modes work correctly
Summary
Key Points:
- ✅ Section markers (
# AUTO,# VM,# C) are deprecated - ✅ Use file extensions instead:
.at,.vm.at,.c.at - ✅ Load order: Bottom first (
.vm.at/.c.at), then top (.at) - ✅ Pure Auto modules don't need split files
- ✅ Document purpose and organization
Benefits:
- Cleaner file organization
- Better separation of concerns
- Easier to maintain
- Clearer compilation target support
Related Documentation:
- Plan 036: Unified Auto Section - Implementation details
- stdlib-organization.md - User-facing tutorial