SmashLang is a JavaScript-inspired programming language that compiles to native binaries. It aims to provide the clarity and ease of use of JavaScript with the performance of languages like C and Rust, without the bloat. This document outlines the architecture, coding standards, and contribution guidelines for SmashLang.
smashlang/
├── src/ # Source code
│ ├── lexer.rs # Tokenization of source code
│ ├── parser.rs # Parsing tokens into AST
│ ├── compiler.rs # Compiling AST to LLVM IR
│ ├── repl.rs # Interactive REPL implementation
│ ├── main.rs # Main entry point for the `smash` binary
│ ├── smashpkg.rs # Package manager implementation
│ ├── smashc.rs # Standalone compiler implementation
│ └── lib.rs # Library exports
├── assets/ # Static assets (logos, etc.)
├── scripts/ # Utility scripts
├── install.sh # Cross-platform installer
└── Cargo.toml # Rust package definition
SmashLang follows a traditional compiler pipeline architecture:
- Lexical Analysis (Lexer): Converts source code into tokens
- Parsing (Parser): Converts tokens into an Abstract Syntax Tree (AST)
- Semantic Analysis: Validates the AST and performs type checking
- Optimization: Optimizes the AST for better performance
- Code Generation (Compiler): Generates LLVM IR from the AST
- Binary Generation: Uses LLVM to generate native binaries
The REPL provides an interactive environment for testing SmashLang code without compiling to binaries.
- Follow the Rust API Guidelines
- Use
rustfmtfor consistent formatting - Use
clippyfor linting - Aim for zero warnings in the codebase
- Use meaningful variable and function names
- Add comments for complex logic, but prefer self-documenting code
- Document all public functions, structs, and enums with doc comments
- Include examples in doc comments where appropriate
- Keep the README.md up-to-date with installation and usage instructions
- Document language features in the docs/ directory
- Write unit tests for all components
- Include integration tests for the compiler pipeline
- Add regression tests for fixed bugs
- Aim for high test coverage, especially in the lexer and parser
- Use
ResultandOptiontypes for error handling - Provide meaningful error messages with source locations
- Avoid panics in library code
- Use the
anyhowcrate for error propagation
- JavaScript-inspired syntax: Familiar to web developers
- Static typing with inference: Type safety without verbosity
- Performance-focused: Compile to efficient native code
- Modern features: Support for modern programming paradigms
- Cross-platform: Run on Linux, macOS, and Windows
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and ensure they pass
- Submit a pull request
Use the following format for commit messages:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Formatting changesrefactor: Code refactoringtest: Adding or modifying testschore: Maintenance tasks
- All code must be reviewed before merging
- Address all review comments
- Ensure tests pass before merging
- Keep pull requests focused on a single feature or fix
- Rust (latest stable version)
- LLVM 15.0 (for the compiler)
- Git
smash: Interactive REPL and script runnersmashc: Standalone compiler for building executables and librariessmashpkg: Package manager for installing and managing dependencies
- Clone the repository
- Install dependencies
- Build with
cargo build - Run tests with
cargo test
smash: The main language binary (REPL and runner)smashpkg: The package managersmashc: The standalone compiler for developers
- Update the lexer to recognize new tokens if needed
- Update the parser to handle new syntax
- Add AST nodes for new constructs
- Implement evaluation in the REPL
- Implement code generation in the compiler
- Add tests for the new feature
- Update documentation
- Define the API in the standard library
- Implement the functionality
- Add bindings to the compiler
- Add tests for the new functionality
- Update documentation
- Use platform-agnostic APIs when possible
- Test on all supported platforms (Linux, macOS, Windows)
- Handle platform-specific paths and behaviors
- Use conditional compilation for platform-specific code
- Profile code to identify bottlenecks
- Optimize hot paths
- Use efficient data structures
- Minimize memory allocations
- Consider parallelism for CPU-intensive tasks
- Validate all user input
- Avoid unsafe code when possible
- Follow secure coding practices
- Keep dependencies up-to-date
- Follow Semantic Versioning (SemVer)
- Maintain a changelog
- Tag releases in Git
- Publish binaries for all supported platforms
By following these guidelines, we can maintain a high-quality codebase and create a powerful, user-friendly programming language. SmashLang aims to combine the best aspects of JavaScript with the performance of native code, providing a compelling alternative for developers across various domains.