Skip to content

Commit e68afcc

Browse files
committed
Initial commit
0 parents  commit e68afcc

File tree

13 files changed

+809
-0
lines changed

13 files changed

+809
-0
lines changed

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Youssef Elshabasy
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Core
2+
3+
Core is a collection of reusable C general purpose functions as well as generic data structures.
4+
5+
## Usage
6+
7+
```c
8+
#include <core/Core.h>
9+
#include <stdio.h>
10+
11+
#define ListElement Int
12+
#include <core/collections/List.h>
13+
14+
#define ListElement Char
15+
#include <core/collections/List.h>
16+
17+
Int32 main() {
18+
var index = ListDefault(Int)();
19+
var chars = ListDefault(Char)();
20+
21+
for (var i = 0; i < 26; ++i) {
22+
ListAppend(Int)(&index, i);
23+
ListAppend(Char)(&chars, 'a' + i);
24+
}
25+
26+
for (var i = 0; i < ListCount(Int)(&index); ++i) {
27+
printf("%d: ", ListAt(Int)(&index, i));
28+
printf("%c\n", ListAt(Char)(&chars, i));
29+
}
30+
31+
ListDestroy(Int)(list);
32+
ListDestroy(Char)(chars);
33+
34+
return 0;
35+
}
36+
```
37+
38+
## Contributing
39+
40+
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
41+
42+
## License
43+
44+
[MIT](LICENSE)

core/Core.h

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
3+
#define var __auto_type
4+
5+
#define null ((void*)0)
6+
7+
typedef struct {} Unit;
8+
9+
typedef bool Bool;
10+
11+
typedef unsigned char Char;
12+
typedef unsigned int Rune;
13+
14+
typedef unsigned char UInt8;
15+
typedef signed char Int8;
16+
17+
typedef unsigned short UInt16;
18+
typedef signed short Int16;
19+
20+
typedef unsigned int UInt32;
21+
typedef signed int Int32;
22+
23+
typedef unsigned long long UInt64;
24+
typedef signed long long Int64;
25+
26+
typedef unsigned long UInt;
27+
typedef signed long Int;
28+
29+
typedef float Float32;
30+
typedef double Float64;

core/Generic.h

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#pragma once
2+
3+
#define GENERIC(Name, T) Name##_##T
4+
#define GENERIC2(Name, T1, T2) Name##_##T1##_##T2
5+
#define GENERIC3(Name, T1, T2, T3) Name##_##T1##_##T2##_##T3
6+
#define GENERIC4(Name, T1, T2, T3, T4) Name##_##T1##_##T2##_##T3##_##T4
7+
#define GENERIC5(Name, T1, T2, T3, T4, T5) Name##_##T1##_##T2##_##T3##_##T4##_##T5
8+
#define GENERIC6(Name, T1, T2, T3, T4, T5, T6) Name##_##T1##_##T2##_##T3##_##T4##_##T5##_##T6
9+
#define GENERIC7(Name, T1, T2, T3, T4, T5, T6, T7) Name##_##T1##_##T2##_##T3##_##T4##_##T5##_##T6##_##T7
10+
#define GENERIC8(Name, T1, T2, T3, T4, T5, T6, T7, T8) Name##_##T1##_##T2##_##T3##_##T4##_##T5##_##T6##_##T7##_##T8

core/Hash.h

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#pragma once
2+
3+
#include <core/Core.h>
4+
5+
#define IsEven(num) ((num & 1) == 0)
6+
7+
static Bool IsPrime(UInt num) {
8+
if (num == 2 || num == 3) {
9+
return true;
10+
}
11+
12+
if (num == 1 || IsEven(num)) {
13+
return false;
14+
}
15+
16+
for (var divisor = 3UL; divisor * divisor <= num; divisor += 2) {
17+
if (num % divisor == 0) {
18+
return false;
19+
}
20+
}
21+
22+
return true;
23+
}
24+
25+
static UInt NextPrime(UInt num) {
26+
if (IsEven(num)) {
27+
++num;
28+
}
29+
30+
while (!IsPrime(num)) {
31+
num += 2;
32+
}
33+
34+
return num;
35+
}

core/Option.h

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef OptionValue
2+
#error "Type parameter 'OptionValue' is not defined."
3+
#define OptionValue int
4+
#endif
5+
6+
#include <core/Generic.h>
7+
8+
#ifndef Option
9+
typedef enum {
10+
Option_None,
11+
Option_Some,
12+
} OptionTag;
13+
14+
#define Option(OptionValue) GENERIC(Option, OptionValue)
15+
#define OptionNone(OptionValue) GENERIC(None, OptionValue)
16+
#define OptionSome(OptionValue) GENERIC(Some, OptionValue)
17+
#endif
18+
19+
typedef struct {
20+
OptionValue value;
21+
OptionTag tag;
22+
} Option(OptionValue);
23+
24+
static Option(OptionValue) OptionNone(OptionValue)() {
25+
return (Option(OptionValue)){
26+
.value = (OptionValue){},
27+
.tag = Option_None,
28+
};
29+
}
30+
31+
static Option(OptionValue) OptionSome(OptionValue)(OptionValue value) {
32+
return (Option(OptionValue)){
33+
.value = value,
34+
.tag = Option_Some,
35+
};
36+
}
37+
38+
#undef OptionValue

core/String.c

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include <core/String.h>
2+
3+
String StringDefault() {
4+
return (String){
5+
.utf8 = ListDefault(UInt8)(),
6+
};
7+
}
8+
9+
String StringCreate(char const* cString) {
10+
var string = StringDefault();
11+
12+
for (; *cString; ++cString) {
13+
ListAppend(UInt8)(&string.utf8, *cString);
14+
}
15+
16+
return string;
17+
}
18+
19+
UInt StringCount(String const* string) {
20+
return ListCount(UInt8)(&string->utf8);
21+
}
22+
23+
int RuneToUTF8(Rune rune, UInt8* utf8) {
24+
if (rune <= 0x7F) {
25+
utf8[0] = rune;
26+
return 1;
27+
}
28+
else if (rune <= 0x7FF) {
29+
utf8[0] = 0xC0 | (rune >> 6);
30+
utf8[1] = 0x80 | (rune & 0x3F);
31+
return 2;
32+
}
33+
else if (rune <= 0xFFFF) {
34+
utf8[0] = 0xE0 | (rune >> 12);
35+
utf8[1] = 0x80 | ((rune >> 6) & 0x3F);
36+
utf8[2] = 0x80 | (rune & 0x3F);
37+
return 3;
38+
}
39+
else if (rune <= 0x10FFFF) {
40+
utf8[0] = 0xF0 | (rune >> 18);
41+
utf8[1] = 0x80 | ((rune >> 12) & 0x3F);
42+
utf8[2] = 0x80 | ((rune >> 6) & 0x3F);
43+
utf8[3] = 0x80 | (rune & 0x3F);
44+
return 4;
45+
}
46+
47+
return 0;
48+
}
49+
50+
void StringAppend(String* string, Rune rune) {
51+
var utf8 = (UInt8[4]){};
52+
var count = RuneToUTF8(rune, utf8);
53+
54+
for (var i = 0; i < count; ++i) {
55+
ListAppend(UInt8)(&string->utf8, utf8[i]);
56+
}
57+
}
58+
59+
Array(UInt8) StringToBytes(String const* string) {
60+
var bytes = ArrayCreateWithCapacity(UInt8)(StringCount(string));
61+
62+
for (var i = 0; i < StringCount(string); ++i) {
63+
ArraySetAt(UInt8)(&bytes, i, ListAt(UInt8)(&string->utf8, i));
64+
}
65+
66+
return bytes;
67+
}
68+
69+
void StringDestroy(String string) {
70+
ListDestroy(UInt8)(string.utf8);
71+
}

core/String.h

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
#define ListElement UInt8
4+
#include <core/collections/List.h>
5+
6+
typedef struct {
7+
List(UInt8) utf8;
8+
} String;
9+
10+
String StringDefault();
11+
12+
String StringCreate(char const* cString);
13+
14+
UInt StringCount(String const* string);
15+
16+
void StringAppend(String* string, Rune rune);
17+
18+
Array(UInt8) StringToBytes(String const* string);
19+
20+
void StringDestroy(String string);

core/Tuple.h

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
#ifndef TupleArgs
2+
#error "Define 'TupleArgs' to specify tuple arity."
3+
#endif
4+
5+
#if TupleArgs < 2
6+
#error "Tuple arity must be at least 2."
7+
#endif
8+
9+
#if TupleArgs > 8
10+
#error "Tuple arity must be at most 8."
11+
#endif
12+
13+
#ifndef TupleT0
14+
#error "Type parameter 'TupleT0' is not defined."
15+
#endif
16+
17+
#ifndef TupleT1
18+
#error "Type parameter 'TupleT1' is not defined."
19+
#endif
20+
21+
#if TupleArgs >= 3
22+
#ifndef TupleT2
23+
#error "Type parameter 'TupleT2' is not defined."
24+
#endif
25+
#endif
26+
27+
#if TupleArgs >= 4
28+
#ifndef TupleT3
29+
#error "Type parameter 'TupleT3' is not defined."
30+
#endif
31+
#endif
32+
33+
#if TupleArgs >= 5
34+
#ifndef TupleT4
35+
#error "Type parameter 'TupleT4' is not defined."
36+
#endif
37+
#endif
38+
39+
#if TupleArgs >= 6
40+
#ifndef TupleT5
41+
#error "Type parameter 'TupleT5' is not defined."
42+
#endif
43+
#endif
44+
45+
#if TupleArgs >= 7
46+
#ifndef TupleT6
47+
#error "Type parameter 'TupleT6' is not defined."
48+
#endif
49+
#endif
50+
51+
#if TupleArgs == 8
52+
#ifndef TupleT7
53+
#error "Type parameter 'TupleT7' is not defined."
54+
#endif
55+
#endif
56+
57+
#include <core/Core.h>
58+
#include <core/Generic.h>
59+
60+
#ifndef Tuple
61+
#define Tuple(TupleT0, TupleT1) GENERIC2(Tuple, TupleT0, TupleT1)
62+
#define Tuple2(TupleT0, TupleT1) GENERIC2(Tuple, TupleT0, TupleT1)
63+
#define Tuple3(TupleT0, TupleT1, TupleT2) GENERIC3(Tuple, TupleT0, TupleT1, TupleT2)
64+
#define Tuple4(TupleT0, TupleT1, TupleT2, TupleT3) GENERIC4(Tuple, TupleT0, TupleT1, TupleT2, TupleT3)
65+
#define Tuple5(TupleT0, TupleT1, TupleT2, TupleT3, TupleT4) GENERIC5(Tuple, TupleT0, TupleT1, TupleT2, TupleT3, TupleT4)
66+
#define Tuple6(TupleT0, TupleT1, TupleT2, TupleT3, TupleT4, TupleT5) GENERIC6(Tuple, TupleT0, TupleT1, TupleT2, TupleT3, TupleT4, TupleT5)
67+
#define Tuple7(TupleT0, TupleT1, TupleT2, TupleT3, TupleT4, TupleT5, TupleT6) GENERIC7(Tuple, TupleT0, TupleT1, TupleT2, TupleT3, TupleT4, TupleT5, TupleT6)
68+
#define Tuple8(TupleT0, TupleT1, TupleT2, TupleT3, TupleT4, TupleT5, TupleT6, TupleT7) GENERIC8(Tuple, TupleT0, TupleT1, TupleT2, TupleT3, TupleT4, TupleT5, TupleT6, TupleT7)
69+
#endif
70+
71+
typedef struct {
72+
TupleT0 _0;
73+
TupleT1 _1;
74+
75+
#if TupleArgs >= 3
76+
TupleT2 _2;
77+
#endif
78+
79+
#if TupleArgs >= 4
80+
TupleT3 _3;
81+
#endif
82+
83+
#if TupleArgs >= 5
84+
TupleT4 _4;
85+
#endif
86+
87+
#if TupleArgs >= 6
88+
TupleT5 _5;
89+
#endif
90+
91+
#if TupleArgs >= 7
92+
TupleT6 _6;
93+
#endif
94+
95+
#if TupleArgs == 8
96+
TupleT7 _7;
97+
#endif
98+
}
99+
#if TupleArgs == 2
100+
Tuple(TupleT0, TupleT1);
101+
#elif TupleArgs == 3
102+
Tuple3(TupleT0, TupleT1, TupleT2);
103+
#elif TupleArgs == 4
104+
Tuple4(TupleT0, TupleT1, TupleT2, TupleT3);
105+
#elif TupleArgs == 5
106+
Tuple5(TupleT0, TupleT1, TupleT2, TupleT3, TupleT4);
107+
#elif TupleArgs == 6
108+
Tuple6(TupleT0, TupleT1, TupleT2, TupleT3, TupleT4, TupleT5);
109+
#elif TupleArgs == 7
110+
Tuple7(TupleT0, TupleT1, TupleT2, TupleT3, TupleT4, TupleT5, TupleT6);
111+
#elif TupleArgs == 8
112+
Tuple8(TupleT0, TupleT1, TupleT2, TupleT3, TupleT4, TupleT5, TupleT6, TupleT7);
113+
#endif

0 commit comments

Comments
 (0)