#if 0 # zc compiler (in a Bash script) # If you dont want to write in the style of C, write as a .zc script! # What this does: # * Creates a .zc-build folder # * Adds some boilerplate # * Inserts your code # * Compiles and produces an executable # * Removes the .zc-build folder, unless there was an error, so you can debug # Alternatively, you can use zc as a C library, if you wish. set -e mkdir -p .zc-build echo "#include " > .zc-build/main.c cat "$@" >> .zc-build/main.c gcc .zc-build/main.c rm -r .zc-build exit #endif #ifndef ZC_H #define ZC_H /* * zc - What if C, but easier? * A work in progress project by Maxwell Jeffress * Licenced to you under the MIT license. */ #include #include #include #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 || #define pass (void)0 /* * 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) #define forget(var) _Generic((var), \ default: var.destructor_fn(&var) \ ) #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. */ #define constructor(class, ...) class new##class(__VA_ARGS__) #define destructor(class, ...) void destroy##class(class* self, ##__VA_ARGS__) #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 #define entry Integer main(Integer argc, String list argv) 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; } 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