From 6d6caf543610e83b8742038fb82ec3d63c38e03e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?b=CA=B0edoh=E2=82=82=20sw=C3=A9?= Date: Sun, 2 Feb 2025 21:44:30 +0500 Subject: [PATCH] Initial commit. --- README.md | 27 +++++++++++++++++ include/with99.h | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 README.md create mode 100644 include/with99.h diff --git a/README.md b/README.md new file mode 100644 index 0000000..d17798d --- /dev/null +++ b/README.md @@ -0,0 +1,27 @@ +# Metalang99-based library, adding Python-like "with" blocks + +```c +#include +#include + +#include + +#define WITH99_RESOURCE_TYPE_intptr(...) int* +#define WITH99_RESOURCE_INIT_intptr(res, ...) (printf("Allocated to %p\n", res), *res = malloc(sizeof(int)), 0) +#define WITH99_RESOURCE_FREE_intptr(res, ...) (printf("Freed %p at %p\n", res, *res), free(*res)) +#define WITH99_RESOURCE_THROWS_intptr(res, ...) 0 + +#define With WITH99_With + +int main(void) { + With( + (intptr, a), + (intptr, b) + ) { + *a = 1; + *b = 2; + *a += *b; + printf("%d\n", *a); + } +} +``` diff --git a/include/with99.h b/include/with99.h new file mode 100644 index 0000000..cab44fc --- /dev/null +++ b/include/with99.h @@ -0,0 +1,75 @@ +#ifndef WITH99_H +#define WITH99_H + +#include +#include +#include +#include +#include + +#if !ML99_VERSION_COMPATIBLE(1, 13, 2) +#error Your Metalang99 is a bit mouldy, update to v1.13.2 or later. +#endif + +#define WITH99_VERSION 1 + +#define WITH99_PRIV_RESTYPE(res, ...) WITH99_RESOURCE_TYPE_ ## res (__VA_ARGS__) +#define WITH99_PRIV_RESINIT(res, ...) WITH99_RESOURCE_INIT_ ## res (__VA_ARGS__) +#define WITH99_PRIV_RESFREE(res, ...) WITH99_RESOURCE_FREE_ ## res (__VA_ARGS__) +#define WITH99_PRIV_RESTHROWS(res, ...) WITH99_RESOURCE_THROWS_ ## res (__VA_ARGS__) + +#define WITH99_PRIV_DECLARE_RESOURCE(res, name, ...) WITH99_PRIV_RESTYPE(res, __VA_ARGS__) name +#define WITH99_PRIV_INIT_RESOURCE(res, name, ...) WITH99_PRIV_RESINIT(res, &name, __VA_ARGS__) +#define WITH99_PRIV_FREE_RESOURCE(res, name, ...) WITH99_PRIV_RESFREE(res, &name, __VA_ARGS__) +#define WITH99_PRIV_THROWS_RESOURCE(res, name, ...) WITH99_PRIV_RESTHROWS(res, __VA_ARGS__) + +#define WITH99_PRIV_throw_match_0_IMPL(tResNameArgs)\ + ML99_appl(ML99_reify(v(ML99_CHAIN_EXPR_STMT)),\ + ML99_appl(ML99_reify(v(WITH99_PRIV_INIT_RESOURCE)),\ + ML99_untuple(v(tResNameArgs))\ + )\ + ) + +#define WITH99_PRIV_IF_ERROR(code)\ + if (!code) + +#define WITH99_PRIV_throw_match_1_IMPL(tResNameArgs)\ + ML99_appl(ML99_reify(v(WITH99_PRIV_IF_ERROR)),\ + ML99_appl(ML99_reify(v(WITH99_PRIV_INIT_RESOURCE)),\ + ML99_untuple(v(tResNameArgs))\ + )\ + ) + +#define WITH99_PRIV_create_stmt_IMPL(tResNameArgs)\ + ML99_appl(ML99_reify(v(ML99_INTRODUCE_VAR_TO_STMT)),\ + ML99_appl(ML99_reify(v(WITH99_PRIV_DECLARE_RESOURCE)),\ + ML99_untuple(v(tResNameArgs))\ + )\ + ),\ + ML99_boolMatchWithArgs(\ + ML99_appl(\ + ML99_reify(\ + v(WITH99_PRIV_THROWS_RESOURCE)\ + ),\ + ML99_untuple(v(tResNameArgs))\ + ),\ + v(WITH99_PRIV_throw_match_),\ + v(tResNameArgs)\ + ),\ + ML99_appl(ML99_reify(v(ML99_CHAIN_EXPR_STMT_AFTER)),\ + ML99_appl(ML99_reify(v(WITH99_PRIV_FREE_RESOURCE)),\ + ML99_untuple(v(tResNameArgs))\ + )\ + ) + + +//#define WITH99_PRIV_create_stmt_IMPL(a) ML99_untuple(v(a)) + +#define WITH99_PRIV_create_stmt_ARITY 1 + +#define WITH99_With(...) ML99_EVAL(WITH99_with(__VA_ARGS__)) + +#define WITH99_with(...) ML99_call(WITH99_with, v(__VA_ARGS__)) +#define WITH99_with_IMPL(...) ML99_variadicsForEach(v(WITH99_PRIV_create_stmt), v(__VA_ARGS__)) + +#endif