A modern extension language for safer and more productive C programming
- dasae-headers
"Make C Great Again"
dasae-headers aims to apply modern programming paradigms to the C language, greatly enhancing safety, expressiveness, and productivity. It provides memory safety, type safety, and improved error handling while maintaining the simplicity of C.
Currently in its early development stage, dasae-headers utilizes C's preprocessor as a transpiler and addresses chronic issues in the C standard library while gradually evolving into an independent language.
dasae-headers was developed with inspiration from the syntax and standard libraries of Zig and Rust:
Memory Safety & Resource Management
- Custom allocators for selective memory usage and control
- Built-in memory tracking for detecting memory leaks and related bugs
- Array safety through checked access methods
- Boundary-checked slices for safe memory manipulation
- Automated resource management through
defer
anderrdefer
statements
Type System Enhancements
- Enhanced type safety through compile-time checks
- Algebraic data types (union enum) with pattern matching and
match
statements - Null safety through optional types with
some
/none
keywords andunwrap
/orelse
patterns
Error Handling & Debugging
- Error-wrapped types for explicit error handling with
ok
/err
keywords - Structured error propagation with
try
,catch
patterns - Comprehensive error tracing with stack traces for debugging
Modern Programming Paradigms
- Type inference through
let
andvar
keywords - Modern function syntax using
fn
declarations - Lambda expressions and callback types
- Consistent code style and naming conventions
- Expressive macros for improved code clarity
Development Tools
- Built-in testing framework for unit and integration tests
- Multi-platform support for various architectures
- Major compiler compatibility (clang, gcc, msvc)
- Operating Systems: Windows, Unix, Linux, macOS, Android, etc.
- CPU Architectures: Considers 64/32-bit architectures
- Compiler Compatibility: clang (preferred), gcc, msvc, etc.
Detailed installation and build guide is in preparation. Please wait a moment!
- Clone this repository:
git clone https://github.com/coding-pelican/dasae-headers.git
- Install the dh-c build tool:
On Windows:
cd dasae-headers
.\install-dh-c.ps1
On Linux/macOS:
cd dasae-headers
chmod +x install-dh-c.sh
./install-dh-c.sh
- Create a new project:
dh-c project myproject
cd myproject
- Start coding by including the necessary headers:
#include "dh/main.h"
#include "dh/opt.h"
#include "dh/err_res.h"
// Include additional headers according to needed functionality
Build your project:
dh-c build dev
Run your project:
dh-c run dev
Run tests:
dh-c test
See the Quick Start Guide for more details.
// Include the main header that provides program entry point
#include "dh/main.h"
// Include string utilities for working with text
#include "dh/Str.h"
// Define the main function with scope and error handling
// Takes command line arguments and returns an error result with void payload
fn_scope(dh_main(Sli$Str_const args), Err$void) {
$ignore args;
// Create a string literal using Str_l
let hello_world = Str_l("Hello, world!");
// Print the string to the console with a newline
Str_println(hello_world);
// Return success (void value with no error)
return_ok({});
} unscoped; // End the scope block
fn_scope(findValueIndex(i32 value, Sli_const$i32 items), Opt$i32) {
for_slice_indexed (items, item, index) {
if (*item != value) { continue; }
return_some(index); // Return with a value
}
return_none(); // Return with no value
} unscoped;
fn_(example(void), void) {
Arr$$(5, i32) nums = Arr_init({ 10, 20, 30, 40, 50 });
// Create optional values
let opt_value = some$(Opt$i32, 42);
let opt_empty = none$(Opt$i32);
// Find a value in array
let found = findValueIndex(30, Sli_arr$(Sli_const$i32, nums));
// Check if option has value
if_some(found, index) {
printf("Found at: %d\n", index);
} else_none {
printf("Not found\n");
}
// Default values
let value = orelse(found, -1); // Use -1 if not found
// Unsafe extraction (assertion if option might be none)
let unsafe_value = unwrap(opt_value);
}
config_ErrSet(math_Err,
DivisionByZero,
Overflow,
Underflow
);
use_ErrSet$(math_Err, i32); // or Generally `use_Err$(i32)`
fn_scope(safeDivide(i32 lhs, i32 rhs), math_Err$i32) {
if (rhs == 0) {
return_err(math_Err_DivisionByZero()); // Return with an error
}
return_ok(lhs / rhs); // Return with a value
} unscoped;
fn_scope_ext(example(void), Err$void) {
// Allocate resources
var buffer = meta_cast$(Sli$i32,
try_(mem_Allocator_alloc(allocator, typeInfo$(i32), 100))
);
// Cleanup always when function returns
defer_(mem_Allocator_free(allocator, anySli(buffer)));
// Cleanup only when an error occurs and propagates
errdefer_(log_error("Occurred error!"));
// Error propagation (early return)
let result_invalid = try_(safeDivide(10, 0));
// Error handling with default value
let result_default = catch_(safeDivide(10, 0), 1);
// Error handling with error payload capture
let result_handling = catch_from(safeDivide(10, 0), err, eval({
Err_print(err); // Print the error
ErrTrace_print(); // Print the error trace
return_err(err); // Return with an error
}));
// Return a normally
return_ok({});
} unscoped_ext;
config_UnionEnum(InputEvent,
(InputEvent_press_key, struct { i32 key; }),
(InputEvent_release_button, struct { i8 button; })
);
use_Opt$(InputEvent);
fn_(pullInputEvent(void), Opt$InputEvent);
fn_(example(void), void) {
if_some(pullInputEvent(), event) {
match_(event) {
pattern_(InputEvent_press_key, on_pressed) {
debug_assert_true_fmt(
-1 < on_pressed->key && on_pressed->key <= 255,
"key is out of range"
);
} break;
pattern_(InputEvent_release_button, on_released) {
debug_assert_true_fmt(
-1 < on_released->button && on_released->button <= 5,
"button is out of range"
);
} break;
fallback_()
claim_unreachable;
}
}
}
dasae-headers provides a simple yet powerful built-in testing framework. You can easily write and run unit tests through the TEST.h
header.
#include "dh/main.h"
#include "dh/TEST.h"
// Define functions to test
fn_(mathAdd(i32 a, i32 b), i32) {
return a + b;
}
fn_(mathMultiply(i32 a, i32 b), i32) {
return a * b;
}
// Define test unit
fn_TEST_scope("Basic Math Operations Test") {
// Addition test
let a = 5;
let b = 7;
let sum = mathAdd(a, b);
// Validate results
try_(TEST_expect(sum == 12));
try_(TEST_expectMsg(sum > 10, "Sum should be greater than 10"));
// Multiplication test
let product = mathMultiply(a, b);
try_(TEST_expect(product == 35));
// Failing test (intentional error)
// try_(TEST_expect(product == 30)); // Fails: 35 != 30
} TEST_unscoped;
Detailed documentation can be found in our wiki:
- Wiki Home - Main documentation portal
- Quick Start Guide - Detailed guide for beginners
- API Reference - Module documentation
Additional resources:
This project is actively under development, and the API is not yet stabilized. We would appreciate if you could use it in experimental projects and provide feedback. If you are interested in improving the project, please refer to contribution.md.
The name "dasae-headers" originated from its beginnings as a header-only library that collected personal favorite C utility code. I haven't decided on a name for it yet. If you have a good name for it, please suggest it :D
Issues, pull requests, and feedback are always welcome!
- Issue reporting: Bug reports / feature requests
- Code contributions: Feature additions / bug fixes via Pull Requests
- Documentation: Improving documentation / adding example code
For any questions or inquiries, please contact the project author:
- Gyeongtae Kim(dev-dasae) <[email protected]>
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright Β© 2024-2025 Gyeongtae Kim