FORTBITE Developer Guide
This guide is for developers who want to understand, modify, or extend FORTBITE's codebase.
Architecture Overview
FORTBITE follows a modular, layered architecture with clear separation of concerns:
┌─────────────────────────────────────┐
│ User Interface │
│ (fortbite_io_m) │
├─────────────────────────────────────┤
│ Evaluator │
│ (fortbite_evaluator_m) │
├─────────────────────────────────────┤
│ Parser │ Functions │
│ (fortbite_parser_m)│(fortbite_funcs_m)│
├─────────────────────┼─────────────────┤
│ AST │ Arithmetic │
│ (fortbite_ast_m) │(fortbite_arith_m)│
├─────────────────────┼─────────────────┤
│ Lexer │ Matrix │
│ (fortbite_lexer_m) │(fortbite_matrix_m)│
├─────────────────────────────────────┤
│ Core Types │
│ (fortbite_types_m) │
├─────────────────────────────────────┤
│ Precision │
│ (fortbite_precision_m) │
└─────────────────────────────────────┘
Module Reference
Core Modules
fortbite_precision_m.f90
Purpose: Defines precision parameters and floating-point kinds
integer, parameter :: sp = real32 ! Single precision
integer, parameter :: dp = real64 ! Double precision
integer, parameter :: qp = real128 ! Quad precision (if available)
fortbite_types_m.f90
Purpose: Core data types and error handling
type :: value_t ! Universal value container
type :: variable_t ! Variable storage with linked list
type :: token_t ! Lexical tokens
type :: fortbite_error_t ! Unified error handling
Key functions:
- Matrix creation:
create_zeros_matrix(),create_ones_matrix(),create_eye_matrix() - Value operations:
create_scalar(),create_complex(),destroy_value() - Error handling:
set_fortbite_error(),create_error_value()
Parsing Pipeline
fortbite_lexer_m.f90
Purpose: Tokenizes input strings into mathematical tokens
function tokenize(input) result(tokens)
Token types: Numbers, identifiers, operators, parentheses, brackets, etc.
fortbite_ast_m.f90
Purpose: Abstract Syntax Tree definition and memory management
type :: ast_node_t
integer :: node_type ! AST_LITERAL, AST_BINARY_OP, etc.
character(len=:), allocatable :: identifier
real(real64) :: value
type(ast_node_t), pointer :: left, right
! ... other fields
end type
fortbite_parser_m.f90
Purpose: Builds ASTs from token streams using recursive descent
function parse_expression(tokens, error) result(root)
Grammar hierarchy:
- Assignment (
x := expr) - Logical operations
- Arithmetic operations (
+,-,*,/,**) - Function calls
- Primary expressions (numbers, variables, parentheses)
Evaluation System
fortbite_evaluator_m.f90
Purpose: Executes ASTs and manages variables
function evaluate_expression(node, context, error) result(value)
Key patterns:
- Visitor pattern for AST traversal
- Type checking and promotion
- Error propagation
- Variable context management
Recent improvements:
- Unified error handling with
quick_error()helper - Consolidated function dispatch with helper functions
- Streamlined argument validation
fortbite_arithmetic_m.f90
Purpose: Basic arithmetic operations with type promotion
function add_values(left, right) result(value)
function multiply_values(left, right) result(value)
! etc.
Mathematical Functions
fortbite_functions_m.f90
Purpose: Advanced mathematical functions
function eval_trigonometric(func_name, arg) result(value)
function eval_hyperbolic(func_name, arg) result(value)
function eval_logarithmic(func_name, arg) result(value)
function eval_exponential(func_name, arg) result(value)
function eval_statistical(func_name, arg) result(value)
function eval_special(func_name, arg) result(value)
function eval_complex_functions(func_name, arg) result(value)
fortbite_matrix_m.f90
Purpose: Linear algebra operations
function matrix_transpose(matrix) result(result)
function matrix_determinant(matrix) result(det)
function matrix_inverse(matrix) result(inv)
function matrix_solve(A, b) result(x)
User Interface
fortbite_io_m.f90
Purpose: REPL loop and user interaction
subroutine repl_loop(context)
function evaluate_math_expression(input, context) result(success)
Code Quality Improvements
Recent Refactoring (Completed)
-
Eliminated Code Duplication
- Created
validate_function_args()helper - Added
validate_matrix_dims()for dimension checking - Reduced ~120 lines of duplicate validation code
- Created
-
Unified Function Dispatch
- Added
eval_matrix_creation()andeval_matrix_operation()helpers - Simplified case statements from 60+ lines to 1-2 lines
- Maintained backward compatibility
- Added
-
Streamlined Matrix Creation
- Created
setup_matrix_base()helper function - Reduced duplicate setup code across all matrix creation functions
- All matrix functions now use consistent patterns
- Created
-
Enhanced Error Handling
- Added unified
fortbite_error_ttype - Created
create_error_value()andquick_error()helpers - Replaced 15+ instances of hardcoded error returns
- Added unified
Development Guidelines
Coding Standards
-
Naming Conventions
- Modules:
fortbite_*_m.f90 - Functions:
verb_noun()(e.g.,create_matrix()) - Types:
*_tsuffix (e.g.,value_t) - Constants:
UPPER_CASE
- Modules:
-
Error Handling
- Always use unified error types
- Prefer helper functions over manual error setting
- Include descriptive error messages
- Clean up resources on error paths
-
Memory Management
- Use allocatable arrays instead of pointers where possible
- Always pair allocate/deallocate
- Implement cleanup routines for complex types
- Use
destroy_*()functions consistently
-
Documentation
- Document all public interfaces with
!>comments - Include usage examples for complex functions
- Explain non-obvious algorithms
- Keep README and guides up to date
- Document all public interfaces with
Adding New Functions
-
Mathematical Functions
! In fortbite_functions_m.f90 case ('your_func') if (validate_args(...)) then result_val = create_scalar(your_calculation(x)) else result_val = create_error_value() end if -
Matrix Operations
! In fortbite_matrix_m.f90 function matrix_your_operation(matrix) result(result) type(value_t), intent(in) :: matrix type(value_t) :: result ! Validate matrix input ! Perform operation ! Return result end function -
Register in Evaluator
! In fortbite_evaluator_m.f90 case ('your_func') value = eval_your_category(node%function_name, args(1))
Testing Strategy
Unit Tests (Recommended)
program test_arithmetic
use fortbite_arithmetic_m
implicit none
call test_addition()
call test_multiplication()
contains
subroutine test_addition()
! Test cases
end subroutine
end program
Integration Tests
# Test mathematical functions
echo "sin(pi/2)" | ./fortbite | grep "1.0"
echo "det([1,2;3,4])" | ./fortbite | grep "\-2"
Performance Considerations
-
Memory Usage
- Large matrices can consume significant memory
- Consider implementing matrix size limits
- Use efficient algorithms (O(n³) → O(n²·⁸) where possible)
-
Precision vs Speed
- High-precision mode is slower
- Consider lazy precision conversion
- Cache frequently used constants
-
Function Dispatch
- Current string-based dispatch is readable but not fastest
- Consider hash tables for very large function sets
- Profile before optimizing
Future Enhancements
Planned Features
- Automated Testing Suite (in progress)
- Package Management (fpm.toml ready)
- Extended Function Library (statistical distributions, etc.)
- Performance Optimization (BLAS integration)
Extension Points
- Custom Functions: Easy to add via
fortbite_functions_m.f90 - New Data Types: Extend
value_tfor intervals, polynomials, etc. - Alternative UIs: Replace
fortbite_io_m.f90for GUI/web interfaces - File I/O: Add import/export capabilities
Debugging Tips
-
Build with Debug Info
make clean && make FFLAGS="-g -fcheck=all -fbacktrace" -
Enable Warnings
make FFLAGS="-Wall -Wextra -Wconversion" -
Memory Debugging
valgrind --tool=memcheck ./build/bin/fortbite -
AST Debugging
- Add print statements in evaluator
- Trace recursive descent parsing
- Verify token sequences
Contributing
-
Fork and Branch
- Create feature branches
- Use descriptive commit messages
- Include tests for new functionality
-
Code Review Checklist
- Follows naming conventions
- Includes error handling
- Has documentation comments
- Memory is properly managed
- Tests pass (when implemented)
-
Performance Testing
- Profile before/after changes
- Test with large matrices
- Verify memory usage patterns
This developer guide provides the foundation for understanding and extending FORTBITE. For questions or clarifications, please refer to the source code comments and existing patterns.
View source
| 1 | # FORTBITE Developer Guide |
| 2 | |
| 3 | This guide is for developers who want to understand, modify, or extend FORTBITE's codebase. |
| 4 | |
| 5 | ## Architecture Overview |
| 6 | |
| 7 | FORTBITE follows a modular, layered architecture with clear separation of concerns: |
| 8 | |
| 9 | ``` |
| 10 | ┌─────────────────────────────────────┐ |
| 11 | │ User Interface │ |
| 12 | │ (fortbite_io_m) │ |
| 13 | ├─────────────────────────────────────┤ |
| 14 | │ Evaluator │ |
| 15 | │ (fortbite_evaluator_m) │ |
| 16 | ├─────────────────────────────────────┤ |
| 17 | │ Parser │ Functions │ |
| 18 | │ (fortbite_parser_m)│(fortbite_funcs_m)│ |
| 19 | ├─────────────────────┼─────────────────┤ |
| 20 | │ AST │ Arithmetic │ |
| 21 | │ (fortbite_ast_m) │(fortbite_arith_m)│ |
| 22 | ├─────────────────────┼─────────────────┤ |
| 23 | │ Lexer │ Matrix │ |
| 24 | │ (fortbite_lexer_m) │(fortbite_matrix_m)│ |
| 25 | ├─────────────────────────────────────┤ |
| 26 | │ Core Types │ |
| 27 | │ (fortbite_types_m) │ |
| 28 | ├─────────────────────────────────────┤ |
| 29 | │ Precision │ |
| 30 | │ (fortbite_precision_m) │ |
| 31 | └─────────────────────────────────────┘ |
| 32 | ``` |
| 33 | |
| 34 | ## Module Reference |
| 35 | |
| 36 | ### Core Modules |
| 37 | |
| 38 | #### `fortbite_precision_m.f90` |
| 39 | **Purpose:** Defines precision parameters and floating-point kinds |
| 40 | ```fortran |
| 41 | integer, parameter :: sp = real32 ! Single precision |
| 42 | integer, parameter :: dp = real64 ! Double precision |
| 43 | integer, parameter :: qp = real128 ! Quad precision (if available) |
| 44 | ``` |
| 45 | |
| 46 | #### `fortbite_types_m.f90` |
| 47 | **Purpose:** Core data types and error handling |
| 48 | ```fortran |
| 49 | type :: value_t ! Universal value container |
| 50 | type :: variable_t ! Variable storage with linked list |
| 51 | type :: token_t ! Lexical tokens |
| 52 | type :: fortbite_error_t ! Unified error handling |
| 53 | ``` |
| 54 | |
| 55 | **Key functions:** |
| 56 | - Matrix creation: `create_zeros_matrix()`, `create_ones_matrix()`, `create_eye_matrix()` |
| 57 | - Value operations: `create_scalar()`, `create_complex()`, `destroy_value()` |
| 58 | - Error handling: `set_fortbite_error()`, `create_error_value()` |
| 59 | |
| 60 | ### Parsing Pipeline |
| 61 | |
| 62 | #### `fortbite_lexer_m.f90` |
| 63 | **Purpose:** Tokenizes input strings into mathematical tokens |
| 64 | ```fortran |
| 65 | function tokenize(input) result(tokens) |
| 66 | ``` |
| 67 | |
| 68 | **Token types:** Numbers, identifiers, operators, parentheses, brackets, etc. |
| 69 | |
| 70 | #### `fortbite_ast_m.f90` |
| 71 | **Purpose:** Abstract Syntax Tree definition and memory management |
| 72 | ```fortran |
| 73 | type :: ast_node_t |
| 74 | integer :: node_type ! AST_LITERAL, AST_BINARY_OP, etc. |
| 75 | character(len=:), allocatable :: identifier |
| 76 | real(real64) :: value |
| 77 | type(ast_node_t), pointer :: left, right |
| 78 | ! ... other fields |
| 79 | end type |
| 80 | ``` |
| 81 | |
| 82 | #### `fortbite_parser_m.f90` |
| 83 | **Purpose:** Builds ASTs from token streams using recursive descent |
| 84 | ```fortran |
| 85 | function parse_expression(tokens, error) result(root) |
| 86 | ``` |
| 87 | |
| 88 | **Grammar hierarchy:** |
| 89 | 1. Assignment (`x := expr`) |
| 90 | 2. Logical operations |
| 91 | 3. Arithmetic operations (`+`, `-`, `*`, `/`, `**`) |
| 92 | 4. Function calls |
| 93 | 5. Primary expressions (numbers, variables, parentheses) |
| 94 | |
| 95 | ### Evaluation System |
| 96 | |
| 97 | #### `fortbite_evaluator_m.f90` |
| 98 | **Purpose:** Executes ASTs and manages variables |
| 99 | ```fortran |
| 100 | function evaluate_expression(node, context, error) result(value) |
| 101 | ``` |
| 102 | |
| 103 | **Key patterns:** |
| 104 | - Visitor pattern for AST traversal |
| 105 | - Type checking and promotion |
| 106 | - Error propagation |
| 107 | - Variable context management |
| 108 | |
| 109 | **Recent improvements:** |
| 110 | - Unified error handling with `quick_error()` helper |
| 111 | - Consolidated function dispatch with helper functions |
| 112 | - Streamlined argument validation |
| 113 | |
| 114 | #### `fortbite_arithmetic_m.f90` |
| 115 | **Purpose:** Basic arithmetic operations with type promotion |
| 116 | ```fortran |
| 117 | function add_values(left, right) result(value) |
| 118 | function multiply_values(left, right) result(value) |
| 119 | ! etc. |
| 120 | ``` |
| 121 | |
| 122 | ### Mathematical Functions |
| 123 | |
| 124 | #### `fortbite_functions_m.f90` |
| 125 | **Purpose:** Advanced mathematical functions |
| 126 | ```fortran |
| 127 | function eval_trigonometric(func_name, arg) result(value) |
| 128 | function eval_hyperbolic(func_name, arg) result(value) |
| 129 | function eval_logarithmic(func_name, arg) result(value) |
| 130 | function eval_exponential(func_name, arg) result(value) |
| 131 | function eval_statistical(func_name, arg) result(value) |
| 132 | function eval_special(func_name, arg) result(value) |
| 133 | function eval_complex_functions(func_name, arg) result(value) |
| 134 | ``` |
| 135 | |
| 136 | #### `fortbite_matrix_m.f90` |
| 137 | **Purpose:** Linear algebra operations |
| 138 | ```fortran |
| 139 | function matrix_transpose(matrix) result(result) |
| 140 | function matrix_determinant(matrix) result(det) |
| 141 | function matrix_inverse(matrix) result(inv) |
| 142 | function matrix_solve(A, b) result(x) |
| 143 | ``` |
| 144 | |
| 145 | ### User Interface |
| 146 | |
| 147 | #### `fortbite_io_m.f90` |
| 148 | **Purpose:** REPL loop and user interaction |
| 149 | ```fortran |
| 150 | subroutine repl_loop(context) |
| 151 | function evaluate_math_expression(input, context) result(success) |
| 152 | ``` |
| 153 | |
| 154 | ## Code Quality Improvements |
| 155 | |
| 156 | ### Recent Refactoring (Completed) |
| 157 | |
| 158 | 1. **Eliminated Code Duplication** |
| 159 | - Created `validate_function_args()` helper |
| 160 | - Added `validate_matrix_dims()` for dimension checking |
| 161 | - Reduced ~120 lines of duplicate validation code |
| 162 | |
| 163 | 2. **Unified Function Dispatch** |
| 164 | - Added `eval_matrix_creation()` and `eval_matrix_operation()` helpers |
| 165 | - Simplified case statements from 60+ lines to 1-2 lines |
| 166 | - Maintained backward compatibility |
| 167 | |
| 168 | 3. **Streamlined Matrix Creation** |
| 169 | - Created `setup_matrix_base()` helper function |
| 170 | - Reduced duplicate setup code across all matrix creation functions |
| 171 | - All matrix functions now use consistent patterns |
| 172 | |
| 173 | 4. **Enhanced Error Handling** |
| 174 | - Added unified `fortbite_error_t` type |
| 175 | - Created `create_error_value()` and `quick_error()` helpers |
| 176 | - Replaced 15+ instances of hardcoded error returns |
| 177 | |
| 178 | ## Development Guidelines |
| 179 | |
| 180 | ### Coding Standards |
| 181 | |
| 182 | 1. **Naming Conventions** |
| 183 | - Modules: `fortbite_*_m.f90` |
| 184 | - Functions: `verb_noun()` (e.g., `create_matrix()`) |
| 185 | - Types: `*_t` suffix (e.g., `value_t`) |
| 186 | - Constants: `UPPER_CASE` |
| 187 | |
| 188 | 2. **Error Handling** |
| 189 | - Always use unified error types |
| 190 | - Prefer helper functions over manual error setting |
| 191 | - Include descriptive error messages |
| 192 | - Clean up resources on error paths |
| 193 | |
| 194 | 3. **Memory Management** |
| 195 | - Use allocatable arrays instead of pointers where possible |
| 196 | - Always pair allocate/deallocate |
| 197 | - Implement cleanup routines for complex types |
| 198 | - Use `destroy_*()` functions consistently |
| 199 | |
| 200 | 4. **Documentation** |
| 201 | - Document all public interfaces with `!>` comments |
| 202 | - Include usage examples for complex functions |
| 203 | - Explain non-obvious algorithms |
| 204 | - Keep README and guides up to date |
| 205 | |
| 206 | ### Adding New Functions |
| 207 | |
| 208 | 1. **Mathematical Functions** |
| 209 | ```fortran |
| 210 | ! In fortbite_functions_m.f90 |
| 211 | case ('your_func') |
| 212 | if (validate_args(...)) then |
| 213 | result_val = create_scalar(your_calculation(x)) |
| 214 | else |
| 215 | result_val = create_error_value() |
| 216 | end if |
| 217 | ``` |
| 218 | |
| 219 | 2. **Matrix Operations** |
| 220 | ```fortran |
| 221 | ! In fortbite_matrix_m.f90 |
| 222 | function matrix_your_operation(matrix) result(result) |
| 223 | type(value_t), intent(in) :: matrix |
| 224 | type(value_t) :: result |
| 225 | |
| 226 | ! Validate matrix input |
| 227 | ! Perform operation |
| 228 | ! Return result |
| 229 | end function |
| 230 | ``` |
| 231 | |
| 232 | 3. **Register in Evaluator** |
| 233 | ```fortran |
| 234 | ! In fortbite_evaluator_m.f90 |
| 235 | case ('your_func') |
| 236 | value = eval_your_category(node%function_name, args(1)) |
| 237 | ``` |
| 238 | |
| 239 | ### Testing Strategy |
| 240 | |
| 241 | #### Unit Tests (Recommended) |
| 242 | ```fortran |
| 243 | program test_arithmetic |
| 244 | use fortbite_arithmetic_m |
| 245 | implicit none |
| 246 | |
| 247 | call test_addition() |
| 248 | call test_multiplication() |
| 249 | |
| 250 | contains |
| 251 | subroutine test_addition() |
| 252 | ! Test cases |
| 253 | end subroutine |
| 254 | end program |
| 255 | ``` |
| 256 | |
| 257 | #### Integration Tests |
| 258 | ```bash |
| 259 | # Test mathematical functions |
| 260 | echo "sin(pi/2)" | ./fortbite | grep "1.0" |
| 261 | echo "det([1,2;3,4])" | ./fortbite | grep "\-2" |
| 262 | ``` |
| 263 | |
| 264 | ### Performance Considerations |
| 265 | |
| 266 | 1. **Memory Usage** |
| 267 | - Large matrices can consume significant memory |
| 268 | - Consider implementing matrix size limits |
| 269 | - Use efficient algorithms (O(n³) → O(n²·⁸) where possible) |
| 270 | |
| 271 | 2. **Precision vs Speed** |
| 272 | - High-precision mode is slower |
| 273 | - Consider lazy precision conversion |
| 274 | - Cache frequently used constants |
| 275 | |
| 276 | 3. **Function Dispatch** |
| 277 | - Current string-based dispatch is readable but not fastest |
| 278 | - Consider hash tables for very large function sets |
| 279 | - Profile before optimizing |
| 280 | |
| 281 | ## Future Enhancements |
| 282 | |
| 283 | ### Planned Features |
| 284 | - **Automated Testing Suite** (in progress) |
| 285 | - **Package Management** (fpm.toml ready) |
| 286 | - **Extended Function Library** (statistical distributions, etc.) |
| 287 | - **Performance Optimization** (BLAS integration) |
| 288 | |
| 289 | ### Extension Points |
| 290 | - **Custom Functions**: Easy to add via `fortbite_functions_m.f90` |
| 291 | - **New Data Types**: Extend `value_t` for intervals, polynomials, etc. |
| 292 | - **Alternative UIs**: Replace `fortbite_io_m.f90` for GUI/web interfaces |
| 293 | - **File I/O**: Add import/export capabilities |
| 294 | |
| 295 | ## Debugging Tips |
| 296 | |
| 297 | 1. **Build with Debug Info** |
| 298 | ```bash |
| 299 | make clean && make FFLAGS="-g -fcheck=all -fbacktrace" |
| 300 | ``` |
| 301 | |
| 302 | 2. **Enable Warnings** |
| 303 | ```bash |
| 304 | make FFLAGS="-Wall -Wextra -Wconversion" |
| 305 | ``` |
| 306 | |
| 307 | 3. **Memory Debugging** |
| 308 | ```bash |
| 309 | valgrind --tool=memcheck ./build/bin/fortbite |
| 310 | ``` |
| 311 | |
| 312 | 4. **AST Debugging** |
| 313 | - Add print statements in evaluator |
| 314 | - Trace recursive descent parsing |
| 315 | - Verify token sequences |
| 316 | |
| 317 | ## Contributing |
| 318 | |
| 319 | 1. **Fork and Branch** |
| 320 | - Create feature branches |
| 321 | - Use descriptive commit messages |
| 322 | - Include tests for new functionality |
| 323 | |
| 324 | 2. **Code Review Checklist** |
| 325 | - [ ] Follows naming conventions |
| 326 | - [ ] Includes error handling |
| 327 | - [ ] Has documentation comments |
| 328 | - [ ] Memory is properly managed |
| 329 | - [ ] Tests pass (when implemented) |
| 330 | |
| 331 | 3. **Performance Testing** |
| 332 | - Profile before/after changes |
| 333 | - Test with large matrices |
| 334 | - Verify memory usage patterns |
| 335 | |
| 336 | --- |
| 337 | |
| 338 | *This developer guide provides the foundation for understanding and extending FORTBITE. For questions or clarifications, please refer to the source code comments and existing patterns.* |