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

BIN
mumble

Binary file not shown.

View File

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