This commit is contained in:
Zander Thannhauser 2025-01-13 20:36:07 -06:00
commit 86934f1895
479 changed files with 18103 additions and 0 deletions

7
.gitignore vendored Normal file
View file

@ -0,0 +1,7 @@
bin/
.build-all.db
junk

27
booleans/free.c Normal file
View file

@ -0,0 +1,27 @@
#include <stdlib.h>
#include <debug.h>
#include <value/free.h>
#include "struct.h"
#include "free.h"
void free_booleans(
struct booleans* this)
{
ENTER;
if (this)
{
free_value(this->true_value);
free_value(this->false_value);
free(this);
}
EXIT;
}

6
booleans/free.h Normal file
View file

@ -0,0 +1,6 @@
struct booleans;
void free_booleans(
struct booleans* this);

82
booleans/new.c Normal file
View file

@ -0,0 +1,82 @@
#include <debug.h>
#include <memory/smalloc.h>
#include <string/new.h>
#include <string/free.h>
#include <value/lambda/new.h>
#include <expression/variable/new.h>
#include <expression/lambda/new.h>
#include <expression/free.h>
#include "struct.h"
#include "new.h"
struct booleans* new_booleans(void)
{
ENTER;
struct booleans* this = smalloc(sizeof(*this));
struct string* x = new_string(L"x", 1);
struct string* y = new_string(L"y", 1);
{
struct expression* body = new_variable_expression(x);
struct expression* lambda_y = new_lambda_expression(y, body);
struct value* lambda_xy = new_lambda_value(NULL, x, lambda_y);
this->true_value = lambda_xy;
free_expression(lambda_y);
free_expression(body);
}
{
struct expression* body = new_variable_expression(y);
struct expression* lambda_y = new_lambda_expression(y, body);
struct value* lambda_xy = new_lambda_value(NULL, x, lambda_y);
this->false_value = lambda_xy;
free_expression(lambda_y);
free_expression(body);
}
free_string(x);
free_string(y);
EXIT;
return this;
}

3
booleans/new.h Normal file
View file

@ -0,0 +1,3 @@
struct booleans* new_booleans(void);

8
booleans/struct.h Normal file
View file

@ -0,0 +1,8 @@
struct booleans
{
struct value* true_value;
struct value* false_value;
};

59
build-all.py Executable file
View file

@ -0,0 +1,59 @@
#!/usr/bin/env python3
import subprocess;
import time;
import atexit;
import os;
import pickle;
PICKLEFILE = ".build-all.db"
try:
with open(PICKLEFILE, "rb") as stream:
ftimes = pickle.load(stream);
except:
ftimes = dict();
def dumpftimes():
with open(PICKLEFILE, "wb") as stream:
pickle.dump(ftimes, stream);
atexit.register(dumpftimes);
buildtypes = set();
for x in os.listdir("buildtypes"):
buildtype = x[:-4];
if buildtype not in ftimes:
ftimes[buildtype] = time.time();
buildtypes.add(buildtype);
for buildtype in sorted(buildtypes, key = lambda x: -ftimes[x]):
print("\033[32m" f"$ make buildtype={buildtype}" "\033[0m");
result = subprocess.run(["make", f"buildtype={buildtype}"]);
if result.returncode:
ftimes[buildtype] = time.time();
print("subcommand failed!");
exit(1);

View file

@ -0,0 +1,31 @@
-g
-I .
-D _GNU_SOURCE
-D DEBUG_BUILD
-D VALGRIND_BUILD
-Wall
-Werror
-Wfatal-errors
-Wstrict-prototypes
-Wextra
-Wdouble-promotion
-Wformat=2
-Wformat-truncation=2
-Wimplicit-fallthrough
-Wconversion
-Wshadow
-Wcast-align=strict
-Wformat-security
-Wnested-externs
-Wuninitialized
-Wmaybe-uninitialized
-Wswitch-default
-Wno-comment
-Wno-unused
-Wno-override-init

32
buildtypes/debug.txt Normal file
View file

@ -0,0 +1,32 @@
-g
-I .
-D _GNU_SOURCE
-D DEBUG_BUILD
-D VALGRIND_BUILD
-Wall
-Werror
-Wfatal-errors
-Wstrict-prototypes
-Wextra
-Wdouble-promotion
-Wformat=2
-Wformat-truncation=2
-Wimplicit-fallthrough
-Wconversion
-Wshadow
-Wcast-align=strict
-Wformat-security
-Wnested-externs
-Wuninitialized
-Wmaybe-uninitialized
-Wswitch-default
-Wno-comment
-Wno-unused
-Wno-override-init

30
buildtypes/release.txt Normal file
View file

@ -0,0 +1,30 @@
-I .
-D _GNU_SOURCE
-D RELEASE_BUILD
-O3
-Wall
-Werror
-Wfatal-errors
-Wstrict-prototypes
-Wextra
-Wdouble-promotion
-Wformat=2
-Wformat-truncation=2
-Wimplicit-fallthrough
-Wconversion
-Wshadow
-Wcast-align=strict
-Wformat-security
-Wnested-externs
-Wuninitialized
-Wmaybe-uninitialized
-Wswitch-default
-Wno-comment
-Wno-override-init
-Wno-unused-parameter

35
buildtypes/test-asan.txt Normal file
View file

@ -0,0 +1,35 @@
-g
-I .
-D _GNU_SOURCE
-D TEST_BUILD
-fsanitize=address
-static-libasan
-Wall
-Werror
-Wfatal-errors
-Wstrict-prototypes
-Wextra
-Wdouble-promotion
-Wformat=2
-Wformat-truncation=2
-Wimplicit-fallthrough
-Wconversion
-Wshadow
-Wcast-align=strict
-Wformat-security
-Wnested-externs
-Wuninitialized
-Wmaybe-uninitialized
-Wswitch
-Wswitch-default
-Wno-comment
-Wno-unused
-Wno-override-init

33
buildtypes/test-ubsan.txt Normal file
View file

@ -0,0 +1,33 @@
-g
-I .
-D _GNU_SOURCE
-D TEST_BUILD
-fsanitize=undefined
-Wall
-Werror
-Wfatal-errors
-Wstrict-prototypes
-Wextra
-Wdouble-promotion
-Wformat=2
-Wformat-truncation=2
-Wimplicit-fallthrough
-Wconversion
-Wshadow
-Wcast-align=strict
-Wformat-security
-Wnested-externs
-Wuninitialized
-Wmaybe-uninitialized
-Wswitch
-Wswitch-default
-Wno-comment
-Wno-unused
-Wno-override-init

31
buildtypes/test.txt Normal file
View file

@ -0,0 +1,31 @@
-g
-I .
-D _GNU_SOURCE
-D TEST_BUILD
-Wall
-Werror
-Wfatal-errors
-Wstrict-prototypes
-Wextra
-Wdouble-promotion
-Wformat=2
-Wformat-truncation=2
-Wimplicit-fallthrough
-Wconversion
-Wshadow
-Wcast-align=strict
-Wformat-security
-Wnested-externs
-Wuninitialized
-Wmaybe-uninitialized
-Wswitch
-Wswitch-default
-Wno-comment
-Wno-unused
-Wno-override-init

73
builtin/compare/eq.c Normal file
View file

@ -0,0 +1,73 @@
#include <assert.h>
#include <debug.h>
/*#include <number/add.h>*/
/*#include <number/free.h>*/
/*#include <value/number/struct.h>*/
/*#include <value/number/new.h>*/
#include <value/lazy/unlazy.h>
#include <value/free.h>
#include <value/builtin_lambda/struct.h>
#include "eq.h"
struct value* builtin_compare_eq(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail)
{
ENTER;
struct value* left = lazy_value_unlazy(prev->value, booleans);
struct value* right = lazy_value_unlazy(tail, booleans);
dpvp(left);
dpvp(right);
assert(left);
assert(right);
TODO;
#if 0
if (left->kind != vk_number || right->kind != vk_number)
{
TODO;
exit(1);
}
struct number* sum = number_add(
/* left: */ ((struct number_value*) left)->value,
/* right: */ ((struct number_value*) right)->value);
struct value* result = new_number_value(sum);
free_number(sum);
free_value(left);
free_value(right);
EXIT;
return result;
#endif
}

10
builtin/compare/eq.h Normal file
View file

@ -0,0 +1,10 @@
struct builtin_lambda_value;
struct value;
struct value* builtin_compare_eq(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail);

73
builtin/compare/gt.c Normal file
View file

@ -0,0 +1,73 @@
#include <assert.h>
#include <debug.h>
/*#include <number/add.h>*/
/*#include <number/free.h>*/
/*#include <value/number/struct.h>*/
/*#include <value/number/new.h>*/
#include <value/lazy/unlazy.h>
#include <value/free.h>
#include <value/builtin_lambda/struct.h>
#include "gt.h"
struct value* builtin_compare_gt(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail)
{
ENTER;
struct value* left = lazy_value_unlazy(prev->value, booleans);
struct value* right = lazy_value_unlazy(tail, booleans);
dpvp(left);
dpvp(right);
assert(left);
assert(right);
TODO;
#if 0
if (left->kind != vk_number || right->kind != vk_number)
{
TODO;
exit(1);
}
struct number* sum = number_add(
/* left: */ ((struct number_value*) left)->value,
/* right: */ ((struct number_value*) right)->value);
struct value* result = new_number_value(sum);
free_number(sum);
free_value(left);
free_value(right);
EXIT;
return result;
#endif
}

8
builtin/compare/gt.h Normal file
View file

@ -0,0 +1,8 @@
struct builtin_lambda_value;
struct value;
struct value* builtin_compare_gt(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail);

73
builtin/compare/gte.c Normal file
View file

@ -0,0 +1,73 @@
#include <assert.h>
#include <debug.h>
/*#include <number/add.h>*/
/*#include <number/free.h>*/
/*#include <value/number/struct.h>*/
/*#include <value/number/new.h>*/
#include <value/lazy/unlazy.h>
#include <value/free.h>
#include <value/builtin_lambda/struct.h>
#include "gte.h"
struct value* builtin_compare_gte(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail)
{
ENTER;
struct value* left = lazy_value_unlazy(prev->value, booleans);
struct value* right = lazy_value_unlazy(tail, booleans);
dpvp(left);
dpvp(right);
assert(left);
assert(right);
TODO;
#if 0
if (left->kind != vk_number || right->kind != vk_number)
{
TODO;
exit(1);
}
struct number* sum = number_add(
/* left: */ ((struct number_value*) left)->value,
/* right: */ ((struct number_value*) right)->value);
struct value* result = new_number_value(sum);
free_number(sum);
free_value(left);
free_value(right);
EXIT;
return result;
#endif
}

8
builtin/compare/gte.h Normal file
View file

@ -0,0 +1,8 @@
struct builtin_lambda_value;
struct value;
struct value* builtin_compare_gte(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail);

73
builtin/compare/lt.c Normal file
View file

@ -0,0 +1,73 @@
#include <assert.h>
#include <debug.h>
/*#include <number/add.h>*/
/*#include <number/free.h>*/
/*#include <value/number/struct.h>*/
/*#include <value/number/new.h>*/
#include <value/lazy/unlazy.h>
#include <value/free.h>
#include <value/builtin_lambda/struct.h>
#include "lt.h"
struct value* builtin_compare_lt(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail)
{
ENTER;
struct value* left = lazy_value_unlazy(prev->value, booleans);
struct value* right = lazy_value_unlazy(tail, booleans);
dpvp(left);
dpvp(right);
assert(left);
assert(right);
TODO;
#if 0
if (left->kind != vk_number || right->kind != vk_number)
{
TODO;
exit(1);
}
struct number* sum = number_add(
/* left: */ ((struct number_value*) left)->value,
/* right: */ ((struct number_value*) right)->value);
struct value* result = new_number_value(sum);
free_number(sum);
free_value(left);
free_value(right);
EXIT;
return result;
#endif
}

8
builtin/compare/lt.h Normal file
View file

@ -0,0 +1,8 @@
struct builtin_lambda_value;
struct value;
struct value* builtin_compare_lt(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail);

80
builtin/compare/lte.c Normal file
View file

@ -0,0 +1,80 @@
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include <debug.h>
#include <booleans/struct.h>
/*#include <number/new.h>*/
#include <number/compare.h>
/*#include <number/set_int.h>*/
/*#include <number/free.h>*/
#include <value/number/struct.h>
/*#include <value/number/new.h>*/
#include <value/lazy/unlazy.h>
#include <value/inc.h>
#include <value/free.h>
#include <value/builtin_lambda/struct.h>
#include "lte.h"
struct value* builtin_compare_lte(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail)
{
ENTER;
struct value* left = lazy_value_unlazy(prev->value, booleans);
struct value* right = lazy_value_unlazy(tail, booleans);
dpvp(left);
dpvp(right);
assert(left);
assert(right);
if (left->kind != vk_number || right->kind != vk_number)
{
TODO;
exit(1);
}
int cmp = compare_number(
/* left: */ ((struct number_value*) left)->value,
/* right: */ ((struct number_value*) right)->value);
struct value* result = inc_value(
cmp <= 0
? booleans->true_value
: booleans->false_value);
free_value(left);
free_value(right);
EXIT;
return result;
}

8
builtin/compare/lte.h Normal file
View file

@ -0,0 +1,8 @@
struct builtin_lambda_value;
struct value;
struct value* builtin_compare_lte(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail);

73
builtin/compare/neq.c Normal file
View file

@ -0,0 +1,73 @@
#include <assert.h>
#include <debug.h>
/*#include <number/add.h>*/
/*#include <number/free.h>*/
/*#include <value/number/struct.h>*/
/*#include <value/number/new.h>*/
#include <value/lazy/unlazy.h>
/*#include <value/free.h>*/
#include <value/builtin_lambda/struct.h>
#include "neq.h"
struct value* builtin_compare_neq(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail)
{
ENTER;
struct value* left = lazy_value_unlazy(prev->value, booleans);
struct value* right = lazy_value_unlazy(tail, booleans);
dpvp(left);
dpvp(right);
assert(left);
assert(right);
TODO;
#if 0
if (left->kind != vk_number || right->kind != vk_number)
{
TODO;
exit(1);
}
struct number* sum = number_add(
/* left: */ ((struct number_value*) left)->value,
/* right: */ ((struct number_value*) right)->value);
struct value* result = new_number_value(sum);
free_number(sum);
free_value(left);
free_value(right);
EXIT;
return result;
#endif
}

8
builtin/compare/neq.h Normal file
View file

@ -0,0 +1,8 @@
struct builtin_lambda_value;
struct value;
struct value* builtin_compare_neq(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail);

71
builtin/numeric/add.c Normal file
View file

@ -0,0 +1,71 @@
#include <stdlib.h>
#include <assert.h>
#include <debug.h>
#include <number/add.h>
#include <number/free.h>
#include <value/number/struct.h>
#include <value/number/new.h>
#include <value/lazy/unlazy.h>
#include <value/free.h>
#include <value/builtin_lambda/struct.h>
#include "add.h"
struct value* builtin_numeric_add(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail)
{
ENTER;
struct value* left = lazy_value_unlazy(prev->value, booleans);
struct value* right = lazy_value_unlazy(tail, booleans);
dpvp(left);
dpvp(right);
assert(left);
assert(right);
if (left->kind != vk_number || right->kind != vk_number)
{
TODO;
exit(1);
}
struct number* sum = number_add(
/* left: */ ((struct number_value*) left)->value,
/* right: */ ((struct number_value*) right)->value);
struct value* result = new_number_value(sum);
free_number(sum);
free_value(left);
free_value(right);
EXIT;
return result;
}

8
builtin/numeric/add.h Normal file
View file

@ -0,0 +1,8 @@
struct value;
struct builtin_lambda_value;
struct value* builtin_numeric_add(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail);

15
builtin/numeric/divide.c Normal file
View file

@ -0,0 +1,15 @@
#include <assert.h>
#include <debug.h>
#include "divide.h"
struct value* builtin_numeric_divide(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail)
{
TODO;
}

9
builtin/numeric/divide.h Normal file
View file

@ -0,0 +1,9 @@
struct booleans;
struct value;
struct builtin_lambda_value;
struct value* builtin_numeric_divide(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail);

View file

@ -0,0 +1,59 @@
#include <stdlib.h>
#include <assert.h>
#include <debug.h>
#include <number/multiply.h>
#include <number/free.h>
#include <value/number/struct.h>
#include <value/number/new.h>
#include <value/lazy/unlazy.h>
#include <value/free.h>
#include <value/builtin_lambda/struct.h>
#include "multiply.h"
struct value* builtin_numeric_multiply(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail)
{
ENTER;
struct value* left = lazy_value_unlazy(prev->value, booleans);
struct value* right = lazy_value_unlazy(tail, booleans);
dpvp(left);
dpvp(right);
assert(left);
assert(right);
if (left->kind != vk_number || right->kind != vk_number)
{
TODO;
exit(1);
}
struct number* sum = number_multiply(
/* left: */ ((struct number_value*) left)->value,
/* right: */ ((struct number_value*) right)->value);
struct value* result = new_number_value(sum);
free_number(sum);
free_value(left);
free_value(right);
EXIT;
return result;
}

View file

@ -0,0 +1,8 @@
struct value;
struct builtin_lambda_value;
struct value* builtin_numeric_multiply(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail);

View file

@ -0,0 +1,59 @@
#include <stdlib.h>
#include <assert.h>
#include <debug.h>
#include <number/subtract.h>
#include <number/free.h>
#include <value/number/struct.h>
#include <value/number/new.h>
#include <value/lazy/unlazy.h>
#include <value/free.h>
#include <value/builtin_lambda/struct.h>
#include "subtract.h"
struct value* builtin_numeric_subtract(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail)
{
ENTER;
struct value* left = lazy_value_unlazy(prev->value, booleans);
struct value* right = lazy_value_unlazy(tail, booleans);
dpvp(left);
dpvp(right);
assert(left);
assert(right);
if (left->kind != vk_number || right->kind != vk_number)
{
TODO;
exit(1);
}
struct number* difference = number_subtract(
/* left: */ ((struct number_value*) left)->value,
/* right: */ ((struct number_value*) right)->value);
struct value* result = new_number_value(difference);
free_number(difference);
free_value(left);
free_value(right);
EXIT;
return result;
}

View file

@ -0,0 +1,8 @@
struct value;
struct builtin_lambda_value;
struct value* builtin_numeric_subtract(
struct booleans* booleans,
struct builtin_lambda_value* prev,
struct value* tail);

16
cmdln/free.c Normal file
View file

@ -0,0 +1,16 @@
#include <stdlib.h>
#include <debug.h>
#include "free.h"
void free_cmdln_flags(
struct cmdln_flags* flags)
{
ENTER;
free(flags);
EXIT;
}

7
cmdln/free.h Normal file
View file

@ -0,0 +1,7 @@
struct cmdln_flags;
void free_cmdln_flags(
struct cmdln_flags* flags);

168
cmdln/new.c Normal file
View file

@ -0,0 +1,168 @@
#include <stdlib.h>
#include <assert.h>
#include <getopt.h>
#include <debug.h>
#include <memory/smalloc.h>
#include "struct.h"
#include "new.h"
struct cmdln_flags* new_cmdln_flags(
int argc, char* const* argv)
{
ENTER;
bool echo = false;
bool rainbow = false;
bool read_init_file = true;
const char* custom_init_path = "~/.13rc";
const char* input_string = NULL;
enum input_kind input_kind = ik_interactive;
static const struct option long_options[] = {
{"echo", no_argument, 0, 1},
{"echo-rainbow", no_argument, 0, 2},
{"no-init", no_argument, 0, 3},
{"custom-init-path", required_argument, 0, 4},
{"command", required_argument, 0, 'c'},
{0, 0, 0, 0}
};
for (int c; (c = getopt_long(argc, argv, ""
"\1\2\3\4c:\5\6"
"", long_options, NULL)) >= 0; )
{
switch (c)
{
case 1: // --echo
{
echo = true;
break;
}
case 2: // --echo-rainbow
{
echo = true;
rainbow = true;
break;
}
case 3: // --no-init
{
read_init_file = false;
break;
}
case 4: // --custom-init-path
{
custom_init_path = optarg;
break;
}
case 'c': // --command
{
switch (input_kind)
{
case ik_interactive:
{
input_kind = ik_string;
input_string = optarg;
dpvp(input_string);
break;
}
default:
TODO;
break;
}
break;
}
default:
TODO;
exit(1);
break;
}
}
struct cmdln_flags* flags = smalloc(sizeof(*flags));
switch (input_kind)
{
case ik_interactive:
{
if (argv[optind])
{
flags->input_file = argv[optind++];
flags->argv = &argv[optind++];
input_kind = ik_file;
}
break;
}
case ik_string:
{
flags->argv = &argv[optind];
break;
}
default:
TODO;
break;
}
flags->echo = echo;
flags->rainbow = rainbow;
flags->read_init_file = read_init_file;
flags->custom_init_path = custom_init_path;
flags->input_kind = input_kind;
flags->input_string = input_string;
EXIT;
return flags;
}

7
cmdln/new.h Normal file
View file

@ -0,0 +1,7 @@
struct cmdln_flags* new_cmdln_flags(
int argc, char* const* argv);

30
cmdln/struct.h Normal file
View file

@ -0,0 +1,30 @@
#include <stdbool.h>
enum input_kind
{
ik_string,
ik_file,
ik_interactive,
};
struct cmdln_flags
{
bool echo;
bool rainbow;
enum input_kind input_kind;
bool read_init_file;
const char* custom_init_path;
const char* input_string;
const char* input_file;
char* const* argv;
};

44
color_factory/free.c Normal file
View file

@ -0,0 +1,44 @@
#include <stdlib.h>
#include <debug.h>
#include <defines/N.h>
#include <string/free.h>
#include "struct.h"
#include "free.h"
void free_color_factory(
struct color_factory* this)
{
ENTER;
if (this)
{
for (unsigned i = 0; i < N(this->colors); i++)
{
free_string(this->colors[i]);
}
free_string(this->numeric);
free_string(this->string);
free_string(this->variable);
free_string(this->builtin);
free_string(this->reset);
free(this);
}
EXIT;
}

7
color_factory/free.h Normal file
View file

@ -0,0 +1,7 @@
struct color_factory;
void free_color_factory(
struct color_factory* this);

108
color_factory/new.c Normal file
View file

@ -0,0 +1,108 @@
#include <limits.h>
#include <math.h>
#include <debug.h>
#include <defines/N.h>
#include <memory/smalloc.h>
#include <string/new.h>
#include "struct.h"
#include "new.h"
struct rgb
{
uint8_t r, g, b;
};
static struct rgb hsv_to_rgb(double hue, double sat, double val)
{
double c = val * sat;
double x = c * (1 - fabs(fmod(hue / (M_PI / 3), 2) - 1));
double m = val - c;
double r, g, b;
if (hue < 1 * M_PI / 3) r = c, g = x, b = 0;
else if (hue < 2 * M_PI / 3) r = x, g = c, b = 0;
else if (hue < 3 * M_PI / 3) r = 0, g = c, b = x;
else if (hue < 4 * M_PI / 3) r = 0, g = x, b = c;
else if (hue < 5 * M_PI / 3) r = x, g = 0, b = c;
else r = c, g = 0, b = x;
return (struct rgb) {
(uint8_t) ((r + m) * 255),
(uint8_t) ((g + m) * 255),
(uint8_t) ((b + m) * 255)};
}
static struct string* new_color_from_hue(
double hue,
double sat,
double val)
{
ENTER;
dpvlf(hue);
dpvlf(sat);
dpvlf(val);
struct rgb rgb = hsv_to_rgb(hue, sat, val);
struct string* string = new_string_from_ascii_format(
"\e[38;2;%hhu;%hhu;%hhum", rgb.r, rgb.g, rgb.b);
EXIT;
return string;
}
struct color_factory* new_color_factory(void)
{
ENTER;
struct color_factory* this = smalloc(sizeof(*this));
for (unsigned i = 0, n = N(this->colors); i < n; i++)
{
this->colors[i] = new_color_from_hue(
/* hue: */ (double) i / N(this->colors) * 2 * M_PI,
/* sat: */ 0.9,
/* val: */ 1.0);
}
this->numeric = new_color_from_hue(31.0 / 180 * M_PI, 0.80, 1.0);
this->string = new_color_from_hue(300.0 / 180 * M_PI, 0.80, 1.0);
this->variable = new_color_from_hue(263.0 / 180 * M_PI, 0.80, 1.0);
this->builtin = new_color_from_hue(0.0, 0.0, 0.52);
this->reset = new_string(L"\e[0m", ULONG_MAX);
EXIT;
return this;
}

3
color_factory/new.h Normal file
View file

@ -0,0 +1,3 @@
struct color_factory* new_color_factory(void);

16
color_factory/struct.h Normal file
View file

@ -0,0 +1,16 @@
struct color_factory
{
struct string* colors[20];
struct string* numeric;
struct string* string;
struct string* variable;
struct string* builtin;
struct string* reset;
};

91
debug.c Normal file
View file

@ -0,0 +1,91 @@
#include <stdio.h>
int debug_depth;
void dpvs_implementation(
const char* expression,
char quote,
const unsigned char* string_value,
size_t len)
{
printf("%*s", debug_depth, "");
printf("%s = %c", expression, quote);
for (const unsigned char* m = string_value; len && *m; m++, len--)
{
switch (*m)
{
case ' ':
case '~':
case '@':
case '$':
case ',':
case '%':
case '^':
case '&':
case '\'':
case '*':
case '#':
case '`':
case ';':
case '.':
case '=':
case '/':
case '+':
case '-':
case '_':
case '!':
case ':':
case '<': case '>':
case '(': case ')':
case '[': case ']':
case '{': case '}':
case '0' ... '9':
case 'a' ... 'z':
case 'A' ... 'Z':
putchar(*m);
break;
case '\\':
printf("\\\\");
break;
case '\"':
printf("\\\"");
break;
case '\e':
printf("\\e");
break;
case '\n':
printf("\\n");
break;
default:
printf("\\x%02X", *m);
break;
}
}
printf("%c\n", quote);
}

282
debug.h Normal file
View file

@ -0,0 +1,282 @@
#if (defined(DEBUG_BUILD) || defined(TEST_BUILD))
#include <inttypes.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <fcntl.h>
#include <unistd.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
#include <wchar.h>
#include <math.h>
#include <getopt.h>
#include <sys/param.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <wchar.h>
#include <valgrind/memcheck.h>
struct statement;
struct tokenizer;
struct istream;
struct cmdln_flags;
struct istream_inheritance;
struct token;
struct position;
struct environment;
struct number;
struct mpq;
struct booleans;
#include <defines/argv0.h>
/*#include <defines/RES.h>*/
/*#include <macros/N.h>*/
/*#include <memory/smalloc.h>*/
/*#include <memory/srealloc.h>*/
/*#include <string/struct.h>*/
/*#include <string/new.h>*/
/*#include <string/inc.h>*/
/*#include <string/free.h>*/
/*#include <string/new.h>*/
/*#include <string/write.h>*/
/*#include <string/free.h>*/
/*#include <structs/charset.h>*/
/*#include <structs/value.h>*/
/*#include <enums/syntax_type.h>*/
/*#include <misc/ptrcmp.h>*/
#endif
#ifdef DEBUG_BUILD
extern int debug_depth;
#define HERE \
printf("%*s" "HERE at %s:%i\n", debug_depth, "", __PRETTY_FUNCTION__, __LINE__);
#define ENTER \
printf("%*s" "%s\n", debug_depth++, "", __PRETTY_FUNCTION__);
#define EXIT \
assert(debug_depth), printf("%*s" "return; // from %s\n", debug_depth--, "", __FUNCTION__);
#define TODO \
{ \
printf("TODO hit at %s:%i!\n", __FILE__, __LINE__); \
\
pid_t __child = fork(); \
\
if (__child < 0) \
{\
perror("fork");\
}\
else if (__child)\
{\
int wstatus = 0;\
\
if (waitpid(__child, &wstatus, 0) < 0)\
perror("waitpid");\
else if (wstatus)\
fprintf(stderr, "child failed!");\
}\
else\
{\
char __buffer[100]; \
snprintf(__buffer, 100, "+%u", __LINE__); \
execlp("gedit", "gedit", __FILE__, __buffer, NULL); \
}\
\
exit(1); \
}
#define CHECK \
{ \
printf("CHECK hit at %s:%i!\n", __FILE__, __LINE__); \
\
pid_t child = fork(); \
\
if (child < 0) \
{\
perror("fork");\
}\
else if (child)\
{\
int wstatus = 0;\
\
if (waitpid(child, &wstatus, 0) < 0)\
perror("waitpid");\
else if (wstatus)\
fprintf(stderr, "child failed!");\
}\
else\
{\
char __buffer[100]; \
snprintf(__buffer, 100, "+%u", __LINE__); \
execlp("gedit", "gedit", __FILE__, __buffer, NULL); \
}\
\
exit(1); \
}
#define NOPE \
{ \
printf("NOPE hit at %s:%i!\n", __FILE__, __LINE__); \
\
pid_t child = fork(); \
\
if (child < 0) \
{\
perror("fork");\
}\
else if (child)\
{\
int wstatus = 0;\
\
if (waitpid(child, &wstatus, 0) < 0)\
perror("waitpid");\
else if (wstatus)\
fprintf(stderr, "child failed!");\
}\
else\
{\
char buffer[100]; \
snprintf(buffer, 100, "+%u", __LINE__); \
execlp("gedit", "gedit", __FILE__, buffer, NULL); \
}\
\
exit(1); \
}
extern void dpvs_implementation(
const char*,
char quote,
const unsigned char*,
size_t);
#define dpvs(str) \
dpvs_implementation(#str, '\"', (const unsigned char*) str, (size_t) -1);
#define dpvsn(str, len) \
dpvs_implementation(#str, '\"', (const unsigned char*) str, (size_t) (len));
#define dpvss(str) \
dpvs_implementation(#str, str->data, str->len);
#define dpvb(b) \
printf("%*s" "%s = %s\n", debug_depth, "", #b, (b) ? "true" : "false");
#define dputs(s) \
printf("%*s" "%s\n", debug_depth, "", s);
#define dpvc(c) \
dpvs_implementation(#c, '\'', (const unsigned char[1]) {(unsigned char) (c)}, (size_t) 1);
#define dpvwc(c) \
printf("%*s" "%s = '%lc'\n", debug_depth, "", #c, c);
#define dpvws(s) \
printf("%*s" "%s = \"%ls\"\n", debug_depth, "", #s, s);
#define dpvp(p) \
printf("%*s" "%s = %p\n", debug_depth, "", #p, p);
#define dpvf(f) \
printf("%*s" "%s = %f\n", debug_depth, "", #f, f);
#define dpvlf(f) \
printf("%*s" "%s = %lf\n", debug_depth, "", #f, f);
#define dpvi(x) \
printf("%*s" "%s = %i\n", debug_depth, "", #x, (x));
#define dpvhhu(x) \
printf("%*s" "%s = %hhu\n", debug_depth, "", #x, (x));
#define dpvhhx(x) \
printf("%*s" "%s = 0x%hhX\n", debug_depth, "", #x, (x));
#define dpvu(x) \
printf("%*s" "%s = %u\n", debug_depth, "", #x, (x));
#define dpvlu(x) \
printf("%*s" "%s = %lu\n", debug_depth, "", #x, (x));
#else
#define ENTER ;
#define EXIT ;
#define HERE ;
#define TODO assert(!"TODO");
#define CHECK assert(!"CHECK");
#define NOPE assert(!"NOPE");
#define dpvp(_) ;
#define dpvs(_) ;
#define dpvss(_) ;
#define dpvsn(str, len) ;
#define dpvb(_) ;
#define dputs(_) ;
#define dpvc(_) ;
#define dpvi(_) ;
#define dpvf(_) ;
#define dpvlf(_) ;
#define dpvhhu(_) ;
#define dpvhhx(_) ;
#define dpvws(_) ;
#define dpvwc(_) ;
#define dpvlu(_) ;
#define dpvu(_) ;
#endif

5
defines/N.h Normal file
View file

@ -0,0 +1,5 @@
#define N(a) \
(sizeof(a) / sizeof(*a))

4
defines/argv0.h Normal file
View file

@ -0,0 +1,4 @@
#define argv0 \
(program_invocation_name)

2
dep-snipe.sh Executable file
View file

@ -0,0 +1,2 @@
#!/bin/sh
find bin -name '*.d' | xargs grep -F "${1}" -l | xargs rm -vf

31
environment/declare.c Normal file
View file

@ -0,0 +1,31 @@
#include <assert.h>
#include <debug.h>
#include <extern/avl/avl.h>
#include "variable/new.h"
#include "struct.h"
#include "declare.h"
void environment_declare(
struct environment* this,
struct string* name,
struct value* value)
{
ENTER;
struct variable* variable = new_variable(name, value);
void* node = avl_insert(this->tree, variable);
if (!node)
{
TODO;
}
EXIT;
}

11
environment/declare.h Normal file
View file

@ -0,0 +1,11 @@
struct environment;
struct string;
struct value;
void environment_declare(
struct environment* this,
struct string* name,
struct value* value);

View file

@ -0,0 +1,98 @@
#include <limits.h>
#include <debug.h>
#include <booleans/struct.h>
#include <string/new.h>
#include <string/free.h>
#include <builtin/numeric/add.h>
#include <builtin/numeric/subtract.h>
#include <builtin/numeric/multiply.h>
#include <builtin/numeric/divide.h>
#include <builtin/compare/eq.h>
#include <builtin/compare/gte.h>
#include <builtin/compare/lte.h>
#include <builtin/compare/gt.h>
#include <builtin/compare/lt.h>
#include <builtin/compare/neq.h>
#include <value/builtin_lambda/new.h>
#include <value/free.h>
#include "struct.h"
#include "declare.h"
#include "declare_builtins.h"
void environment_declare_builtins(
struct environment* this,
struct booleans* booleans)
{
ENTER;
#define DECLARE_BOOLEAN(name, value) \
{ \
struct string* string = new_string(name, UINT_MAX); \
\
environment_declare(this, string, value); \
\
free_string(string); \
}
DECLARE_BOOLEAN(L"true", booleans->true_value);
DECLARE_BOOLEAN(L"false", booleans->false_value);
#define DECLARE_BUILTIN(name, funcptr, num_of_param) \
{ \
struct string* string = new_string(name, UINT_MAX); \
\
struct value* value = new_builtin_lambda_value( \
/* name: */ string, \
/* function pointer: */ funcptr, \
/* number of parameters: */ num_of_param, \
/* value: */ NULL, \
/* prev: */ NULL); \
\
environment_declare(this, string, value); \
\
free_value(value); \
\
free_string(string); \
}
DECLARE_BUILTIN(L"+", builtin_numeric_add, 2);
DECLARE_BUILTIN(L"-", builtin_numeric_subtract, 2);
DECLARE_BUILTIN(L"", builtin_numeric_subtract, 2);
DECLARE_BUILTIN(L"×", builtin_numeric_multiply, 2);
DECLARE_BUILTIN(L"÷", builtin_numeric_divide, 2);
DECLARE_BUILTIN(L"=", builtin_compare_eq, 2);
DECLARE_BUILTIN(L"", builtin_compare_gte, 2);
DECLARE_BUILTIN(L"", builtin_compare_lte, 2);
DECLARE_BUILTIN(L">", builtin_compare_gt, 2);
DECLARE_BUILTIN(L"<", builtin_compare_lt, 2);
DECLARE_BUILTIN(L"", builtin_compare_neq, 2);
// declare =
// declare ≥
// declare ≤
// declare ≮
// declare ≯
// declare ≰
// declare ≱
// declare ≠
EXIT;
}

View file

@ -0,0 +1,9 @@
struct environment;
struct booleans;
void environment_declare_builtins(
struct environment* this,
struct booleans* booleans);

27
environment/free.c Normal file
View file

@ -0,0 +1,27 @@
#include <stdlib.h>
#include <debug.h>
#include <extern/avl/avl.h>
#include "struct.h"
#include "free.h"
void free_environment(
struct environment* this)
{
ENTER;
if (this && !--this->refcount)
{
free_environment(this->fallback);
avl_free_tree(this->tree);
free(this);
}
EXIT;
}

7
environment/free.h Normal file
View file

@ -0,0 +1,7 @@
struct environment;
void free_environment(
struct environment* this);

15
environment/inc.c Normal file
View file

@ -0,0 +1,15 @@
#include <debug.h>
#include "struct.h"
#include "inc.h"
struct environment* inc_environment(
struct environment* this)
{
if (this)
this->refcount++;
return this;
}

5
environment/inc.h Normal file
View file

@ -0,0 +1,5 @@
struct environment* inc_environment(
struct environment* this);

53
environment/lookup.c Normal file
View file

@ -0,0 +1,53 @@
#include <stdlib.h>
#include <assert.h>
#include <debug.h>
#include <extern/avl/avl.h>
#include <string/struct.h>
#include <value/inc.h>
#include "variable/struct.h"
#include "struct.h"
#include "lookup.h"
struct value* environment_lookup(
struct environment* this,
struct string* name)
{
ENTER;
struct value* result = NULL;
for (struct environment* moving = this;
!result && moving;
moving = moving->fallback)
{
struct avl_node_t* node = avl_search(moving->tree, &name);
if (node)
{
struct variable* variable = node->item;
result = inc_value(variable->value);
}
}
if (!result)
{
dpvu(*name->data);
TODO;
exit(1);
}
EXIT;
return result;
}

8
environment/lookup.h Normal file
View file

@ -0,0 +1,8 @@
struct environment;
struct string;
struct value* environment_lookup(
struct environment* this,
struct string* name);

33
environment/new.c Normal file
View file

@ -0,0 +1,33 @@
#include <debug.h>
#include <extern/avl/avl.h>
#include <memory/smalloc.h>
#include "variable/compare.h"
#include "variable/free.h"
#include "inc.h"
#include "struct.h"
#include "new.h"
struct environment* new_environment(
struct environment* fallback)
{
ENTER;
struct environment* this = smalloc(sizeof(*this));
this->fallback = inc_environment(fallback);
this->tree = avl_alloc_tree(
compare_variables,
free_variable);
this->refcount = 1;
EXIT;
return this;
}

5
environment/new.h Normal file
View file

@ -0,0 +1,5 @@
struct environment* new_environment(
struct environment* fallback);

11
environment/struct.h Normal file
View file

@ -0,0 +1,11 @@
struct environment
{
struct environment* fallback;
struct avl_tree_t* tree;
unsigned refcount;
};

View file

@ -0,0 +1,18 @@
#include <debug.h>
#include <string/compare.h>
#include "struct.h"
#include "compare.h"
int compare_variables(
const void* a,
const void* b)
{
const struct variable *A = a, *B = b;
return compare_strings(A->name, B->name);
}
// wcscmp(A->name->data, B->name->data);

View file

@ -0,0 +1,6 @@
int compare_variables(
const void* a,
const void* b);

View file

@ -0,0 +1,25 @@
#include <stdlib.h>
#include <debug.h>
#include <string/free.h>
#include <value/free.h>
#include "struct.h"
#include "free.h"
void free_variable(
void* ptr)
{
struct variable* this = ptr;
free_string(this->name);
free_value(this->value);
free(this);
}

View file

@ -0,0 +1,5 @@
void free_variable(
void* ptr);

View file

@ -0,0 +1,29 @@
#include <debug.h>
#include <memory/smalloc.h>
#include <string/inc.h>
#include <value/inc.h>
#include "struct.h"
#include "new.h"
struct variable* new_variable(
struct string* name,
struct value* value)
{
ENTER;
struct variable* this = smalloc(sizeof(*this));
this->name = inc_string(name);
this->value = inc_value(value);
EXIT;
return this;
}

View file

@ -0,0 +1,9 @@
struct string;
struct value;
struct variable* new_variable(
struct string* name,
struct value* value);

View file

@ -0,0 +1,12 @@
struct string;
struct value;
struct variable
{
struct string* name;
struct value* value;
};

11
examples/init.txt Normal file
View file

@ -0,0 +1,11 @@
# these are built in to the language
# true <- λ x, y: x
# false <- λ x, y: y
𝐼 <- λ x: x
𝑌 <- λ f: (λ x: f (x x)) (λ x: f (x x))

63
examples/sandbox.txt Normal file
View file

@ -0,0 +1,63 @@
# comments
0
1
3.14159
# booleans are lambdas or values?
# well, if they're lambdas, then they're read by the init file?
# if they're user-defined, then what should comparisions return?
# maybe they just return what 'true' or 'false' would return in the \
given envronment?
# also keep in mind that if they're values, we'll need a builtin \
conditional switch function in addition to them.
# it's probably best if they're builtin lambdas, like '+' or '×'.
true
false
# an expression doesn't end until it could validly end:
λ
x:
x
# ends before the 2
2
(λ x: x)(2)
f <- λ x: x; f 2
# numerical operators exist and can curry ...somehow:
+
-
×
÷
+ 1
× 2
+ 1 1
× 2 2
× (+ 1 2) 3
fib <- 𝑌 λ f x: (≤ x 1) x (+ (f (- x 1)) (f (- x 2)))
fib 8
(𝑌 λ f x: (≤ x 1) x (+ (f (- x 1)) (f (- x 2)))) 10

View file

@ -0,0 +1,117 @@
#include <stdlib.h>
#include <assert.h>
#include <debug.h>
#include <environment/new.h>
#include <environment/declare.h>
#include <environment/free.h>
#include <value/struct.h>
#include <value/lambda/struct.h>
#include <value/builtin_lambda/struct.h>
#include <value/builtin_lambda/new.h>
#include <value/lazy/new.h>
#include <value/lazy/unlazy.h>
#include <value/free.h>
#include "../evaluate.h"
#include "struct.h"
#include "evaluate.h"
struct value* application_expression_evaluate(
struct expression* super,
struct environment* outer_environment,
struct booleans* booleans)
{
ENTER;
struct value* result;
struct application_expression* this = (void*) super;
struct value* left = expression_evaluate(this->left, outer_environment, booleans);
struct value* lleft = lazy_value_unlazy(left, booleans);
struct value* right = new_lazy_value(
/* capture environment: */ outer_environment,
/* expression: */ this->right);
switch (lleft->kind)
{
case vk_lambda:
{
struct lambda_value* lambda = (void*) lleft;
struct environment* environment = new_environment(lambda->environment);
environment_declare(environment, lambda->variable_name, right);
result = expression_evaluate(lambda->body, environment, booleans);
free_environment(environment);
break;
}
case vk_builtin_lambda:
{
struct builtin_lambda_value* lambda = (void*) lleft;
assert(lambda->number_of_parameters > 0);
if (lambda->number_of_parameters == 1)
{
result = (lambda->funcptr)(booleans, lambda, right);
}
else
{
result = new_builtin_lambda_value(
/* name: */ lambda->name,
/* funcptr: */ lambda->funcptr,
/* number_of_parameters: */ lambda->number_of_parameters - 1,
/* value: */ right,
/* prev: */ lambda);
}
break;
}
case vk_lazy:
{
TODO;
break;
}
default:
{
dpvu(lleft->kind);
TODO;
exit(1);
break;
}
}
free_value(left);
free_value(lleft);
free_value(right);
EXIT;
return result;
}

View file

@ -0,0 +1,7 @@
struct value* application_expression_evaluate(
struct expression* this,
struct environment* environment,
struct booleans* booleans);

View file

@ -0,0 +1,23 @@
#include <debug.h>
#include <value/free.h>
#include "../free.h"
#include "struct.h"
#include "free.h"
void free_application_expression(
struct expression* super)
{
ENTER;
struct application_expression* this = (void*) super;
free_expression(this->left);
free_expression(this->right);
EXIT;
}

View file

@ -0,0 +1,6 @@
struct expression;
void free_application_expression(
struct expression* super);

View file

@ -0,0 +1,20 @@
#include <debug.h>
#include "../inheritance.h"
#include "prettyprint_errors.h"
#include "prettyprint.h"
#include "evaluate.h"
#include "free.h"
#include "inheritance.h"
struct expression_inheritance application_expression_inheritance = {
.prettyprint_errors = application_expression_prettyprint_errors,
.prettyprint = application_expression_prettyprint,
.evaluate = application_expression_evaluate,
.free = free_application_expression
};

View file

@ -0,0 +1,2 @@
extern struct expression_inheritance application_expression_inheritance;

View file

@ -0,0 +1,29 @@
#include <debug.h>
#include <expression/inc.h>
#include "../new.h"
#include "inheritance.h"
#include "struct.h"
#include "new.h"
struct expression* new_application_expression(
struct expression* left,
struct expression* right)
{
ENTER;
struct application_expression* this = (void*) new_expression(
/* inheritance: */ &application_expression_inheritance,
/* alloc size: */ sizeof(*this));
this->left = inc_expression(left);
this->right = inc_expression(right);
EXIT;
return (void*) this;
}

View file

@ -0,0 +1,6 @@
struct expression;
struct expression* new_application_expression(
struct expression* left,
struct expression* right);

View file

@ -0,0 +1,72 @@
#include <sys/param.h>
#include <debug.h>
/*#include <color_factory/struct.h>*/
#include <stringtree/new.h>
#include <stringtree/prepend.h>
#include <stringtree/append.h>
#include <stringtree/free.h>
#include <expression/prettyprint.h>
#include "struct.h"
#include "prettyprint.h"
struct stringtree* application_expression_prettyprint(
int *out_chosen_color,
struct expression* super,
struct color_factory* cfactory,
bool with_color)
{
ENTER;
struct application_expression* const this = (void*) super;
int left_color, right_color;
struct stringtree* left = expression_prettyprint(
&left_color,
this->left,
cfactory,
with_color);
struct stringtree* right = expression_prettyprint(
&right_color,
this->right,
cfactory,
with_color);
if (with_color && out_chosen_color)
{
*out_chosen_color = MAX(left_color, right_color);
}
struct stringtree* tree = new_stringtree();
stringtree_append_stringtree(tree, left);
stringtree_append_cstr(tree, L" ");
stringtree_append_stringtree(tree, right);
free_stringtree(left);
free_stringtree(right);
EXIT;
return tree;
}

View file

@ -0,0 +1,15 @@
#include <stdbool.h>
struct expression;
struct color_factory;
struct stringtree* application_expression_prettyprint(
int *out_chosen_color,
struct expression* this,
struct color_factory* cfactory,
bool with_color);

View file

@ -0,0 +1,34 @@
#include <stddef.h>
#include <assert.h>
#include <debug.h>
#include "../prettyprint_errors.h"
#include "struct.h"
#include "prettyprint_errors.h"
struct stringtree* application_expression_prettyprint_errors(
struct expression* super)
{
ENTER;
struct application_expression* const this = (void*) super;
struct stringtree* tree = expression_prettyprint_errors(this->left);
if (tree)
{
TODO;
}
else
{
tree = expression_prettyprint_errors(this->right);
}
EXIT;
return NULL;
}

View file

@ -0,0 +1,4 @@
struct stringtree* application_expression_prettyprint_errors(
struct expression* super);

View file

@ -0,0 +1,10 @@
#include "../struct.h"
struct application_expression
{
struct expression super;
struct expression *left, *right;
};

25
expression/evaluate.c Normal file
View file

@ -0,0 +1,25 @@
#include <assert.h>
#include <debug.h>
#include "struct.h"
#include "inheritance.h"
#include "evaluate.h"
struct value* expression_evaluate(
struct expression* this,
struct environment* environment,
struct booleans* booleans)
{
ENTER;
assert(this);
assert(this->inheritance);
assert(this->inheritance->evaluate);
struct value* value = (this->inheritance->evaluate)(
this, environment, booleans);
EXIT;
return value;
}

11
expression/evaluate.h Normal file
View file

@ -0,0 +1,11 @@
struct expression;
struct environment;
struct booleans;
struct value* expression_evaluate(
struct expression*,
struct environment*,
struct booleans* booleans);

29
expression/free.c Normal file
View file

@ -0,0 +1,29 @@
#include <stdlib.h>
#include <assert.h>
#include <debug.h>
#include "inheritance.h"
#include "struct.h"
#include "free.h"
void free_expression(
struct expression* this)
{
ENTER;
if (this && !--this->refcount)
{
assert(this);
assert(this->inheritance);
assert(this->inheritance->free);
(this->inheritance->free)(this);
free(this);
}
EXIT;
}

6
expression/free.h Normal file
View file

@ -0,0 +1,6 @@
struct expression;
void free_expression(
struct expression* this);

15
expression/inc.c Normal file
View file

@ -0,0 +1,15 @@
#include <debug.h>
#include "struct.h"
#include "inc.h"
struct expression* inc_expression(
struct expression* this)
{
if (this)
this->refcount++;
return this;
}

4
expression/inc.h Normal file
View file

@ -0,0 +1,4 @@
struct expression* inc_expression(
struct expression* this);

28
expression/inheritance.h Normal file
View file

@ -0,0 +1,28 @@
#include <stdbool.h>
struct booleans;
struct color_factory;
struct expression;
struct environment;
struct expression_inheritance
{
struct stringtree* (*prettyprint)(
int *out_chosen_color,
struct expression* this,
struct color_factory* cfactory,
bool with_color);
struct stringtree* (*prettyprint_errors)(
struct expression* this);
struct value* (*evaluate)(
struct expression*,
struct environment*,
struct booleans* booleans);
void (*free)(
struct expression*);
};

View file

@ -0,0 +1,25 @@
#include <debug.h>
#include <value/lambda/new.h>
#include "struct.h"
#include "evaluate.h"
struct value* lambda_expression_evaluate(
struct expression* super,
struct environment* environment,
struct booleans* booleans)
{
ENTER;
struct lambda_expression* this = (void*) super;
struct value* result = new_lambda_value(
/* captured environment: */ environment,
/* variable name: */ this->variable_name,
/* body: */ this->body);
EXIT;
return result;
}

View file

@ -0,0 +1,11 @@
struct expression;
struct environment;
struct booleans;
struct value* lambda_expression_evaluate(
struct expression* this,
struct environment* environment,
struct booleans* booleans);

23
expression/lambda/free.c Normal file
View file

@ -0,0 +1,23 @@
#include <debug.h>
#include <string/free.h>
#include <expression/free.h>
#include "struct.h"
#include "free.h"
void free_lambda_expression(
struct expression* super)
{
ENTER;
struct lambda_expression* this = (void*) super;
free_string(this->variable_name);
free_expression(this->body);
EXIT;
}

6
expression/lambda/free.h Normal file
View file

@ -0,0 +1,6 @@
struct expression;
void free_lambda_expression(
struct expression* super);

View file

@ -0,0 +1,20 @@
#include <debug.h>
#include "../inheritance.h"
#include "prettyprint_errors.h"
#include "prettyprint.h"
#include "evaluate.h"
#include "free.h"
#include "inheritance.h"
struct expression_inheritance lambda_expression_inheritance = {
.prettyprint_errors = lambda_expression_prettyprint_errors,
.prettyprint = lambda_expression_prettyprint,
.evaluate = lambda_expression_evaluate,
.free = free_lambda_expression
};

View file

@ -0,0 +1,2 @@
extern struct expression_inheritance lambda_expression_inheritance;

34
expression/lambda/new.c Normal file
View file

@ -0,0 +1,34 @@
#include <debug.h>
/*#include <mpq/inc.h>*/
/*#include <parse/token/inc.h>*/
#include <string/inc.h>
#include "../new.h"
#include "../inc.h"
#include "inheritance.h"
#include "struct.h"
#include "new.h"
struct expression* new_lambda_expression(
struct string *variable_name,
struct expression* body)
{
ENTER;
struct lambda_expression* this = (void*) new_expression(
/* inheritance: */ &lambda_expression_inheritance,
/* alloc size: */ sizeof(*this));
this->variable_name = inc_string(variable_name);
this->body = inc_expression(body);
EXIT;
return (void*) this;
}

8
expression/lambda/new.h Normal file
View file

@ -0,0 +1,8 @@
struct value;
struct string;
struct expression* new_lambda_expression(
struct string *parameter_name,
struct expression* body);

View file

@ -0,0 +1,75 @@
#include <debug.h>
#include <defines/N.h>
#include <color_factory/struct.h>
#include <stringtree/new.h>
#include <stringtree/prepend.h>
#include <stringtree/append.h>
#include <stringtree/free.h>
#include "../prettyprint.h"
#include "struct.h"
#include "prettyprint.h"
struct stringtree* lambda_expression_prettyprint(
int *out_chosen_color,
struct expression* super,
struct color_factory* cfactory,
bool with_color)
{
ENTER;
struct lambda_expression* const this = (void*) super;
int chosen_color;
struct stringtree* tree = new_stringtree();
stringtree_append_cstr(tree, L"λ");
stringtree_append_string(tree, this->variable_name);
stringtree_append_cstr(tree, L": ");
struct stringtree* subtree = expression_prettyprint(
&chosen_color,
this->body,
cfactory,
with_color);
if (with_color)
{
int my_color = (chosen_color + 1) % (int) N(cfactory->colors);
stringtree_prepend_string(tree, cfactory->colors[my_color]);
stringtree_append_string(tree, cfactory->reset);
if (out_chosen_color)
*out_chosen_color = my_color;
}
stringtree_append_stringtree(tree, subtree);
free_stringtree(subtree);
EXIT;
return tree;
}

View file

@ -0,0 +1,15 @@
#include <stdbool.h>
struct expression;
struct color_factory;
struct stringtree* lambda_expression_prettyprint(
int *out_chosen_color,
struct expression* this,
struct color_factory* cfactory,
bool with_color);

Some files were not shown because too many files have changed in this diff Show more