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:
Enhanced Safety
- Automated memory management through
defer
statements - Null safety through
Optional
types - Enhanced type safety through compile-time checks
- Built-in memory tracking for detecting memory leaks and related bugs
Modern Programming Structures
- Type inference through
let
andvar
keywords - Boundary-checked slices for safe memory manipulation
- Result types for explicit error handling with
try_
,catch_
patterns - Algebraic data types (union enum) with pattern matching
- Array safety through checked access methods
Development Productivity
- Expressive macros for improved code clarity
- Modern function syntax using
fn_
declarations - Cross-platform support for various architectures
- Major compiler compatibility (clang, gcc, msvc)
- Consistent code style and naming conventions
- 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 usi
8000
ng 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.
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) <codingpelican@gmail.com>
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright Β© 2024-2025 Gyeongtae Kim