Add simple evaluation
This commit is contained in:
@@ -2,26 +2,48 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include "nihilispm.h"
|
#include "nihilispm.h"
|
||||||
|
#include "nihilispm_internal.h"
|
||||||
|
#include "nihilispm_utility.h"
|
||||||
|
#include "nihilispm_state.h"
|
||||||
|
|
||||||
struct nl_object *nl_evaluate_list(struct nl_object *list) {
|
struct nl_object *nl_evaluate_list(struct nl_state *state, struct nl_object *list) {
|
||||||
return NULL;
|
// TODO: Recursively eval args
|
||||||
|
struct nl_object *evaluated_list = nl_nil_create();
|
||||||
|
|
||||||
|
FOREACH_LIST(list, iter, item) {
|
||||||
|
struct nl_object *obj = nl_evaluate(state, item);
|
||||||
|
nl_list_append(evaluated_list, obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct nl_object *fun = nl_car(evaluated_list);
|
||||||
|
struct nl_object *args = nl_cdr(evaluated_list);
|
||||||
|
struct nl_object *result = NULL;
|
||||||
|
|
||||||
|
assert(fun->type == NL_TYPE_BUILTIN);
|
||||||
|
if (fun->type == NL_TYPE_BUILTIN) {
|
||||||
|
result = fun->builtin(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nl_object *nl_evaluate_symbol(struct nl_object *symbol) {
|
// TODO: Non-builtins
|
||||||
return NULL;
|
|
||||||
|
// TODO: cleanup
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct nl_object *nl_evaluate(struct nl_object *obj) {
|
struct nl_object *nl_evaluate(struct nl_state *state, struct nl_object *obj) {
|
||||||
assert(obj != NULL);
|
assert(obj != NULL);
|
||||||
|
|
||||||
switch (obj->type) {
|
switch (obj->type) {
|
||||||
case NL_TYPE_CELL:
|
case NL_TYPE_CELL:
|
||||||
return nl_evaluate_list(obj);
|
return nl_evaluate_list(state, obj);
|
||||||
case NL_TYPE_SYMBOL:
|
case NL_TYPE_SYMBOL:
|
||||||
return NULL; //nl_evalute_symbol(obj);
|
return nl_state_get(state, obj->symbol);
|
||||||
case NL_TYPE_INT:
|
case NL_TYPE_INT:
|
||||||
case NL_TYPE_STRING:
|
case NL_TYPE_STRING:
|
||||||
|
case NL_TYPE_ERROR:
|
||||||
return obj;
|
return obj;
|
||||||
|
case NL_TYPE_BUILTIN:
|
||||||
case NL_TYPE_COUNT:
|
case NL_TYPE_COUNT:
|
||||||
assert(0);
|
assert(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
19
src/main.c
19
src/main.c
@@ -1,10 +1,29 @@
|
|||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "nihilispm.h"
|
#include "nihilispm.h"
|
||||||
#include "nihilispm_state.h"
|
#include "nihilispm_state.h"
|
||||||
|
#include "nihilispm_internal.h"
|
||||||
|
#include "nihilispm_utility.h"
|
||||||
|
#include "builtins.h"
|
||||||
|
|
||||||
int main(int argc, const char **argv) {
|
int main(int argc, const char **argv) {
|
||||||
(void) argc, (void) argv;
|
(void) argc, (void) argv;
|
||||||
struct nl_state *state = nl_state_create();
|
struct nl_state *state = nl_state_create();
|
||||||
|
|
||||||
|
nl_state_put(state, "+", nl_builtin_create(nl_builtin_add));
|
||||||
|
nl_state_put(state, "-", nl_builtin_create(nl_builtin_sub));
|
||||||
|
nl_state_put(state, "*", nl_builtin_create(nl_builtin_mul));
|
||||||
|
nl_state_put(state, "/", nl_builtin_create(nl_builtin_div));
|
||||||
|
nl_state_put(state, "%", nl_builtin_create(nl_builtin_mod));
|
||||||
|
|
||||||
|
struct nl_object *sexp = nl_parse(argv[1]);
|
||||||
|
struct nl_object *result = nl_evaluate(state, nl_car(sexp));
|
||||||
|
|
||||||
|
assert(result != NULL);
|
||||||
|
assert(result->type == NL_TYPE_INT);
|
||||||
|
|
||||||
|
printf("%d\n", result->integer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
10
src/memory.c
10
src/memory.c
@@ -48,6 +48,15 @@ struct nl_object *nl_error_create(const char *error)
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct nl_object *nl_builtin_create(nl_builtin builtin)
|
||||||
|
{
|
||||||
|
struct nl_object* obj = nl_object_alloc();
|
||||||
|
obj->type = NL_TYPE_BUILTIN;
|
||||||
|
obj->builtin = builtin;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
static struct nl_object* nl_object_alloc() {
|
static struct nl_object* nl_object_alloc() {
|
||||||
return malloc(sizeof(struct nl_object));
|
return malloc(sizeof(struct nl_object));
|
||||||
}
|
}
|
||||||
@@ -77,6 +86,7 @@ void nl_object_delete(struct nl_object *obj) {
|
|||||||
obj->error = NULL;
|
obj->error = NULL;
|
||||||
break;
|
break;
|
||||||
case NL_TYPE_INT:
|
case NL_TYPE_INT:
|
||||||
|
case NL_TYPE_BUILTIN:
|
||||||
case NL_TYPE_COUNT:
|
case NL_TYPE_COUNT:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ enum nl_type {
|
|||||||
NL_TYPE_INT = 2,
|
NL_TYPE_INT = 2,
|
||||||
NL_TYPE_STRING = 3,
|
NL_TYPE_STRING = 3,
|
||||||
NL_TYPE_ERROR = 4,
|
NL_TYPE_ERROR = 4,
|
||||||
NL_TYPE_COUNT = 5,
|
NL_TYPE_BUILTIN = 5,
|
||||||
|
NL_TYPE_COUNT = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct nl_cell {
|
struct nl_cell {
|
||||||
@@ -15,6 +16,8 @@ struct nl_cell {
|
|||||||
struct nl_object *cdr;
|
struct nl_object *cdr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct nl_object *(*nl_builtin)(struct nl_object *args);
|
||||||
|
|
||||||
struct nl_object {
|
struct nl_object {
|
||||||
enum nl_type type;
|
enum nl_type type;
|
||||||
union {
|
union {
|
||||||
@@ -23,6 +26,7 @@ struct nl_object {
|
|||||||
int integer;
|
int integer;
|
||||||
const char *string;
|
const char *string;
|
||||||
const char *error;
|
const char *error;
|
||||||
|
nl_builtin builtin;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,6 +41,6 @@ struct nl_state; // TODO
|
|||||||
|
|
||||||
struct nl_object *nl_tokenize(const char *source);
|
struct nl_object *nl_tokenize(const char *source);
|
||||||
struct nl_object *nl_parse(const char *sexp);
|
struct nl_object *nl_parse(const char *sexp);
|
||||||
struct nl_object *nl_evaluate(struct nl_object *sexp);
|
struct nl_object *nl_evaluate(struct nl_state *state, struct nl_object *sexp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,12 +10,12 @@
|
|||||||
item_name != NULL && iter_name != NULL && (cond); \
|
item_name != NULL && iter_name != NULL && (cond); \
|
||||||
iter_name = iter_name->cell.cdr, item_name = (iter_name == NULL) ? NULL : iter_name->cell.car)
|
iter_name = iter_name->cell.cdr, item_name = (iter_name == NULL) ? NULL : iter_name->cell.car)
|
||||||
|
|
||||||
|
|
||||||
struct nl_object *nl_cell_create(struct nl_object *car, struct nl_object *cdr);
|
struct nl_object *nl_cell_create(struct nl_object *car, struct nl_object *cdr);
|
||||||
struct nl_object *nl_int_create(int integer);
|
struct nl_object *nl_int_create(int integer);
|
||||||
struct nl_object *nl_symbol_create(const char* symbol);
|
struct nl_object *nl_symbol_create(const char* symbol);
|
||||||
struct nl_object *nl_string_create(const char* string);
|
struct nl_object *nl_string_create(const char* string);
|
||||||
struct nl_object *nl_error_create(const char* error);
|
struct nl_object *nl_error_create(const char* error);
|
||||||
|
struct nl_object *nl_builtin_create(nl_builtin builtin);
|
||||||
|
|
||||||
void nl_object_delete(struct nl_object *obj);
|
void nl_object_delete(struct nl_object *obj);
|
||||||
|
|
||||||
|
|||||||
13
src/parse.c
13
src/parse.c
@@ -67,8 +67,12 @@ struct nl_object *nl_token_next(const char **curr_src) {
|
|||||||
// -2 for removing start/end quotes
|
// -2 for removing start/end quotes
|
||||||
str = strndup(start + 1, *curr_src - start - 2);
|
str = strndup(start + 1, *curr_src - start - 2);
|
||||||
return nl_cell_create(nl_string_create(str), NULL);
|
return nl_cell_create(nl_string_create(str), NULL);
|
||||||
//case '0':
|
case '0'...'9': {
|
||||||
// TODO: Parse integers
|
char *end = NULL;
|
||||||
|
long value = strtol(*curr_src, &end, 0);
|
||||||
|
*curr_src = end;
|
||||||
|
return nl_cell_create(nl_int_create(value), NULL);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
while (!nl_is_delimiter(**curr_src)) {
|
while (!nl_is_delimiter(**curr_src)) {
|
||||||
(*curr_src)++;
|
(*curr_src)++;
|
||||||
@@ -116,8 +120,7 @@ struct nl_object *nl_parse_token_atom(struct nl_object *maybe_atom) {
|
|||||||
atom = nl_string_create(strdup(maybe_atom->string));
|
atom = nl_string_create(strdup(maybe_atom->string));
|
||||||
break;
|
break;
|
||||||
case NL_TYPE_INT:
|
case NL_TYPE_INT:
|
||||||
// TODO: Copy the token
|
atom = nl_int_create(maybe_atom->integer);
|
||||||
assert(0);
|
|
||||||
break;
|
break;
|
||||||
case NL_TYPE_COUNT:
|
case NL_TYPE_COUNT:
|
||||||
assert(false);
|
assert(false);
|
||||||
@@ -152,7 +155,7 @@ static struct nl_object *nl_parse_tokens_recursive(struct nl_object **token_iter
|
|||||||
*token_iter = (*token_iter)->cell.cdr;
|
*token_iter = (*token_iter)->cell.cdr;
|
||||||
while (1) {
|
while (1) {
|
||||||
token = (*token_iter)->cell.car;
|
token = (*token_iter)->cell.car;
|
||||||
if (token->symbol[0] == END_LIST_CHAR) {
|
if (token->type == NL_TYPE_SYMBOL && token->symbol[0] == END_LIST_CHAR) {
|
||||||
*token_iter = (*token_iter)->cell.cdr;
|
*token_iter = (*token_iter)->cell.cdr;
|
||||||
if (list == NULL) {
|
if (list == NULL) {
|
||||||
list = nl_cell_create(NULL, NULL);
|
list = nl_cell_create(NULL, NULL);
|
||||||
|
|||||||
Reference in New Issue
Block a user