# $Id$
-SERENADE_OBJS = main.o parser.o util.o run.o
+SERENADE_OBJS = main.o parser.o util.o run.o interpreter.o
.PHONY: all clean
.SUFFIXES: .o .c
--- /dev/null
+/* $Id$ */
+/* --- START LICENSE --- */
+/* -------------------------------------------------------------------------- */
+/* Serenade is a Lisp Dialect */
+/* -------------------------------------------------------------------------- */
+/* Copyright (c) 2024 Nishi. */
+/* Redistribution and use in source and binary forms, with or without modific */
+/* ation, are permitted provided that the following conditions are met: */
+/* 1. Redistributions of source code must retain the above copyright noti */
+/* ce, this list of conditions and the following disclaimer. */
+/* 2. Redistributions in binary form must reproduce the above copyright n */
+/* otice, this list of conditions and the following disclaimer in the documen */
+/* tation and/or other materials provided with the distribution. */
+/* 3. Neither the name of the copyright holder nor the names of its contr */
+/* ibutors may be used to endorse or promote products derived from this softw */
+/* are without specific prior written permission. */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS */
+/* " AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, TH */
+/* E IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPO */
+/* SE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS */
+/* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CON */
+/* SEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITU */
+/* TE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPT */
+/* ION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S */
+/* TRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN AN */
+/* Y WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY */
+/* OF SUCH DAMAGE. */
+/* -------------------------------------------------------------------------- */
+/* --- END LICENSE --- */
+
+#include "interpreter.h"
+
+#include <stdlib.h>
+
+struct sn_interpreter* sn_create_interpreter(void) {
+ struct sn_interpreter* sn = malloc(sizeof(struct sn_interpreter));
+ return sn;
+}
+
+void sn_interpreter_free(struct sn_interpreter* sn) { free(sn); }
--- /dev/null
+/* $Id$ */
+/* --- START LICENSE --- */
+/* -------------------------------------------------------------------------- */
+/* Serenade is a Lisp Dialect */
+/* -------------------------------------------------------------------------- */
+/* Copyright (c) 2024 Nishi. */
+/* Redistribution and use in source and binary forms, with or without modific */
+/* ation, are permitted provided that the following conditions are met: */
+/* 1. Redistributions of source code must retain the above copyright noti */
+/* ce, this list of conditions and the following disclaimer. */
+/* 2. Redistributions in binary form must reproduce the above copyright n */
+/* otice, this list of conditions and the following disclaimer in the documen */
+/* tation and/or other materials provided with the distribution. */
+/* 3. Neither the name of the copyright holder nor the names of its contr */
+/* ibutors may be used to endorse or promote products derived from this softw */
+/* are without specific prior written permission. */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS */
+/* " AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, TH */
+/* E IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPO */
+/* SE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS */
+/* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CON */
+/* SEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITU */
+/* TE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPT */
+/* ION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, S */
+/* TRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN AN */
+/* Y WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY */
+/* OF SUCH DAMAGE. */
+/* -------------------------------------------------------------------------- */
+/* --- END LICENSE --- */
+
+#ifndef __SERENADE_INTERPRETER_H__
+#define __SERENADE_INTERPRETER_H__
+
+#include "parser.h"
+
+struct sn_interpreter {};
+
+struct sn_interpreter* sn_create_interpreter(void);
+void sn_interpreter_free(struct sn_interpreter* sn);
+
+#endif
/* --- END LICENSE --- */
#include "../config.h"
+#include "interpreter.h"
#include "parser.h"
+#include "run.h"
#include "serenade.h"
+#include "util.h"
#include <stdbool.h>
#include <stdio.h>
struct sn_generic** t = sn_parse(str, s.st_size);
if(t != NULL) {
int j;
+ struct sn_interpreter* sn = sn_create_interpreter();
for(j = 0; t[j] != NULL; j++) {
+ sn_run(sn, t[j]);
sn_generic_free(t[j]);
}
+ sn_interpreter_free(sn);
free(t);
}
free(str);
void push_stack(struct sn_generic* gen, char* buf, int mode) {
struct sn_generic* newgen = malloc(sizeof(struct sn_generic));
newgen->type = mode;
- if(mode == SN_TYPE_STRING || mode == SN_TYPE_FUNCTION) {
+ if(mode == SN_TYPE_STRING) {
newgen->string = sn_strdup(buf);
newgen->string_length = strlen(buf);
+ } else if(mode == SN_TYPE_FUNCTION) {
+ newgen->name = sn_strdup(buf);
} else if(mode == SN_TYPE_DOUBLE) {
newgen->number = atof(buf);
}
int i;
int start = 0;
bool dq = false;
+ struct sn_generic** gens = malloc(sizeof(struct sn_generic*));
+ gens[0] = NULL;
for(i = 0; i < size; i++) {
char c = data[i];
if(c == '"') {
memcpy(d, data + start, i - start + 1);
struct sn_generic* gen = sn_expr_parse(d, i - start + 1);
if(gen != NULL) {
- sn_print_generic(gen);
- sn_generic_free(gen);
+ int j;
+ struct sn_generic** old_gens = gens;
+ for(j = 0; old_gens[j] != NULL; j++)
+ ;
+ gens = malloc(sizeof(struct sn_generic*) * (j + 2));
+ for(j = 0; old_gens[j] != NULL; j++) {
+ gens[j] = old_gens[j];
+ }
+ gens[j] = gen;
+ gens[j + 1] = NULL;
}
free(d);
+ } else if(br < 0) {
+ return gens;
}
}
}
- return NULL;
+ return gens;
}
void sn_generic_free(struct sn_generic* g) {
/* --- END LICENSE --- */
#include "run.h"
+#include "util.h"
-int sn_run(struct sn_generic* gen) { return 0; }
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct sn_generic* _sn_run(struct sn_interpreter* sn, struct sn_generic* gen) {
+ if(gen->type == SN_TYPE_TREE) {
+ struct sn_generic* op = gen->tree->args[0];
+ if(op->type == SN_TYPE_TREE) {
+ op = _sn_run(sn, op);
+ }
+ int j;
+ for(j = 1; gen->tree->args[j]; j++)
+ ;
+ struct sn_generic** args = malloc(sizeof(struct sn_generic*) * (j - 1));
+ int argc = j - 1;
+ for(j = 1; gen->tree->args[j]; j++) {
+ args[j - 1] = _sn_run(sn, gen->tree->args[j]);
+ }
+
+ struct sn_generic* r = malloc(sizeof(struct sn_generic));
+ r->type = SN_TYPE_VOID;
+
+ if(op->type != SN_TYPE_FUNCTION) {
+ fprintf(stderr, "Cannot call non-function (%d)\n", op->type);
+ free(args);
+ return NULL;
+ } else {
+ }
+ free(args);
+ return r;
+ } else {
+ return gen;
+ }
+ return NULL;
+}
+
+int sn_run(struct sn_interpreter* sn, struct sn_generic* gen) { _sn_run(sn, gen); }
#ifndef __SERENADE_RUN_H__
#define __SERENADE_RUN_H__
+#include "interpreter.h"
#include "parser.h"
-int sn_run(struct sn_generic* gen);
+int sn_run(struct sn_interpreter* sn, struct sn_generic* gen);
#endif