Просмотр исходного кода

"mutate" now actually works

master
FelixBrendel 7 лет назад
Родитель
Сommit
ce28d94a9a
4 измененных файлов: 42 добавлений и 35 удалений
  1. +10
    -1
      bin/pre.slime
  2. +4
    -1
      bin/test.slime
  3. +9
    -9
      src/env.c
  4. +19
    -24
      src/eval.c

+ 10
- 1
bin/pre.slime Просмотреть файл

@@ -5,6 +5,15 @@
"Checks if the argument is nil." "Checks if the argument is nil."
(= x nil))) (= x nil)))


(define append
(lambda (seq elem)
(if (nil? seq)
nil
(if (not (= (type (rest seq)) :pair))
;; we are on the last element
(mutate seq (pair (first seq) elem))
(append (rest seq) elem)))))

(define last (define last
(lambda (seq) (lambda (seq)
"Returns the last element of the given sequence." "Returns the last element of the given sequence."
@@ -79,5 +88,5 @@ as compared to `reduce'."
(print sep)) (print sep))
;; TODO(Felix): later we should use `extend' here: ;; TODO(Felix): later we should use `extend' here:
;; (eval (extend (quote (printf :sep sep :end end)) (rest args))) ;; (eval (extend (quote (printf :sep sep :end end)) (rest args)))
(eval (pair printf (pair :sep (pair sep (pair :end (pair end (rest args)))))))
(eval (extend '(printf :sep sep :end end) (rest args)))
nil)))) nil))))

+ 4
- 1
bin/test.slime Просмотреть файл

@@ -1 +1,4 @@
(define operators (list + - * /))
(define l '(1 2 3 4))
(define r (rest l))
(mutate r (list 100 200))
(print l)

+ 9
- 9
src/env.c Просмотреть файл

@@ -4,8 +4,8 @@ struct Environment {
int capacity; int capacity;
int next_index; int next_index;
// TODO(Felix): Use a hashmap here. // TODO(Felix): Use a hashmap here.
char** keys;
Ast_Node* values;
char** keys;
Ast_Node** values;
}; };


typedef struct Environment Environment; typedef struct Environment Environment;
@@ -19,8 +19,8 @@ Environment* create_child_environment(Environment* parent) {
env->parent = parent; env->parent = parent;
env->capacity = start_capacity; env->capacity = start_capacity;
env->next_index = 0; env->next_index = 0;
env->keys = (char**)malloc(start_capacity * sizeof(char*));
env->values = (Ast_Node*)malloc(start_capacity * sizeof(Ast_Node));
env->keys = (char**)malloc(start_capacity * sizeof(char*));
env->values = (Ast_Node**)malloc(start_capacity * sizeof(Ast_Node*));


return env; return env;
} }
@@ -30,7 +30,7 @@ Environment* create_empty_environment() {
} }


void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
// NOTE(Felix): right now we are simmply adding the symol at the
// NOTE(Felix): right now we are simply adding the symol at the
// back of the list without checking if it already exists but are // back of the list without checking if it already exists but are
// also searching for thesymbol from the back, so we will find the // also searching for thesymbol from the back, so we will find the
// latest defined one first, but a bit messy. Later we should use // latest defined one first, but a bit messy. Later we should use
@@ -38,19 +38,19 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {


if (env->next_index == env->capacity) { if (env->next_index == env->capacity) {
env->capacity *= 2; env->capacity *= 2;
env->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*));
env->values = (Ast_Node*)realloc(env->values, env->capacity * sizeof(Ast_Node));
env->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*));
env->values = (Ast_Node**)realloc(env->values, env->capacity * sizeof(Ast_Node*));
} }


env->keys [env->next_index] = symbol->value.symbol->identifier; env->keys [env->next_index] = symbol->value.symbol->identifier;
env->values[env->next_index] = *value;
env->values[env->next_index] = value;
++env->next_index; ++env->next_index;
} }


Ast_Node* lookup_symbol(Symbol* sym, Environment* env) { Ast_Node* lookup_symbol(Symbol* sym, Environment* env) {
for (int i = env->next_index - 1; i >= 0; --i) for (int i = env->next_index - 1; i >= 0; --i)
if (string_equal(env->keys[i], sym->identifier)) if (string_equal(env->keys[i], sym->identifier))
return env->values+i;
return env->values[i];


if (env->parent) if (env->parent)
return lookup_symbol(sym, env->parent); return lookup_symbol(sym, env->parent);


+ 19
- 24
src/eval.c Просмотреть файл

@@ -20,7 +20,6 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;
} }



if (arguments->type == Ast_Node_Type_Nil) if (arguments->type == Ast_Node_Type_Nil)
goto eval_time; goto eval_time;


@@ -324,21 +323,21 @@ int list_length(Ast_Node* node) {
be baked into the quoted list. So even after changing a, the result be baked into the quoted list. So even after changing a, the result
of (eval condition) would be 1.00000. of (eval condition) would be 1.00000.
**/ **/
Ast_Node* copy_list(Ast_Node* node) {
// we don't copy immutables in here
if (node->type != Ast_Node_Type_Pair) {
return node;
}
/* Ast_Node* copy_list(Ast_Node* node) { */
/* // we don't copy immutables in here */
/* if (node->type != Ast_Node_Type_Pair) { */
/* return node; */
/* } */


Ast_Node* result = new(Ast_Node);
result->type = Ast_Node_Type_Pair;
result->value.pair = new(Pair);
/* Ast_Node* result = new(Ast_Node); */
/* result->type = Ast_Node_Type_Pair; */
/* result->value.pair = new(Pair); */


result->value.pair->first = copy_list(node->value.pair->first);
result->value.pair->rest = copy_list(node->value.pair->rest);
/* result->value.pair->first = copy_list(node->value.pair->first); */
/* result->value.pair->rest = copy_list(node->value.pair->rest); */


return result;
}
/* return result; */
/* } */


bool is_truthy (Ast_Node* expression, Environment* env); bool is_truthy (Ast_Node* expression, Environment* env);


@@ -370,11 +369,9 @@ Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_argumen
if (current_head->type == Ast_Node_Type_Pair) { if (current_head->type == Ast_Node_Type_Pair) {
evaluated_arguments_head->value.pair->rest = create_ast_node_pair(nullptr, nullptr); evaluated_arguments_head->value.pair->rest = create_ast_node_pair(nullptr, nullptr);
evaluated_arguments_head = evaluated_arguments_head->value.pair->rest; evaluated_arguments_head = evaluated_arguments_head->value.pair->rest;
}
else if (current_head->type == Ast_Node_Type_Nil) {
} else if (current_head->type == Ast_Node_Type_Nil) {
evaluated_arguments_head->value.pair->rest = current_head; evaluated_arguments_head->value.pair->rest = current_head;
}
else {
} else {
create_error(Error_Type_Ill_Formed_Arguments, arguments); create_error(Error_Type_Ill_Formed_Arguments, arguments);
return nullptr; return nullptr;
} }
@@ -493,7 +490,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
} }
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;


if (result) return create_ast_node_number(1);;
if (result) return create_ast_node_number(1);
} }


return create_ast_node_nil(); return create_ast_node_nil();
@@ -599,8 +596,8 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
if (arguments_length != 2) if (arguments_length != 2)
report_error(Error_Type_Wrong_Number_Of_Arguments); report_error(Error_Type_Wrong_Number_Of_Arguments);


if (arguments->value.pair->first->type == Ast_Node_Type_Nil ||
arguments->value.pair->first->type == Ast_Node_Type_Keyword)
if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil ||
evaluated_arguments->value.pair->first->type == Ast_Node_Type_Keyword)
{ {
report_error(Error_Type_Type_Missmatch); report_error(Error_Type_Type_Missmatch);
} }
@@ -608,9 +605,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
Ast_Node* target = evaluated_arguments->value.pair->first; Ast_Node* target = evaluated_arguments->value.pair->first;
Ast_Node* source = evaluated_arguments->value.pair->rest->value.pair->first; Ast_Node* source = evaluated_arguments->value.pair->rest->value.pair->first;


target->type = source->type;
target->value = source->value;

*target = *source;
return target; return target;
} }
case Built_In_Load: { case Built_In_Load: {
@@ -757,7 +752,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
} }


default: { default: {
printf("alskjdalskdjaldskjalk");
printf("wtf???????????");
report_error(Error_Type_Not_A_Function); report_error(Error_Type_Not_A_Function);
} }
} }


Загрузка…
Отмена
Сохранить