+1
.envrc
+1
.envrc
···
1
+
use flake
+16
LICENSE
+16
LICENSE
···
1
+
MIT No Attribution
2
+
3
+
Copyright <year> Sona Tau Estrada Rivera <sona@stau.space>
4
+
5
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this
6
+
software and associated documentation files (the "Software"), to deal in the Software
7
+
without restriction, including without limitation the rights to use, copy, modify,
8
+
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
9
+
permit persons to whom the Software is furnished to do so.
10
+
11
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
12
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
13
+
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
14
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
15
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
16
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+12
README.md
+12
README.md
+25
flake.lock
+25
flake.lock
···
1
+
{
2
+
"nodes": {
3
+
"nixpkgs": {
4
+
"locked": {
5
+
"lastModified": 1762111121,
6
+
"narHash": "sha256-4vhDuZ7OZaZmKKrnDpxLZZpGIJvAeMtK6FKLJYUtAdw=",
7
+
"rev": "b3d51a0365f6695e7dd5cdf3e180604530ed33b4",
8
+
"revCount": 888552,
9
+
"type": "tarball",
10
+
"url": "https://api.flakehub.com/f/pinned/NixOS/nixpkgs/0.1.888552%2Brev-b3d51a0365f6695e7dd5cdf3e180604530ed33b4/019a4ac5-41ea-7209-b0c4-883187b7dcdd/source.tar.gz"
11
+
},
12
+
"original": {
13
+
"type": "tarball",
14
+
"url": "https://flakehub.com/f/NixOS/nixpkgs/0.1"
15
+
}
16
+
},
17
+
"root": {
18
+
"inputs": {
19
+
"nixpkgs": "nixpkgs"
20
+
}
21
+
}
22
+
},
23
+
"root": "root",
24
+
"version": 7
25
+
}
+42
flake.nix
+42
flake.nix
···
1
+
{
2
+
description = "Declarations for the environment that this project will use.";
3
+
4
+
# Flake inputs
5
+
inputs.nixpkgs.url = "https://flakehub.com/f/NixOS/nixpkgs/0.1";
6
+
7
+
# Flake outputs
8
+
outputs = inputs:
9
+
let
10
+
# The systems supported for this flake
11
+
supportedSystems = [
12
+
"x86_64-linux" # 64-bit Intel/AMD Linux
13
+
"aarch64-linux" # 64-bit ARM Linux
14
+
"x86_64-darwin" # 64-bit Intel macOS
15
+
"aarch64-darwin" # 64-bit ARM macOS
16
+
];
17
+
18
+
# Helper to provide system-specific attributes
19
+
forEachSupportedSystem = f: inputs.nixpkgs.lib.genAttrs supportedSystems (system: f {
20
+
pkgs = import inputs.nixpkgs { inherit system; };
21
+
});
22
+
in
23
+
{
24
+
devShells = forEachSupportedSystem ({ pkgs }: {
25
+
default = pkgs.mkShell {
26
+
# The Nix packages provided in the environment
27
+
# Add any you need here
28
+
packages = with pkgs; [
29
+
gcc
30
+
gnumake
31
+
];
32
+
33
+
# Set any environment variables for your dev shell
34
+
env = { };
35
+
36
+
# Add any shell logic you want executed any time the environment is activated
37
+
shellHook = ''
38
+
'';
39
+
};
40
+
});
41
+
};
42
+
}
+72
src/list.h
+72
src/list.h
···
1
+
#ifndef LIST_H_
2
+
#define LIST_H_
3
+
/* ----- List definition ----- */
4
+
#ifndef LIST_IMPLEMENTATION
5
+
#define DefList(type) \
6
+
struct Node##type { \
7
+
type head; \
8
+
struct Node##type* rest; \
9
+
}; \
10
+
typedef struct Node##type* List##type; \
11
+
void List##type##_deinit(List##type list); \
12
+
type List##type##_car(struct Node##type node); \
13
+
struct Node##type* List##type##_cdr(struct Node##type node); \
14
+
List##type List##type##_cons(type a, List##type list); \
15
+
List##type List##type##_rev(List##type list, List##type a); \
16
+
List##type List##type##_reverse(List##type list); \
17
+
size_t List##type##_length(List##type list); \
18
+
type List##type##_at(List##type list, size_t index);
19
+
#else
20
+
#define DefList(type) \
21
+
struct Node##type { \
22
+
type head; \
23
+
struct Node##type* rest; \
24
+
}; \
25
+
typedef struct Node##type* List##type; \
26
+
\
27
+
void List##type##_deinit(List##type list) { \
28
+
if (list != NULL) { \
29
+
List##type##_deinit(list->rest); \
30
+
assert(list->rest == NULL); \
31
+
free(list); \
32
+
list = NULL; \
33
+
} \
34
+
} \
35
+
\
36
+
type List##type##_car(struct Node##type node) { \
37
+
List##type##_deinit(node.rest); \
38
+
return node.head; \
39
+
} \
40
+
\
41
+
struct Node##type* List##type##_cdr(struct Node##type node) { \
42
+
return node.rest; \
43
+
} \
44
+
\
45
+
List##type List##type##_cons(type a, List##type list) { \
46
+
struct Node##type* node = (struct Node##type*)calloc(sizeof(struct Node##type), 1); \
47
+
exists(node); \
48
+
*node = (struct Node##type){ .head = a, .rest = list }; \
49
+
return (List##type)node; \
50
+
} \
51
+
\
52
+
List##type List##type##_rev(List##type list, List##type a) { \
53
+
if (list != NULL) return List##type##_rev(list->rest, List##type##_cons(list->head, a)); \
54
+
else return a; \
55
+
} \
56
+
\
57
+
List##type List##type##_reverse(List##type list) { \
58
+
return List##type##_rev(list, NULL); \
59
+
} \
60
+
\
61
+
size_t List##type##_length(List##type list) { \
62
+
if (list != NULL) return List##type##_length(list->rest) + 1; \
63
+
else return 0; \
64
+
} \
65
+
\
66
+
type List##type##_at(List##type list, size_t index) { \
67
+
if (list != NULL) return index == 1 ? list->head : List##type##_at(list->rest, index - 1); \
68
+
else exists(NULL); \
69
+
return (type){0}; \
70
+
}
71
+
#endif
72
+
#endif // LIST_H_