It seems like the compiler allocates memory a lot, and is very optimistic in assuming a) the allocation will succeed and b) strings won't exceed 999 characters plus a null terminator.
Seeing how many variables are declared and used like
int *myDictLen = malloc(sizeof(int));
*myDictLen = 0;
I strongly suspect that the author is basically unaware of the & address operator. I would suggest that learning C syntax is a prerequisite to improving it.
You shouldn't new or malloc unless you need to. The more you allocate the more you leak.
Just stack/automatically allocate the resource and take the address with & then pass the pointer around. Because the data is automatically cleaned up you know you won't have any leaks (and certain whole other classes of bugs).
EDIT - Consider:
int myDictLen = 0;
int* myDictLenPtr = &myDictLen;
/* now you can pass around the pointer myDictLenPtr
to functions that can used an int* and it will be
available in this scope and automatically cleaned
up for you. */
If a function takes an argument of type pointer-to-int, you can simply pass a reference to an int variable on the stack with "&myInt". The code in question seems to be using heap allocation just to get a pointer-to-int, which makes one suspect that the author doesn't know about the & operator.
Sure you can, it just won't be "right." It depends on your use case and target audience if you care about "right" vs "functional." I'd say anyone who wants to really understand how programming works, should write at least one toy compiler/interpreter. It's interesting the kinds of insights you can pickup trying to pull that off.
Getting back to this particular case, there's something to be said for the idea of learning C before trying to replace C. C certainly isn't a flawless language, but now it's hard to have much faith that OP knows it well enough to understand its flaws.
Is this intended to replace C? I don't see anything that suggests that's what this project is about.
All I see is "C with different syntax". That could easily be a challenging side project whilst learning compilers / language design.
I've always found changing things up a useful means of practice. I wanted to learn how HTTP servers worked. I wanted to learn more Lisp. I implemented it in Common Lisp. I learned a lot.
As a point of reference, implementing a broken, partially complete, and definitely error filled version of Scheme on C is how I finally wrapped my head around Lisp. I'd been running into that one for a long time before figuring out.
The comma operator has more uses than that. One of them is to introduce some needed side effect in a sequence of definitions, without introducing a statement (out of esthetics, or C90 compatibility concerns):
{
int x = (side_effect(), initializing_expr());
int y = x + 42;
From C99 onward, this could be:
{
side_effect();
int x = initializing_expr();
int y = x + 2;
We use the comma operator in for loops because it has places in its syntax which take one expression. This limitation can arise in other contexts, like some macro MAC(E) where E must be a single expression. If want to to have two sequenced effects in there, we can use MAC((eff1, eff2)).