parent
6b05487242
commit
a0734df444
4
makefile
4
makefile
|
@ -6,7 +6,7 @@
|
||||||
# make uninstall
|
# make uninstall
|
||||||
|
|
||||||
## C compiler
|
## C compiler
|
||||||
CC=gcc # much faster compilation than gcc
|
CC=tcc # much faster compilation than gcc
|
||||||
COMPILER_FLAGS=#-g3 -Wall -Wextra -Wconversion -Wdouble-promotion -Wno-unused-parameter -Wno-unused-function -Wno-sign-conversion -fsanitize=undefined
|
COMPILER_FLAGS=#-g3 -Wall -Wextra -Wconversion -Wdouble-promotion -Wno-unused-parameter -Wno-unused-function -Wno-sign-conversion -fsanitize=undefined
|
||||||
# exclude: -fsanitize-trap, because I'm using an old version of gcc and couldn't bother getting a new one.
|
# exclude: -fsanitize-trap, because I'm using an old version of gcc and couldn't bother getting a new one.
|
||||||
## ^ from <https://nullprogram.com/blog/2023/04/29/>
|
## ^ from <https://nullprogram.com/blog/2023/04/29/>
|
||||||
|
@ -35,7 +35,7 @@ STYLE_BLUEPRINT=webkit
|
||||||
FORMATTER=clang-format -i -style=$(STYLE_BLUEPRINT)
|
FORMATTER=clang-format -i -style=$(STYLE_BLUEPRINT)
|
||||||
|
|
||||||
build: $(SRC)
|
build: $(SRC)
|
||||||
$(CC) $(COMPILER_FLAGS) $(INCS) $(SRC) $(MPC) -o mumble $(LIBS) $(DEBUG)
|
$(CC) $(COMPILER_FLAGS) $(INCS) $(SRC) $(MPC) -o mumble $(LIBS)
|
||||||
|
|
||||||
format: $(SRC)
|
format: $(SRC)
|
||||||
$(FORMATTER) $(SRC)
|
$(FORMATTER) $(SRC)
|
||||||
|
|
29
src/mumble.c
29
src/mumble.c
|
@ -5,7 +5,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "mpc/mpc.h"
|
#include "mpc/mpc.h"
|
||||||
#define VERBOSE 1
|
#define VERBOSE 0
|
||||||
#define LISPVAL_ASSERT(cond, err) \
|
#define LISPVAL_ASSERT(cond, err) \
|
||||||
if (!(cond)) { \
|
if (!(cond)) { \
|
||||||
return lispval_err(err); \
|
return lispval_err(err); \
|
||||||
|
@ -122,12 +122,8 @@ lispval* lispval_qexpr(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
void print_lispval_tree(lispval* v, int indent_level);
|
|
||||||
void delete_lispval(lispval* v)
|
void delete_lispval(lispval* v)
|
||||||
{
|
{
|
||||||
if(v == NULL) return;
|
|
||||||
printf("\n Freeing:");
|
|
||||||
print_lispval_tree(v, 2);
|
|
||||||
switch (v->type) {
|
switch (v->type) {
|
||||||
case LISPVAL_NUM:
|
case LISPVAL_NUM:
|
||||||
if(VERBOSE) printf("\nFreed num");
|
if(VERBOSE) printf("\nFreed num");
|
||||||
|
@ -656,7 +652,7 @@ lispval* evaluate_lispval(lispval* l, lispenv* env)
|
||||||
|
|
||||||
// Check if this is a symbol
|
// Check if this is a symbol
|
||||||
if(l->type == LISPVAL_SYM){
|
if(l->type == LISPVAL_SYM){
|
||||||
return get_from_lispenv(l->sym, env);
|
get_from_lispenv(l->sym, env);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the children if needed
|
// Evaluate the children if needed
|
||||||
|
@ -666,32 +662,16 @@ lispval* evaluate_lispval(lispval* l, lispenv* env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if any are errors.
|
// Check if any are errors.
|
||||||
// lispval* error = NULL;
|
|
||||||
for (int i = 0; i < l->count; i++) {
|
for (int i = 0; i < l->count; i++) {
|
||||||
if (l->cell[i]->type == LISPVAL_ERR) {
|
if (l->cell[i]->type == LISPVAL_ERR) {
|
||||||
return l->cell[i];
|
return clone_lispval(l->cell[i]);
|
||||||
// error = clone_lispval(l->cell[i]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Now the problem is that evlauate_lispval is recursive
|
|
||||||
// and it also allocates new memory.
|
|
||||||
// This means that I want to delete the allocated memory.
|
|
||||||
// But the problem is that it could delete the original object l
|
|
||||||
// leading to a double-free error
|
|
||||||
// To mitigate this, I've made the delete_lispval function
|
|
||||||
// a bit more robust, to be able to handle cases where it had
|
|
||||||
// already been deleted
|
|
||||||
// But the compromise here is to not care about destruction to
|
|
||||||
// the original object in case of an error.
|
|
||||||
// if(error!=NULL){
|
|
||||||
// delete_lispval(l);
|
|
||||||
// return error;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Check if the first element is an operation.
|
// Check if the first element is an operation.
|
||||||
if (l->count >= 2 && ((l->cell[0])->type == LISPVAL_FUNC)) {
|
if (l->count >= 2 && ((l->cell[0])->type == LISPVAL_FUNC)) {
|
||||||
lispval* temp = clone_lispval(l->cell[0]);
|
lispval* temp = clone_lispval(l->cell[0]);
|
||||||
lispval* f = pop_lispval(temp, 0);
|
lispval* f = pop_lispval(l, 0);
|
||||||
lispval* operands = temp;
|
lispval* operands = temp;
|
||||||
// lispval* operation = clone_lispval(l->cell[0]);
|
// lispval* operation = clone_lispval(l->cell[0]);
|
||||||
// lispval* operands = lispval_sexpr();
|
// lispval* operands = lispval_sexpr();
|
||||||
|
@ -774,7 +754,6 @@ int main(int argc, char** argv)
|
||||||
print_lispval_parenthesis(answer);
|
print_lispval_parenthesis(answer);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_lispval(l);
|
delete_lispval(l);
|
||||||
delete_lispval(answer);
|
delete_lispval(answer);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user