Skip to content

dasae-headers: A modern extension language for safer and more productive C programming

License

Notifications You must be signed in to change notification settings

coding-pelican/dasae-headers

Repository files navigation

dasae-headers

dasae-headers: Modern and Safe C programming

A modern extension language for safer and more productive C programming

Language: English Language: Korean
Language: C17 Platform: Windows | Linux | macOS License: MIT

πŸ“‹ Table of Contents

🌟 Introduction

"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.

πŸ›‘οΈ Key Features

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 and errdefer 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 and unwrap/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 and var 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)

🌐 Platform Support

  • Operating Systems: Windows, Unix, Linux, macOS, Android, etc.
  • CPU Architectures: Considers 64/32-bit architectures
  • Compiler Compatibility: clang (preferred), gcc, msvc, etc.

πŸš€ Getting Started

πŸ’½ Installation

Detailed installation and build guide is in preparation. Please wait a moment!

  1. Clone this repository:
git clone https://github.com/coding-pelican/dasae-headers.git
  1. 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
  1. Create a new project:
dh-c project myproject
cd myproject
  1. 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

πŸ”¨ Building and Running

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.

⚑ Code Samples

πŸ‘‹ Hello, world!

// 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

πŸ” Optional Values Example

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);
}

πŸ”„ Error Results Example

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;

🀝 Pattern Matching Example

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;
        }
    }
}

πŸ§ͺ Test Code Example

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;

πŸ“š Documentation

Detailed documentation can be found in our wiki:

Additional resources:

🚧 Current Status

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

πŸ™ Contributing

Issues, pull requests, and feedback are always welcome!

  1. Issue reporting: Bug reports / feature requests
  2. Code contributions: Feature additions / bug fixes via Pull Requests
  3. Documentation: Improving documentation / adding example code

πŸ“§ Contact

For any questions or inquiries, please contact the project author:

πŸ“œ License

This project is licensed under the MIT License - see the LICENSE file for details.

Copyright Β© 2024-2025 Gyeongtae Kim