"mutate" now actually works
This commit is contained in:
+10
-1
@@ -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
@@ -1 +1,4 @@
|
|||||||
(define operators (list + - * /))
|
(define l '(1 2 3 4))
|
||||||
|
(define r (rest l))
|
||||||
|
(mutate r (list 100 200))
|
||||||
|
(print l)
|
||||||
|
|||||||
@@ -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;
|
char** keys;
|
||||||
Ast_Node* values;
|
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->keys = (char**)malloc(start_capacity * sizeof(char*));
|
||||||
env->values = (Ast_Node*)malloc(start_capacity * sizeof(Ast_Node));
|
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->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*));
|
||||||
env->values = (Ast_Node*)realloc(env->values, env->capacity * sizeof(Ast_Node));
|
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
@@ -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) {
|
/* Ast_Node* copy_list(Ast_Node* node) { */
|
||||||
// we don't copy immutables in here
|
/* // we don't copy immutables in here */
|
||||||
if (node->type != Ast_Node_Type_Pair) {
|
/* if (node->type != Ast_Node_Type_Pair) { */
|
||||||
return node;
|
/* return node; */
|
||||||
}
|
/* } */
|
||||||
|
|
||||||
Ast_Node* result = new(Ast_Node);
|
/* Ast_Node* result = new(Ast_Node); */
|
||||||
result->type = Ast_Node_Type_Pair;
|
/* result->type = Ast_Node_Type_Pair; */
|
||||||
result->value.pair = new(Pair);
|
/* result->value.pair = new(Pair); */
|
||||||
|
|
||||||
result->value.pair->first = copy_list(node->value.pair->first);
|
/* result->value.pair->first = copy_list(node->value.pair->first); */
|
||||||
result->value.pair->rest = copy_list(node->value.pair->rest);
|
/* 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 ||
|
if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil ||
|
||||||
arguments->value.pair->first->type == Ast_Node_Type_Keyword)
|
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 = *source;
|
||||||
target->value = source->value;
|
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user