Add example and readme, update header
This commit is contained in:
105
README.md
Normal file
105
README.md
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
# zc
|
||||||
|
|
||||||
|
What if C, but easier?
|
||||||
|
|
||||||
|
## What is zc?
|
||||||
|
|
||||||
|
zc is a headerfile which makes a bunch of macros which mess with the way the C programming language works.
|
||||||
|
|
||||||
|
One of the primary advantages of using zc is easier object orientated patterns, without the bloat of C++. (The syntax does need a little getting used to.)
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo make install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
There are 2 ways to use zc:
|
||||||
|
|
||||||
|
* Inside of C - do `#include <zc.h>` and you've now got access to all that zc has to offer.
|
||||||
|
* Using a .zc file and the zc command - you won't be yelled at as much. Type `zc filename.zc` to compile.
|
||||||
|
|
||||||
|
However, using either will allow you to program in the same way.
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
This section is WIP
|
||||||
|
|
||||||
|
Define an entry point:
|
||||||
|
|
||||||
|
```c
|
||||||
|
entry {
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Create variables:
|
||||||
|
|
||||||
|
```c
|
||||||
|
entry {
|
||||||
|
Integer x is 5;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Print something out:
|
||||||
|
|
||||||
|
```c
|
||||||
|
entry {
|
||||||
|
Integer x is 5;
|
||||||
|
print(x);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a list of something:
|
||||||
|
|
||||||
|
```c
|
||||||
|
entry {
|
||||||
|
Integer list x is many(Integer, 5);
|
||||||
|
x[0] is 5;
|
||||||
|
x[1] is 10;
|
||||||
|
x[2] is 15;
|
||||||
|
x[3] is 20;
|
||||||
|
x[4] is 25;
|
||||||
|
|
||||||
|
// Resize the list
|
||||||
|
resize(x, 10);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a class, constructor, destructor, and methods:
|
||||||
|
|
||||||
|
```c
|
||||||
|
class(Car, {
|
||||||
|
String make;
|
||||||
|
Integer year;
|
||||||
|
Method(Car, drive, void);
|
||||||
|
Destructor(Car);
|
||||||
|
});
|
||||||
|
|
||||||
|
method(Car, drive, void) {
|
||||||
|
// self allows you to access elements inside the class
|
||||||
|
printf("Car %s from %d goes vroom vroom\n", self->make, self->year);
|
||||||
|
}
|
||||||
|
|
||||||
|
destructor(Car) {
|
||||||
|
free(self->make);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(Car, String make, Integer year) {
|
||||||
|
return (Car) {
|
||||||
|
.make = make,
|
||||||
|
.year = year,
|
||||||
|
.drive = &__Car_drive,
|
||||||
|
.destructor_fn = &destroyCar,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
entry {
|
||||||
|
Car myCar = newCar("Toyota", 1996);
|
||||||
|
myCar.drive(&myCar);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
See `bank.zc` for a full example.
|
||||||
93
bank.zc
Normal file
93
bank.zc
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
class(BankAccount, {
|
||||||
|
Integer money;
|
||||||
|
String name;
|
||||||
|
Method(BankAccount, deposit, Integer, Integer amount);
|
||||||
|
Method(BankAccount, withdraw, Integer, Integer amount);
|
||||||
|
Method(BankAccount, getAmount, Integer);
|
||||||
|
Destructor(BankAccount);
|
||||||
|
});
|
||||||
|
|
||||||
|
method(BankAccount, deposit, Integer, Integer amount) {
|
||||||
|
self->money += amount;
|
||||||
|
return self->money;
|
||||||
|
}
|
||||||
|
|
||||||
|
method(BankAccount, withdraw, Integer, Integer amount) {
|
||||||
|
self->money -= amount;
|
||||||
|
return self->money;
|
||||||
|
}
|
||||||
|
|
||||||
|
method(BankAccount, getAmount, Integer) {
|
||||||
|
return self->money;
|
||||||
|
}
|
||||||
|
|
||||||
|
destructor(BankAccount) {}
|
||||||
|
|
||||||
|
constructor(BankAccount, String name) {
|
||||||
|
return (BankAccount) {
|
||||||
|
.money = 10,
|
||||||
|
.name = name,
|
||||||
|
.deposit = &__BankAccount_deposit,
|
||||||
|
.withdraw = &__BankAccount_withdraw,
|
||||||
|
.getAmount = &__BankAccount_getAmount,
|
||||||
|
.destructor_fn = &destroyBankAccount
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class(Bank, {
|
||||||
|
Integer size;
|
||||||
|
Integer capacity;
|
||||||
|
BankAccount list accounts;
|
||||||
|
Method(Bank, addAccount, BankAccount*, BankAccount account);
|
||||||
|
Method(Bank, getAccount, BankAccount*, String name);
|
||||||
|
Destructor(Bank);
|
||||||
|
});
|
||||||
|
|
||||||
|
method(Bank, addAccount, BankAccount*, BankAccount account) {
|
||||||
|
if (self->size plus 1 greaterorequalto self->capacity) {
|
||||||
|
resize(self->accounts, self->capacity * 2);
|
||||||
|
}
|
||||||
|
self->accounts[self->size] = account;
|
||||||
|
self->size increment;
|
||||||
|
return &self->accounts[self->size - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
method(Bank, getAccount, BankAccount*, String name) {
|
||||||
|
for (Integer i = 0; i lessthan self->size; i increment) {
|
||||||
|
if (strcmp(name, self->accounts[i].name) equals 0) {
|
||||||
|
return &self->accounts[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
destructor(Bank) {
|
||||||
|
for (Integer i = 0; i lessthan self->size; i increment) {
|
||||||
|
forget(self->accounts[i]);
|
||||||
|
}
|
||||||
|
free(self->accounts);
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(Bank) {
|
||||||
|
return (Bank) {
|
||||||
|
.size = 0,
|
||||||
|
.capacity = 32,
|
||||||
|
.accounts = many(BankAccount, 32),
|
||||||
|
.addAccount = &__Bank_addAccount,
|
||||||
|
.getAccount = &__Bank_getAccount,
|
||||||
|
.destructor_fn = &destroyBank
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
entry {
|
||||||
|
Bank myBank = newBank();
|
||||||
|
myBank.addAccount(&myBank, newBankAccount("Maxwell"));
|
||||||
|
myBank.addAccount(&myBank, newBankAccount("John Citizen"));
|
||||||
|
myBank.addAccount(&myBank, newBankAccount("Jane Citizen"));
|
||||||
|
|
||||||
|
BankAccount* max = myBank.getAccount(&myBank, "Maxwell");
|
||||||
|
max->deposit(max, 100);
|
||||||
|
print(max->getAmount(max));
|
||||||
|
}
|
||||||
61
zc.h
61
zc.h
@@ -1,18 +1,23 @@
|
|||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
# This is under construction!
|
|
||||||
|
|
||||||
# zc compiler (in a Bash script)
|
# zc compiler (in a Bash script)
|
||||||
# If you dont want to write in the style of C, write as a zc script!
|
# If you dont want to write in the style of C, write as a .zc script!
|
||||||
# What this does:
|
# What this does:
|
||||||
# * Creates a .zcbuild folder
|
# * Creates a .zc-build folder
|
||||||
# * Adds some boilerplate
|
# * Adds some boilerplate
|
||||||
# * Inserts your code
|
# * Inserts your code
|
||||||
# * Compiles and produces an executable
|
# * 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.
|
# Alternatively, you can use zc as a C library, if you wish.
|
||||||
|
|
||||||
echo "Work in progress! Please come back later"
|
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
|
||||||
|
|
||||||
exit
|
exit
|
||||||
|
|
||||||
@@ -21,6 +26,12 @@ exit
|
|||||||
#ifndef ZC_H
|
#ifndef ZC_H
|
||||||
#define 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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@@ -64,6 +75,8 @@ exit
|
|||||||
#define and &&
|
#define and &&
|
||||||
#define or ||
|
#define or ||
|
||||||
|
|
||||||
|
#define pass (void)0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TYPES
|
* TYPES
|
||||||
* Creates friendlier names for different types.
|
* Creates friendlier names for different types.
|
||||||
@@ -102,19 +115,15 @@ default: printf("unknown type\n") \
|
|||||||
__new_something;\
|
__new_something;\
|
||||||
end)
|
end)
|
||||||
|
|
||||||
#define newlist(...) (then\
|
|
||||||
void* __new_something is malloc(sizeof({__VA_ARGS__}));\
|
|
||||||
if (__new_something equals NULL) { print("Couldn't malloc :("); exit(1); }\
|
|
||||||
__new_something;\
|
|
||||||
end)
|
|
||||||
|
|
||||||
#define many(x, size) (then\
|
#define many(x, size) (then\
|
||||||
x* __new_something is malloc(sizeof(x) * size);\
|
x* __new_something is malloc(sizeof(x) * size);\
|
||||||
if (__new_something equals NULL) { print("Couldn't malloc :("); exit(1); }\
|
if (__new_something equals NULL) { print("Couldn't malloc :("); exit(1); }\
|
||||||
__new_something;\
|
__new_something;\
|
||||||
end)
|
end)
|
||||||
|
|
||||||
#define forget free
|
#define forget(var) _Generic((var), \
|
||||||
|
default: var.destructor_fn(&var) \
|
||||||
|
)
|
||||||
|
|
||||||
#define resize(var, size) then\
|
#define resize(var, size) then\
|
||||||
typeof(*var)* __resized_something is realloc(var, sizeof(typeof(*var)) * size);\
|
typeof(*var)* __resized_something is realloc(var, sizeof(typeof(*var)) * size);\
|
||||||
@@ -128,12 +137,36 @@ end
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define constructor(class, ...) class new##class(__VA_ARGS__)
|
#define constructor(class, ...) class new##class(__VA_ARGS__)
|
||||||
// #define destructor(class, ...) void destroy##class(class* self, __VA_ARGS__)
|
#define destructor(class, ...) void destroy##class(class* self, ##__VA_ARGS__)
|
||||||
|
|
||||||
#define class typedef struct
|
#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)
|
#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 destroyInteger(Integer* self) {}
|
||||||
static inline void destroyFloat(Float* self) {}
|
static inline void destroyFloat(Float* self) {}
|
||||||
static inline void destroyDouble(Double* self) {}
|
static inline void destroyDouble(Double* self) {}
|
||||||
|
|||||||
Reference in New Issue
Block a user