step: add some plumbing for "q-expressions"

This commit is contained in:
NunoSempere 2023-05-01 21:19:46 -04:00
parent f9bfc8fb46
commit e064fd5ec9
3 changed files with 54 additions and 13 deletions

View File

@ -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/>

BIN
mumble

Binary file not shown.

View File

@ -21,7 +21,8 @@ enum {
LISPVAL_NUM, LISPVAL_NUM,
LISPVAL_ERR, LISPVAL_ERR,
LISPVAL_SYM, LISPVAL_SYM,
LISPVAL_SEXPR LISPVAL_SEXPR,
LISPVAL_QEXPR,
}; };
enum { enum {
@ -66,6 +67,15 @@ lispval* lispval_sexpr(void)
return v; return v;
} }
lispval* lispval_qexpr(void)
{
lispval* v = malloc(sizeof(lispval));
v->type = LISPVAL_QEXPR;
v->count = 0;
v->cell = NULL;
return v;
}
// Destructor // Destructor
void delete_lispval(lispval* v) void delete_lispval(lispval* v)
{ {
@ -79,6 +89,7 @@ void delete_lispval(lispval* v)
free(v->sym); free(v->sym);
break; break;
case LISPVAL_SEXPR: case LISPVAL_SEXPR:
case LISPVAL_QEXPR:
for (int i = 0; i < v->count; i++) { for (int i = 0; i < v->count; i++) {
delete_lispval(v->cell[i]); delete_lispval(v->cell[i]);
} }
@ -109,8 +120,17 @@ lispval* read_lispval(mpc_ast_t* t)
return read_lispval_num(t); return read_lispval_num(t);
} else if (strstr(t->tag, "symbol")) { } else if (strstr(t->tag, "symbol")) {
return lispval_sym(t->contents); return lispval_sym(t->contents);
} else if ((strcmp(t->tag, ">") == 0) || strstr(t->tag, "sexpr")) { } else if ((strcmp(t->tag, ">") == 0) || strstr(t->tag, "sexpr") || strstr(t->tag, "qexpr")) {
lispval* x = lispval_sexpr();
lispval* x;
if((strcmp(t->tag, ">") == 0) || strstr(t->tag, "sexpr")){
x = lispval_sexpr();
} else if(strstr(t->tag, "qexpr")){
x = lispval_qexpr();
} else {
return lispval_err("Error: Unreachable code state reached.");
}
for (int i = 0; i < (t->children_num); i++) { for (int i = 0; i < (t->children_num); i++) {
if (strcmp(t->children[i]->contents, "(") == 0) { if (strcmp(t->children[i]->contents, "(") == 0) {
continue; continue;
@ -118,6 +138,12 @@ lispval* read_lispval(mpc_ast_t* t)
if (strcmp(t->children[i]->contents, ")") == 0) { if (strcmp(t->children[i]->contents, ")") == 0) {
continue; continue;
} }
if (strcmp(t->children[i]->contents, "{") == 0) {
continue;
}
if (strcmp(t->children[i]->contents, "}") == 0) {
continue;
}
if (strcmp(t->children[i]->tag, "regex") == 0) { if (strcmp(t->children[i]->tag, "regex") == 0) {
continue; continue;
} }
@ -125,7 +151,7 @@ lispval* read_lispval(mpc_ast_t* t)
} }
return x; return x;
} else { } else {
lispval* err = lispval_err("Unknown ast type."); lispval* err = lispval_err("Unknown AST type.");
return err; return err;
} }
} }
@ -155,6 +181,12 @@ void print_lispval_tree(lispval* v, int indent_level)
print_lispval_tree(v->cell[i], indent_level + 2); print_lispval_tree(v->cell[i], indent_level + 2);
} }
break; break;
case LISPVAL_QEXPR:
printf("\n%sQExpr, with %d children:", indent, v->count);
for (int i = 0; i < v->count; i++) {
print_lispval_tree(v->cell[i], indent_level + 2);
}
break;
default: default:
printf("Error: unknown lispval type\n"); printf("Error: unknown lispval type\n");
printf("%s", v->sym); printf("%s", v->sym);
@ -181,6 +213,13 @@ void print_lispval_parenthesis(lispval* v)
} }
printf(") "); printf(") ");
break; break;
case LISPVAL_QEXPR:
printf("{ ");
for (int i = 0; i < v->count; i++) {
print_lispval_parenthesis(v->cell[i]);
}
printf("} ");
break;
default: default:
printf("Error: unknown lispval type\n"); printf("Error: unknown lispval type\n");
printf("%s", v->sym); printf("%s", v->sym);
@ -316,6 +355,7 @@ int main(int argc, char** argv)
mpc_parser_t* Number = mpc_new("number"); mpc_parser_t* Number = mpc_new("number");
mpc_parser_t* Symbol = mpc_new("symbol"); mpc_parser_t* Symbol = mpc_new("symbol");
mpc_parser_t* Sexpr = mpc_new("sexpr"); mpc_parser_t* Sexpr = mpc_new("sexpr");
mpc_parser_t* Qexpr = mpc_new("qexpr");
mpc_parser_t* Expr = mpc_new("expr"); mpc_parser_t* Expr = mpc_new("expr");
mpc_parser_t* Mumble = mpc_new("mumble"); mpc_parser_t* Mumble = mpc_new("mumble");
@ -324,10 +364,11 @@ int main(int argc, char** argv)
number : /-?[0-9]+\\.?([0-9]+)?/ ; \ number : /-?[0-9]+\\.?([0-9]+)?/ ; \
symbol : '+' | '-' | '*' | '/' ; \ symbol : '+' | '-' | '*' | '/' ; \
sexpr : '(' <expr>* ')' ; \ sexpr : '(' <expr>* ')' ; \
expr : <number> | <symbol> | <sexpr> ; \ qexpr : '{' <expr>* '}' ; \
expr : <number> | <symbol> | <sexpr> | <qexpr>; \
mumble : /^/ <expr>* /$/ ; \ mumble : /^/ <expr>* /$/ ; \
", ",
Number, Symbol, Sexpr, Expr, Mumble); Number, Symbol, Sexpr, Qexpr, Expr, Mumble);
// Initialize a repl // Initialize a repl
int loop = 1; int loop = 1;
@ -381,7 +422,7 @@ int main(int argc, char** argv)
} }
/* Undefine and Delete our Parsers */ /* Undefine and Delete our Parsers */
mpc_cleanup(5, Number, Symbol, Sexpr, Expr, Mumble); mpc_cleanup(6, Number, Symbol, Sexpr, Qexpr, Expr, Mumble);
return 0; return 0;
} }