Mark Poliakov 91961bcec5 Lots of changes with long commit message again
1. (list ...)
2. string-* functions
3. (native str) to resolve native functions at runtime
4. Memory fuckups in compiler core unit loading
5. Now can call non-identifiers in compiler
2021-04-09 00:18:48 +03:00

91 lines
1.9 KiB
C

#include "node.h"
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
struct node *string_from_owned(char *ptr) {
struct node *n = malloc(sizeof(struct node));
n->type = N_STRING;
n->n_string = ptr;
return n;
}
struct node *cons(struct node *a, struct node *b) {
struct node *n = malloc(sizeof(struct node));
n->type = N_CONS;
n->n_cons.car = a;
n->n_cons.cdr = b;
return n;
}
struct node *ident(const char *text) {
struct node *n = malloc(sizeof(struct node));
n->type = N_IDENT;
n->n_ident = strdup(text);
return n;
}
struct node *integer(intmax_t v) {
struct node *n = malloc(sizeof(struct node));
n->type = N_INTEGER;
n->n_integer = v;
return n;
}
struct node *list(int n, ...) {
struct node *head, *tail, *pair;
va_list ap;
va_start(ap, n);
head = NULL;
for (int i = 0; i < n; ++i) {
pair = cons(va_arg(ap, struct node *), NULL);
if (head) {
tail->n_cons.cdr = pair;
} else {
head = pair;
}
tail = pair;
}
va_end(ap);
return head;
}
void vm_print(const struct node *node, int depth) {
if (!node) {
printf("nil");
return;
}
switch (node->type) {
case N_IDENT:
printf("%s", node->n_ident);
break;
case N_INTEGER:
printf("%zd", node->n_integer);
break;
case N_STRING:
printf("\"%s\"", node->n_string);
break;
case N_CONS:
if (!depth) {
printf("(");
}
vm_print(node->n_cons.car, 0);
if (node->n_cons.cdr) {
printf(" ");
if (node->n_cons.cdr->type == N_CONS) {
vm_print(node->n_cons.cdr, depth + 1);
} else {
printf(". ");
vm_print(node->n_cons.cdr, 0);
}
}
if (!depth) {
printf(")");
}
break;
}
}