step: playing around with more tweaks

This commit is contained in:
NunoSempere 2023-05-02 12:50:32 -04:00
parent 59c51e0027
commit ce12b90eb5
3 changed files with 68 additions and 51 deletions

View File

@ -6,8 +6,8 @@
# make uninstall # make uninstall
## C compiler ## C compiler
CC=tcc # much faster compilation than gcc CC=gcc # 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/>
## <https://news.ycombinator.com/item?id=35758898> ## <https://news.ycombinator.com/item?id=35758898>

BIN
mumble

Binary file not shown.

View File

@ -5,12 +5,15 @@
#include <string.h> #include <string.h>
#include "mpc/mpc.h" #include "mpc/mpc.h"
#define VERBOSE 0 #define VERBOSE 1
#define LISPVAL_ASSERT(cond, err) \ #define LISPVAL_ASSERT(cond, err) \
if (!(cond)) { \ if (!(cond)) { \
return lispval_err(err); \ return lispval_err(err); \
} }
#define printfln(...) do { \
printf ("\n@ %s (%d): ", __FILE__, __LINE__); \
printf (__VA_ARGS__); \
} while (0)
// Types // Types
// Types: Forward declarations // Types: Forward declarations
@ -60,7 +63,7 @@ enum {
// Constructors // Constructors
lispval* lispval_num(double x) lispval* lispval_num(double x)
{ {
if(VERBOSE) printf("\nAllocated num"); if(VERBOSE) printfln("Allocated num");
lispval* v = malloc(sizeof(lispval)); lispval* v = malloc(sizeof(lispval));
v->type = LISPVAL_NUM; v->type = LISPVAL_NUM;
v->count = 0; v->count = 0;
@ -70,7 +73,7 @@ lispval* lispval_num(double x)
lispval* lispval_err(char* message) lispval* lispval_err(char* message)
{ {
if(VERBOSE) printf("\nAllocated err"); if(VERBOSE) printfln("Allocated err");
lispval* v = malloc(sizeof(lispval)); lispval* v = malloc(sizeof(lispval));
v->type = LISPVAL_ERR; v->type = LISPVAL_ERR;
v->count = 0; v->count = 0;
@ -81,7 +84,7 @@ lispval* lispval_err(char* message)
lispval* lispval_sym(char* symbol) lispval* lispval_sym(char* symbol)
{ {
if(VERBOSE) printf("\nAllocated sym"); if(VERBOSE) printfln("Allocated sym");
lispval* v = malloc(sizeof(lispval)); lispval* v = malloc(sizeof(lispval));
v->type = LISPVAL_SYM; v->type = LISPVAL_SYM;
v->count = 0; v->count = 0;
@ -91,7 +94,7 @@ lispval* lispval_sym(char* symbol)
} }
lispval* lispval_func(lispbuiltin func, char* funcname){ lispval* lispval_func(lispbuiltin func, char* funcname){
if(VERBOSE) printf("\nAllocated sym"); if(VERBOSE) printfln("Allocated sym");
lispval* v = malloc(sizeof(lispval)); lispval* v = malloc(sizeof(lispval));
v->type = LISPVAL_FUNC; v->type = LISPVAL_FUNC;
v->count = 0; v->count = 0;
@ -103,7 +106,7 @@ lispval* lispval_func(lispbuiltin func, char* funcname){
lispval* lispval_sexpr(void) lispval* lispval_sexpr(void)
{ {
if(VERBOSE) printf("\nAllocated sexpr"); if(VERBOSE) printfln("Allocated sexpr");
lispval* v = malloc(sizeof(lispval)); lispval* v = malloc(sizeof(lispval));
v->type = LISPVAL_SEXPR; v->type = LISPVAL_SEXPR;
v->count = 0; v->count = 0;
@ -113,7 +116,7 @@ lispval* lispval_sexpr(void)
lispval* lispval_qexpr(void) lispval* lispval_qexpr(void)
{ {
if(VERBOSE) printf("\nAllocated qexpr"); if(VERBOSE) printfln("Allocated qexpr");
lispval* v = malloc(sizeof(lispval)); lispval* v = malloc(sizeof(lispval));
v->type = LISPVAL_QEXPR; v->type = LISPVAL_QEXPR;
v->count = 0; v->count = 0;
@ -122,37 +125,42 @@ 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; if(v == NULL) return;
// print_lispval_tree(v, 0);
switch (v->type) { switch (v->type) {
case LISPVAL_NUM: case LISPVAL_NUM:
if(VERBOSE) printf("\nFreed num"); if(VERBOSE) printfln("Freeing num");
break; break;
case LISPVAL_ERR: case LISPVAL_ERR:
if(VERBOSE) printf("\nFreed err"); if(VERBOSE) printfln("Freeing err");
if (v->err != NULL) if (v->err != NULL)
free(v->err); free(v->err);
v->err = NULL; v->err = NULL;
if(VERBOSE) printfln("Freed err");
break; break;
case LISPVAL_SYM: case LISPVAL_SYM:
if(VERBOSE) printf("\nFreed sym"); if(VERBOSE) printfln("Freeing sym");
if (v->sym != NULL) if (v->sym != NULL)
free(v->sym); free(v->sym);
v->sym = NULL; v->sym = NULL;
if(VERBOSE) printfln("Freed sym");
break; break;
case LISPVAL_FUNC: case LISPVAL_FUNC:
if(VERBOSE) printf("\nFreed func"); if(VERBOSE) printfln("Freeing func");
if (v->funcname != NULL) if (v->funcname != NULL)
free(v->funcname); free(v->funcname);
v->funcname = NULL; v->funcname = NULL;
if(VERBOSE) printfln("Freed func");
// Don't do anything with v->func for now // Don't do anything with v->func for now
// Though we could delete the pointer to the function later // Though we could delete the pointer to the function later
// free(v->func); // free(v->func);
break; break;
case LISPVAL_SEXPR: case LISPVAL_SEXPR:
case LISPVAL_QEXPR: case LISPVAL_QEXPR:
if(VERBOSE) printf("\nFreed s/qexpr"); if(VERBOSE) printfln("Freeing sexpr|qexpr");
for (int i = 0; i < v->count; i++) { for (int i = 0; i < v->count; i++) {
if (v->cell[i] != NULL) if (v->cell[i] != NULL)
delete_lispval(v->cell[i]); delete_lispval(v->cell[i]);
@ -161,7 +169,10 @@ void delete_lispval(lispval* v)
if (v->cell != NULL) if (v->cell != NULL)
free(v->cell); free(v->cell);
v->cell = NULL; v->cell = NULL;
if(VERBOSE) printfln("Freed sexpr|qexpr");
break; break;
default:
if(VERBOSE) printfln("Error: Unknown expression type.");
} }
if (v != NULL) if (v != NULL)
free(v); free(v);
@ -262,7 +273,7 @@ lispval* read_lispval(mpc_ast_t* t)
} }
} }
if (VERBOSE) if (VERBOSE)
printf("\nNon ignorable children: %i", c); printfln("Non ignorable children: %i", c);
if (strstr(t->tag, "number")) { if (strstr(t->tag, "number")) {
return read_lispval_num(t); return read_lispval_num(t);
@ -305,74 +316,79 @@ lispval* read_lispval(mpc_ast_t* t)
// Print // Print
void print_lispval_tree(lispval* v, int indent_level) void print_lispval_tree(lispval* v, int indent_level)
{ {
char* indent = malloc(sizeof(char) * (indent_level + 1)); char* indent = " ";/*malloc(sizeof(char) * (indent_level + 1));
for (int i = 0; i < indent_level; i++) { for (int i = 0; i < indent_level; i++) {
indent[i] = ' '; indent[i] = ' ';
} }
indent[indent_level] = '\0'; indent[indent_level] = '\0';*/
switch (v->type) { switch (v->type) {
case LISPVAL_NUM: case LISPVAL_NUM:
printf("\n%sNumber: %f", indent, v->num); printfln("%sNumber: %f", indent, v->num);
break; break;
case LISPVAL_ERR: case LISPVAL_ERR:
printf("\n%sError: %s", indent, v->err); printfln("%sError: %s", indent, v->err);
break; break;
case LISPVAL_SYM: case LISPVAL_SYM:
printf("\n%sSymbol: %s", indent, v->sym); printfln("%sSymbol: %s", indent, v->sym);
break;
case LISPVAL_FUNC:
printfln("%sFunction, name: %s, pointer: %p", indent, v->funcname, v->func);
break; break;
case LISPVAL_SEXPR: case LISPVAL_SEXPR:
printf("\n%sSExpr, with %d children:", indent, v->count); printfln("%sSExpr, with %d children:", indent, v->count);
for (int i = 0; i < v->count; i++) { for (int i = 0; i < v->count; i++) {
print_lispval_tree(v->cell[i], indent_level + 2); print_lispval_tree(v->cell[i], indent_level + 2);
} }
break; break;
case LISPVAL_QEXPR: case LISPVAL_QEXPR:
printf("\n%sQExpr, with %d children:", indent, v->count); printfln("%sQExpr, with %d children:", indent, v->count);
for (int i = 0; i < v->count; i++) { for (int i = 0; i < v->count; i++) {
print_lispval_tree(v->cell[i], indent_level + 2); print_lispval_tree(v->cell[i], indent_level + 2);
} }
break; break;
default: default:
printf("Error: unknown lispval type\n"); printfln("Error: unknown lispval type\n");
printf("%s", v->sym); // printfln("%s", v->sym);
} }
free(indent); // printfln("Freeing indent");
indent = NULL; // if (indent!=NULL) free(indent);
printfln("Freed indent");
// indent = NULL;
} }
void print_lispval_parenthesis(lispval* v) void print_lispval_parenthesis(lispval* v)
{ {
switch (v->type) { switch (v->type) {
case LISPVAL_NUM: case LISPVAL_NUM:
printf("%f ", v->num); printfln("%f ", v->num);
break; break;
case LISPVAL_ERR: case LISPVAL_ERR:
printf("%s ", v->err); printfln("%s ", v->err);
break; break;
case LISPVAL_SYM: case LISPVAL_SYM:
printf("%s ", v->sym); printfln("%s ", v->sym);
break; break;
case LISPVAL_FUNC: case LISPVAL_FUNC:
printf("<function name: %s pointer: %p>", v->funcname, v->func); printfln("<function name: %s pointer: %p>", v->funcname, v->func);
break; break;
case LISPVAL_SEXPR: case LISPVAL_SEXPR:
printf("( "); printfln("( ");
for (int i = 0; i < v->count; i++) { for (int i = 0; i < v->count; i++) {
print_lispval_parenthesis(v->cell[i]); print_lispval_parenthesis(v->cell[i]);
} }
printf(") "); printfln(") ");
break; break;
case LISPVAL_QEXPR: case LISPVAL_QEXPR:
printf("{ "); printfln("{ ");
for (int i = 0; i < v->count; i++) { for (int i = 0; i < v->count; i++) {
print_lispval_parenthesis(v->cell[i]); print_lispval_parenthesis(v->cell[i]);
} }
printf("} "); printfln("} ");
break; break;
default: default:
printf("Error: unknown lispval type\n"); printfln("Error: unknown lispval type\n");
printf("%s", v->sym); // printfln("%s", v->sym);
} }
} }
@ -383,14 +399,14 @@ void print_ast(mpc_ast_t* ast, int indent_level)
indent[i] = ' '; indent[i] = ' ';
} }
indent[indent_level] = '\0'; indent[indent_level] = '\0';
printf("\n%sTag: %s", indent, ast->tag); printfln("%sTag: %s", indent, ast->tag);
printf("\n%sContents: %s", indent, printfln("%sContents: %s", indent,
strcmp(ast->contents, "") ? ast->contents : "None"); strcmp(ast->contents, "") ? ast->contents : "None");
printf("\n%sNumber of children: %i", indent, ast->children_num); printfln("%sNumber of children: %i", indent, ast->children_num);
/* Print the children */ /* Print the children */
for (int i = 0; i < ast->children_num; i++) { for (int i = 0; i < ast->children_num; i++) {
mpc_ast_t* child_i = ast->children[i]; mpc_ast_t* child_i = ast->children[i];
printf("\n%sChild #%d", indent, i); printfln("%sChild #%d", indent, i);
print_ast(child_i, indent_level + 2); print_ast(child_i, indent_level + 2);
} }
free(indent); free(indent);
@ -462,7 +478,7 @@ lispval* take_lispval(lispval* v, int i)
// Ops for q-expressions // Ops for q-expressions
lispval* builtin_head(lispval* v) lispval* builtin_head(lispval* v)
{ {
// printf("Entering builtin_head with v->count = %d and v->cell[0]->type = %d\n", v->count, v->cell[0]->type); // printfln("Entering builtin_head with v->count = %d and v->cell[0]->type = %d\n", v->count, v->cell[0]->type);
// head { 1 2 3 } // head { 1 2 3 }
// But actually, that gets processd into head ({ 1 2 3 }), hence the v->cell[0]->cell[0]; // But actually, that gets processd into head ({ 1 2 3 }), hence the v->cell[0]->cell[0];
LISPVAL_ASSERT(v->count == 1, "Error: function head passed too many arguments"); LISPVAL_ASSERT(v->count == 1, "Error: function head passed too many arguments");
@ -745,18 +761,18 @@ int main(int argc, char** argv)
// Print AST if VERBOSE // Print AST if VERBOSE
if (VERBOSE) { if (VERBOSE) {
printf("\nPrinting AST"); printfln("Printing AST");
print_ast(ast, 0); print_ast(ast, 0);
} }
// Evaluate the AST // Evaluate the AST
if(VERBOSE) printf("\n\nEvaluating the AST"); if(VERBOSE) printfln("\nEvaluating the AST");
// lispval result = evaluate_ast(ast); // lispval result = evaluate_ast(ast);
lispval* l = read_lispval(ast); lispval* l = read_lispval(ast);
if (VERBOSE) { if (VERBOSE) {
printf("\n\nPrinting initially parsed lispvalue"); printfln("\nPrinting initially parsed lispvalue");
printf("\nTree printing: "); printfln("Tree printing: ");
print_lispval_tree(l, 2); print_lispval_tree(l, 2);
printf("\nParenthesis printing: "); printfln("Parenthesis printing: ");
print_lispval_parenthesis(l); print_lispval_parenthesis(l);
} }
// Create an environment // Create an environment
@ -765,12 +781,13 @@ int main(int argc, char** argv)
// Eval the lispval in that environment. // Eval the lispval in that environment.
lispval* answer = evaluate_lispval(l, env); lispval* answer = evaluate_lispval(l, env);
{ {
printf("\n\nResult: "); printfln("Result: ");
print_lispval_parenthesis(answer); print_lispval_parenthesis(answer);
printf("\n"); print_lispval_tree(answer, 0);
printf("\n");
} }
delete_lispval(l); // delete_lispval(l);
delete_lispval(answer); // delete_lispval(answer);
// Clean up environment // Clean up environment
destroy_lispenv(env); destroy_lispenv(env);