2026-02-06 18:39:35 +11:00
|
|
|
#if 0
|
|
|
|
|
|
|
|
|
|
# zc compiler (in a Bash script)
|
2026-02-07 14:04:32 +11:00
|
|
|
# If you dont want to write in the style of C, write as a .zc script!
|
2026-02-06 18:39:35 +11:00
|
|
|
# What this does:
|
2026-02-07 14:04:32 +11:00
|
|
|
# * Creates a .zc-build folder
|
2026-02-06 18:39:35 +11:00
|
|
|
# * Adds some boilerplate
|
|
|
|
|
# * Inserts your code
|
|
|
|
|
# * Compiles and produces an executable
|
2026-02-07 14:04:32 +11:00
|
|
|
# * Removes the .zc-build folder, unless there was an error, so you can debug
|
2026-02-06 18:39:35 +11:00
|
|
|
|
|
|
|
|
# Alternatively, you can use zc as a C library, if you wish.
|
|
|
|
|
|
2026-02-07 14:04:32 +11:00
|
|
|
set -e
|
|
|
|
|
|
|
|
|
|
mkdir -p .zc-build
|
|
|
|
|
echo "#include <zc.h>" > .zc-build/main.c
|
|
|
|
|
cat "$@" >> .zc-build/main.c
|
|
|
|
|
gcc .zc-build/main.c
|
|
|
|
|
rm -r .zc-build
|
2026-02-06 18:39:35 +11:00
|
|
|
|
|
|
|
|
exit
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef ZC_H
|
|
|
|
|
#define ZC_H
|
|
|
|
|
|
2026-02-07 14:04:32 +11:00
|
|
|
/*
|
|
|
|
|
* zc - What if C, but easier?
|
|
|
|
|
* A work in progress project by Maxwell Jeffress
|
|
|
|
|
* Licenced to you under the MIT license.
|
|
|
|
|
*/
|
|
|
|
|
|
2026-02-06 18:39:35 +11:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
#error C++ is not supported by zc
|
|
|
|
|
#include "Try using C instead?"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* TOKENS
|
|
|
|
|
* Defines different tokens for use in zc. Allows code to read more
|
|
|
|
|
* like English.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define then {
|
|
|
|
|
#define end }
|
|
|
|
|
|
|
|
|
|
#define is =
|
|
|
|
|
#define plus +
|
|
|
|
|
#define minus -
|
|
|
|
|
#define times *
|
|
|
|
|
#define divideby /
|
|
|
|
|
|
|
|
|
|
#define increment ++
|
|
|
|
|
#define decrement --
|
|
|
|
|
|
|
|
|
|
#define adds +=
|
|
|
|
|
#define subtracts -=
|
|
|
|
|
#define multiplies *=
|
|
|
|
|
#define divides /=
|
|
|
|
|
|
|
|
|
|
#define equals ==
|
|
|
|
|
#define not !
|
|
|
|
|
#define greaterthan >
|
|
|
|
|
#define lessthan <
|
|
|
|
|
#define greaterorequalto >=
|
|
|
|
|
#define lesserorequalto <=
|
|
|
|
|
|
|
|
|
|
#define and &&
|
|
|
|
|
#define or ||
|
|
|
|
|
|
2026-02-07 14:04:32 +11:00
|
|
|
#define pass (void)0
|
|
|
|
|
|
2026-02-06 18:39:35 +11:00
|
|
|
/*
|
|
|
|
|
* TYPES
|
|
|
|
|
* Creates friendlier names for different types.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define list *
|
|
|
|
|
|
|
|
|
|
#define Integer int
|
|
|
|
|
#define Float float
|
|
|
|
|
#define Double double
|
|
|
|
|
#define Character char
|
|
|
|
|
#define String char*
|
|
|
|
|
#define Boolean bool
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* PRINTING
|
|
|
|
|
* Allows much easier printing to the console.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define print(x) _Generic((x), \
|
|
|
|
|
int: printf("%d\n", x), \
|
|
|
|
|
float: printf("%f\n", x), \
|
|
|
|
|
char*: printf("%s\n", x), \
|
|
|
|
|
default: printf("unknown type\n") \
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* MEMORY MANAGEMENT
|
|
|
|
|
* These functions map malloc and realloc to provide user-friendly
|
|
|
|
|
* memory management.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#define new(x) (then\
|
|
|
|
|
x* __new_something is malloc(sizeof(x));\
|
|
|
|
|
if (__new_something equals NULL) { print("Couldn't malloc :("); exit(1); }\
|
|
|
|
|
__new_something;\
|
|
|
|
|
end)
|
|
|
|
|
|
|
|
|
|
#define many(x, size) (then\
|
|
|
|
|
x* __new_something is malloc(sizeof(x) * size);\
|
|
|
|
|
if (__new_something equals NULL) { print("Couldn't malloc :("); exit(1); }\
|
|
|
|
|
__new_something;\
|
|
|
|
|
end)
|
|
|
|
|
|
2026-02-07 14:04:32 +11:00
|
|
|
#define forget(var) _Generic((var), \
|
|
|
|
|
default: var.destructor_fn(&var) \
|
|
|
|
|
)
|
2026-02-06 18:39:35 +11:00
|
|
|
|
|
|
|
|
#define resize(var, size) then\
|
|
|
|
|
typeof(*var)* __resized_something is realloc(var, sizeof(typeof(*var)) * size);\
|
|
|
|
|
if (__resized_something equals NULL) { print("Couldn't realloc :("); exit(1); }\
|
|
|
|
|
var = __resized_something;\
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* CLASSES
|
|
|
|
|
* These macros assist with creating classes.
|
2026-02-07 14:04:32 +11:00
|
|
|
*/
|
2026-02-06 18:39:35 +11:00
|
|
|
|
|
|
|
|
#define constructor(class, ...) class new##class(__VA_ARGS__)
|
2026-02-07 14:04:32 +11:00
|
|
|
#define destructor(class, ...) void destroy##class(class* self, ##__VA_ARGS__)
|
2026-02-06 18:39:35 +11:00
|
|
|
|
2026-02-07 14:04:32 +11:00
|
|
|
#define Destructor(class) void (*destructor_fn)(struct class* self)
|
|
|
|
|
|
|
|
|
|
#define Method(class, name, return, ...) return (*name)(struct class* self, ##__VA_ARGS__)
|
|
|
|
|
#define method(class, name, return, ...) return __##class##_##name(class* self, ##__VA_ARGS__)
|
|
|
|
|
|
|
|
|
|
#define class(className, body) struct className; typedef struct className body className
|
2026-02-06 18:39:35 +11:00
|
|
|
|
|
|
|
|
#define entry Integer main(Integer argc, String list argv)
|
|
|
|
|
|
2026-02-07 14:04:32 +11:00
|
|
|
static inline Integer newInteger() {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
static inline Float newFloat() {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
static inline Double newDouble() {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
static inline Character newCharacter() {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
static inline String newString() {
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
static inline Boolean newBoolean() {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-06 18:39:35 +11:00
|
|
|
static inline void destroyInteger(Integer* self) {}
|
|
|
|
|
static inline void destroyFloat(Float* self) {}
|
|
|
|
|
static inline void destroyDouble(Double* self) {}
|
|
|
|
|
static inline void destroyCharacter(Character* self) {}
|
|
|
|
|
static inline void destroyString(String* self) {}
|
|
|
|
|
static inline void destroyBoolean(Boolean* self) {}
|
|
|
|
|
|
|
|
|
|
#endif
|