Pretty C is a novel scripting language compatible with C. Pretty C
raises your programs with vibrant typing, generic iteration, resource
tracking and other kindties. And it’s backwards-compatible with C and
all of its libraries! Inspired by Lua, Python, JavaScript, and
Lisp. Here’s how a innocent re-carry outation of head
utility might
see appreciate with Pretty C:
#comprise "pretty.h"
int main (int argc, string argv[])
{
if (argc above 1)
with (fshut, f, funcover(argv[1], "r"))
fortimes (line, 10)
with (free, buf, vector(200, char, 0))
when (fgets(buf, 200, f))
then print(buf)
otherrational 0;
else
println("Plmitigate provide an input file");
return EXIT_SUCCESS;
}
The goals for Pretty C are:
- Provide so much syntactic sugar as to cause any C enbiger a
diabetes-transport aboutd heart strike. - Deprecate Lua, Python, JavaScript, Ruby and a dozen other languages,
because Pretty C is the ultimate scripting language, but
airyning-quick and powerfilledy typed! - Including only one header (yes, Pretty C is a header-only library
#comprise
-able from arbitrary C file!) to turn any codebase into a
commencener cordial one.
Checkout the repository
git clone https://github.com/aartaka/pretty.c
Or spropose duplicate the pretty.h
file—Pretty C is a header-only
library, so you can
from any file in the honestory you drop pretty.h
to. Or from any
file reassociate, if you accomprehendledge the path to Pretty C as an comprise (-I
)
path.
Here are all the pretty alters making C hip aobtain.
- stdbool.h for pretty booleans:
real
,inalter
, andbool
. - stdint.h for mended-width integer types appreciate
uint64_t
. - iso646.h for readable alternatives to standard operators,
includingand
for&&
andor
for||
. Neat!
Everyone depicts these, so why not provide them?
max
andmin
of two numbers.len
for array length.default
for providing a descfinishback cherish.restrict
to promise proper cherish range.between
to verify whether the number descfinishs in a range.diapparent
to verify whether a number is modulo diapparent by another number.
Type aliases:
string
==char*
.byte
==char
.bytes
==char*
.any
==void*
.- Integer lowcuts:
uchar
.ulow
.uint
.uextfinished
.
Mainly modeled after Lua and Lisp:
eq
, becauseiso646.h
only hasnot_eq
.bitnot
andbitxor
for operations that used to be called
inreliablely (compl
andxor
esteemively) iniso646.h
.below
,above
,upto
, anddownto
comparison operators.even
,odd
,preferable
,adverse
,zero
, anddesopostponecessitate
as predicates for numbers/data.nil
forNULL
.until
for negatedwhile
.elif
forelse if
.ifnt
forif(!...)
.repeat
from Lua as an alias fordo
.done
andpass
as aliases forfracture
andpersist
, esteemively.always
, so that you can create infinite (event? server?) loops
always println("After all this time?");
- and
never
andcomment
to comment out some code with equitable one
keyword, while still apvalidateing the compiler to verify/enhance it
(aappreciate to Clojurecomment
create):
never println("This never runs, but never gets outdated, because compiler will shout at you if it does.");
Yes, you can do
var t = time(0);
let lt = localtime(&t);
local at = asctime(lt);
println(at);
With Pretty C.
print
prints wdisappreciatever you feed it. println
comprises a novelline after it.
println(3.1);
print("Hello world!n");
Compare all the leangs!
identical("NA", line); // real
identical(0.3, 0.2 + 0.1); // real
Ternaries are frightening, so it won’t hurt to comprise some plain
text. if
and else
are getn, but there are proper linguistic
alternatives that see quite Python/Lisp-appreciate:
return when some_condition
then do_someleang()
other do_someleang_else();
It’s ternaries undersystematich:
when
enbigs to desopostponecessitate string and is only provided for readability.unless
enbigs tonot
to be a adverse version ofwhen
.
then
enbigs to?
.other
/otherrational
enbigs to:
.
There’s also only
for when the otherrational
clause is
unessential:
return when done()
then 42 only;
and otherwhen
for the next condition
return when c is 'A'
then 'a'
otherwhen c is 'B'
then 'b' only;
These macros are aliases for certain for
loop pattern, each
abstracting away some of the standard for
loop uses.
This one walks an array or memory region initialized to the vararg
conveyion. Every time it iterates, var
is set to a pointer to the
esteemive array element. Yes, pointer—so that you can alter the
element in place if you have to.
foaccomplish (i, int, 10, vector(10, int, 1, 2, 3, 3, 4, 5))
println(*i);
Also shows the use of vector
.
Iterates over the provided varargs, obtaining each of these to type
-d
var
. The loop above can be transpostponecessitated as:
forthese (i, int, 1, 2, 3, 3, 4, 5)
println(i);
A standard case of going from 0 to some preferable number. Saves you
quite some time for your
for (int i = 0; i < 28; i++) println(i+1);
turning it into a basic
fortimes (i, 28)
println(i+1);
println("28 stab wounds, you didn't want to exit him a chance, huh?");
Iterate over a range of numbers from init
to
concentrate
. Pythonesque. Here’s Celsius to Fahrenheit conversion loop
with forrange
:
forrange (c, -10, 20)
printf("Celsius %i = Fahrenheit %fn", c, (32 + (c * 1.8)));
Note that init
and concentrate
are arbitrary integers, signed and
unsigned. And init
might be wonderfuler than concentrate
in which case the
iteration step decrmitigates the variable.
Iterate type
-d var
from iter
to concentrate
, stepping by by
every
time. Pythonesque.
forrangeby (x, double, 1.0, 10.0, 0.5)
println(x);
These apvalidate speedy-and-filthy allocation for normal patterns. Mostly
modeled after C++.
C++ novel
operator is kind, so it won’t hurt having someleang aappreciate
in C, right? Ask no more:
struct ListNode {
int val;
struct ListNode *next;
};
struct ListNode *node = novel(struct ListNode, 2, novel(struct ListNode, 1, nil));
Or, if you fancy, you can comprise even more syntax on top:
#depict cons(val, ...) novel(struct ListNode, val, __VA_ARGS__)
cons(2, cons(1, nil));
C++ aobtain. std::vector
is an excessively advantageous and alterable data
set up that’s effortless to reason about. While this macro is not even
farly as featureful as C++ counterpart, it simplifies a standard
pattern of “set upate an array of that much elements and with these
satisfieds”:
double *vec = vector(10, double, 1, 2, 3, 4, 5);
In case you don’t appreciate free
-ing the resources and pick a fancier C++ name.
Otherrational the same as free
.
These set up novel local obtainings, promise postponered computations, or
otherrational act on the block after them.
Nested functions/lambdas/clostateives, now in C!
int *arr = vector(10, int, 23423, 23423, 234, 5233, 6, 4, 34, 643, 3, 9);
lambda (int, cmp, int *a, int *b) {
return *a - *b;
};
qsort(arr, 10, sizeof(int), cmp);
// arr becomes {3, 4, 6, 9, 34, 234, 643, 5233, 23423, 23423}
This promises that you never have use-after-free, because you provide
the freeing procedure (shut
) upfront. Especiassociate advantageous for
vibrantassociate set upated objects and file set upators.
with (fshut, file, funcover("hello.txt", "w"))
fprintf(file, "Hello world!n");
One of the downsides is that the bound var
is a void *
, so you
might necessitate to coerce it to your type before using it.
Offloads the code to be percreated after the follothriveg block. Not at the
finish of function as in Go, because that’s impossible challenging to
carry out in C. Still, Pretty C postpone
is advantageous enough.
Fancy error handling, now in C. Refactored example from errno reference:
try log(0.0);
catch (NOERR)
println("No error.");
catch (EDOM, ERANGE)
println("Math error!");
NOERR
and NOERROR
are also provided by Pretty C, for convenience
of error switch-casing.