Lexical scoping is working, but defun broke because of that.

Need macros next
This commit is contained in:
FelixBrendel
2018-12-27 16:29:20 +01:00
parent 34b7390ba9
commit 9b5692da9d
7 changed files with 291 additions and 256 deletions
+162 -161
View File
@@ -1,196 +1,197 @@
(define defmacro (define defmacro
(macro (@name @params :rest @body) (macro (@name @params :rest @body)
"Macro for creating macros with a more concise syntax." "Macro for creating macros with a more concise syntax."
(eval (pair 'define (pair @name (pair (pair 'macro (pair @params @body)) nil)))))) (eval (pair 'define-upwards (pair @name (pair (pair 'macro (pair @params @body)) nil))))))
(defmacro defun (@name @params :rest @body) (define defun
(macro (@name @params :rest @body)
"Macro for creating functions with a more concise syntax." "Macro for creating functions with a more concise syntax."
(eval (pair 'define (pair @name (pair (pair 'lambda (pair @params @body)) nil))))) (eval (pair 'define-upwards (pair @name (pair (pair 'lambda (pair @params @body)) nil))))))
(defun nil? (x) ;; (defun nil? (x)
"Checks if the argument is nil." ;; "Checks if the argument is nil."
(= x nil)) ;; (= x nil))
(defun number? (x) ;; (defun number? (x)
"Checks if the argument is a number." ;; "Checks if the argument is a number."
(= (type x) :number)) ;; (= (type x) :number))
(defun symbol? (x) ;; (defun symbol? (x)
"Checks if the argument is a symbol." ;; "Checks if the argument is a symbol."
(= (type x) :symbol)) ;; (= (type x) :symbol))
(defun keyword? (x) ;; (defun keyword? (x)
"Checks if the argument is a keyword." ;; "Checks if the argument is a keyword."
(= (type x) :keyword)) ;; (= (type x) :keyword))
(defun pair? (x) ;; (defun pair? (x)
"Checks if the argument is a pair." ;; "Checks if the argument is a pair."
(= (type x) :pair)) ;; (= (type x) :pair))
(defun string? (x) ;; (defun string? (x)
"Checks if the argument is a string." ;; "Checks if the argument is a string."
(= (type x) :string)) ;; (= (type x) :string))
(defun dynamic-function? (x) ;; (defun dynamic-function? (x)
"Checks if the argument is a function." ;; "Checks if the argument is a function."
(= (type x) :dynamic-function)) ;; (= (type x) :dynamic-function))
(defun dynamic-macro? (x) ;; (defun dynamic-macro? (x)
"Checks if the argument is a macro." ;; "Checks if the argument is a macro."
(= (type x) :dynamic-macro)) ;; (= (type x) :dynamic-macro))
(defun built-in-function? (x) ;; (defun built-in-function? (x)
"Checks if the argument is a built-in function." ;; "Checks if the argument is a built-in function."
(= (type x) :built-in-function)) ;; (= (type x) :built-in-function))
(defun apply (fun seq) ;; (defun apply (fun seq)
"Applies the funciton to the sequence, as in calls the funciton with ;; "Applies the funciton to the sequence, as in calls the function
ithe sequence as arguemens." ;; with ithe sequence as arguemens."
(eval (pair fun seq))) ;; (eval (pair fun seq)))
(defmacro when (@test :rest @body) ;; (defmacro when (@test :rest @body)
"Executes the code in :rest if test is true." ;; "Executes the code in :rest if test is true."
(if (eval @test) ;; (if (eval @test)
(eval (pair prog @body)) ;; (eval (pair prog @body))
nil)) ;; nil))
(defmacro unless (@test :rest @body) ;; (defmacro unless (@test :rest @body)
"Executes the code in :rest if test is false." ;; "Executes the code in :rest if test is false."
(if (eval @test) ;; (if (eval @test)
nil ;; nil
(eval (pair prog @body)))) ;; (eval (pair prog @body))))
(defun end (seq) ;; (defun end (seq)
"Returns the last pair in the sqeuence." ;; "Returns the last pair in the sqeuence."
(if (or (nil? seq) (not (pair? (rest seq)))) ;; (if (or (nil? seq) (not (pair? (rest seq))))
seq ;; seq
(end (rest seq)))) ;; (end (rest seq))))
(defun last (seq) ;; (defun last (seq)
"Returns the (first) of the last (pair) of the given sequence." ;; "Returns the (first) of the last (pair) of the given sequence."
(first (end seq))) ;; (first (end seq)))
(defun extend (seq elem) ;; (defun extend (seq elem)
"Extends a list with the given element, by putting it in ;; "Extends a list with the given element, by putting it in
the (rest) of the last element of the sequence." ;; the (rest) of the last element of the sequence."
(when (pair? seq) ;; (when (pair? seq)
(define e (end seq)) ;; (define e (end seq))
(mutate e (pair (first e) elem))) ;; (mutate e (pair (first e) elem)))
seq) ;; seq)
(defun incr (val) ;; (defun incr (val)
"Adds one to the argument." ;; "Adds one to the argument."
(+ val 1)) ;; (+ val 1))
(defun decr (val) ;; (defun decr (val)
"Subtracts one from the argument." ;; "Subtracts one from the argument."
(- val 1)) ;; (- val 1))
(defun append (seq elem) ;; (defun append (seq elem)
"Appends an element to a sequence, by extendeing the list ;; "Appends an element to a sequence, by extendeing the list
with (pair elem nil)." ;; with (pair elem nil)."
(extend seq (pair elem nil))) ;; (extend seq (pair elem nil)))
(defun length (seq) ;; (defun length (seq)
"Returns the length of the given sequence." ;; "Returns the length of the given sequence."
(if (nil? seq) ;; (if (nil? seq)
0 ;; 0
(incr (length (rest seq))))) ;; (incr (length (rest seq)))))
(defmacro n-times (@times @action) ;; (defmacro n-times (@times @action)
"Executes @action @times times." ;; "Executes @action @times times."
(unless (<= (eval @times) 0) ;; (unless (<= (eval @times) 0)
(eval @action) ;; (eval @action)
(apply n-times (list (list - @times 1) @action)))) ;; (apply n-times (list (list - @times 1) @action))))
(defmacro for (@symbol @from @to :rest @for-body) ;; (defmacro for (@symbol @from @to :rest @for-body)
"Designed to resemble a C style for loop. It takes a symbol as ;; "Designed to resemble a C style for loop. It takes a symbol as
well as its starting number and end number and executes the ;; well as its starting number and end number and executes the
@for-body with the defined symbol for all numbers between @from ;; @for-body with the defined symbol for all numbers between @from
to @to, where @to is exclusive." ;; to @to, where @to is exclusive."
(if (< (eval @from) (eval @to)) ;; (if (< (eval @from) (eval @to))
(macro-define @op incr) ;; (macro-define @op incr)
(if (> (eval @from) (eval @to)) ;; (if (> (eval @from) (eval @to))
(macro-define @op decr) ;; (macro-define @op decr)
(macro-define @op nil))) ;; (macro-define @op nil)))
(when @op ;; (when @op
(macro-define (eval @symbol) (eval @from)) ;; (macro-define (eval @symbol) (eval @from))
(eval (pair prog @for-body)) ;; (eval (pair prog @for-body))
(eval (extend (list for @symbol (@op @from) @to) @for-body)))) ;; (eval (extend (list for @symbol (@op @from) @to) @for-body))))
(defun range (:keys from :defaults-to 0 to) ;; (defun range (:keys from :defaults-to 0 to)
"Returns a sequence of numbers starting with the number defined ;; "Returns a sequence of numbers starting with the number defined
by the key 'from' and ends with the number defined in 'to'." ;; by the key 'from' and ends with the number defined in 'to'."
(when (< from to) ;; (when (< from to)
(pair from (range :from (+ 1 from) :to to)))) ;; (pair from (range :from (+ 1 from) :to to))))
(defun range-while (:keys from :defaults-to 0 to) ;; (defun range-while (:keys from :defaults-to 0 to)
"Returns a sequence of numbers starting with the number defined ;; "Returns a sequence of numbers starting with the number defined
by the key 'from' and ends with the number defined in 'to'." ;; by the key 'from' and ends with the number defined in 'to'."
(define result (list (copy from))) ;; (define result (list (copy from)))
(define head result) ;; (define head result)
(mutate from (incr from)) ;; (mutate from (incr from))
(while (< from to) ;; (while (< from to)
(prog ;; (prog
(mutate head (pair (first head) (pair (copy from) nil))) ;; (mutate head (pair (first head) (pair (copy from) nil)))
(define head (rest head)) ;; (define head (rest head))
(mutate from (incr from)))) ;; (mutate from (incr from))))
result) ;; result)
(defun map (fun seq) ;; (defun map (fun seq)
"Takes a function and a sequence as arguments and returns a new ;; "Takes a function and a sequence as arguments and returns a new
sequence which contains the results of using the first sequences ;; sequence which contains the results of using the first sequences
elemens as argument to that function." ;; elemens as argument to that function."
(if (nil? seq) ;; (if (nil? seq)
seq ;; seq
(pair (fun (first seq)) ;; (pair (fun (first seq))
(map fun (rest seq))))) ;; (map fun (rest seq)))))
(defun reduce (fun seq) ;; (defun reduce (fun seq)
"Takes a function and a sequence as arguments and applies the ;; "Takes a function and a sequence as arguments and applies the
function to the argument sequence. This only works correctly if ;; function to the argument sequence. This only works correctly if
the given function accepts a variable amount of parameters. If ;; the given function accepts a variable amount of parameters. If
your funciton is limited to two arguments, use `reduce-binary' ;; your funciton is limited to two arguments, use `reduce-binary'
instead." ;; instead."
(apply fun seq)) ;; (apply fun seq))
(defun reduce-binary (fun seq) ;; (defun reduce-binary (fun seq)
"Takes a function and a sequence as arguments and applies the ;; "Takes a function and a sequence as arguments and applies the
function to the argument sequence. reduce-binary applies the ;; function to the argument sequence. reduce-binary applies the
arguments `pair-wise' which means it works with binary functions ;; arguments `pair-wise' which means it works with binary functions
as compared to `reduce'." ;; as compared to `reduce'."
(if (nil? (rest seq)) ;; (if (nil? (rest seq))
(first seq) ;; (first seq)
(fun (first seq) ;; (fun (first seq)
(reduce-binary fun (rest seq))))) ;; (reduce-binary fun (rest seq)))))
(defun filter (fun seq) ;; (defun filter (fun seq)
"Takes a function and a sequence as arguments and applies the ;; "Takes a function and a sequence as arguments and applies the
function to every value in the sequence. If the result of that ;; function to every value in the sequence. If the result of that
funciton application returns a truthy value, the original value is ;; funciton application returns a truthy value, the original value is
added to a list, which in the end is returned." ;; added to a list, which in the end is returned."
(when seq ;; (when seq
(if (fun (first seq)) ;; (if (fun (first seq))
(pair (first seq) ;; (pair (first seq)
(filter fun (rest seq))) ;; (filter fun (rest seq)))
(filter fun (rest seq))))) ;; (filter fun (rest seq)))))
(defun printf (:keys sep :defaults-to " " end :defaults-to "\n" :rest args) ;; (defun printf (:keys sep :defaults-to " " end :defaults-to "\n" :rest args)
"A wrapper for the built-in (print) that accepts a variable number ;; "A wrapper for the built-in (print) that accepts a variable number
of arguments and also provides keywords for specifying the printed ;; of arguments and also provides keywords for specifying the printed
separators between the arguments and what should be printed after the ;; separators between the arguments and what should be printed after the
las argument." ;; las argument."
(defmacro printf-quoted (:keys @sep @end :rest @args) ;; (defmacro printf-quoted (:keys @sep @end :rest @args)
(if (nil? @args) ;; (if (nil? @args)
(prog (print (eval @end)) nil) ;; (prog (print (eval @end)) nil)
(prog ;; (prog
(print (first @args)) ;; (print (first @args))
(unless (nil? (rest @args)) ;; (unless (nil? (rest @args))
(print (eval @sep))) ;; (print (eval @sep)))
(eval (pair printf-quoted ;; (eval (pair printf-quoted
(extend (list :@sep (eval @sep) :@end (eval @end)) (rest @args))))))) ;; (extend (list :@sep (eval @sep) :@end (eval @end)) (rest @args)))))))
(eval (pair printf-quoted (extend (list :@sep (eval sep) :@end (eval end)) args)))) ;; (eval (pair printf-quoted (extend (list :@sep (eval sep) :@end (eval end)) args))))
(defmacro pe (@expr) ;; (defmacro pe (@expr)
(printf @expr "evaluates to" (eval @expr))) ;; (printf @expr "evaluates to" (eval @expr)))
+23 -6
View File
@@ -1,12 +1,29 @@
(defun make-vector (x y z) (defun make-vector (x y z)
(let ((local-x x) (let ((local-x x)
(local-y y) (local-y y)
(local-z z)) (local-z z)
(lambda () (defun (macro (@name @params :rest @body)
local-x))) (eval (pair 'define-upwards (pair @name (pair (pair 'lambda (pair @params @body)) nil)))))))
(defun set-x (new-x) (mutate local-x new-x))
(defun set-y (new-y) (mutate local-y new-y))
(defun set-z (new-z) (mutate local-z new-z))
(defun dispatch (message)
(if (= message ::get-x)
local-x
(if (= message ::set-x)
set-x
nil)))
(break)
dispatch))
(define v (make-vector 1 2 3)) (define v (make-vector 1 2 3))
(print (v))
(print (v ::get-x))
((v ::set-x) 19)
(print (v ::get-x))
(read " ") (read " ")
+3 -2
View File
@@ -109,6 +109,7 @@ void append_to_keyword_argument_list(Keyword_Arguments* args,
append_to_Ast_Node_array_list(args->values, default_value); append_to_Ast_Node_array_list(args->values, default_value);
} }
struct Environment;
struct Function { struct Function {
bool is_macro; bool is_macro;
@@ -117,10 +118,10 @@ struct Function {
Keyword_Arguments* keyword_arguments; Keyword_Arguments* keyword_arguments;
// rest_argument will be nullptr if no rest argument is declared // rest_argument will be nullptr if no rest argument is declared
char* rest_argument; char* rest_argument;
struct Ast_Node* body; // implicit prog Ast_Node* body; // implicit prog
Environment* parent_environment; // we are doing closures now!!
}; };
struct Environment;
struct CFunction { struct CFunction {
std::function<Ast_Node*(Ast_Node*, Environment*)> function; std::function<Ast_Node*(Ast_Node*, Environment*)> function;
+41 -4
View File
@@ -324,7 +324,7 @@ void load_built_ins_into_environment(Environment* env) {
return value; return value;
}); });
defun("macro-define", cLambda { defun("define-upwards", cLambda {
try { try {
arguments_length = list_length(arguments); arguments_length = list_length(arguments);
} }
@@ -345,15 +345,50 @@ void load_built_ins_into_environment(Environment* env) {
report_error(Error_Type::Type_Missmatch); report_error(Error_Type::Type_Missmatch);
} }
if (!env->parent) {
report_error(Error_Type::Unknown_Error);
}
Ast_Node* value = arguments->value.pair->rest->value.pair->first; Ast_Node* value = arguments->value.pair->rest->value.pair->first;
try { try {
value = eval_expr(value, env); value = eval_expr(value, env);
} }
define_macro_symbol(symbol, value, env); define_symbol(symbol, value, env->parent);
return value; return value;
}); });
// defun("macro-define", cLambda {
// try {
// arguments_length = list_length(arguments);
// }
// if (arguments_length != 2) {
// report_error(Error_Type::Wrong_Number_Of_Arguments);
// }
// Ast_Node* symbol = arguments->value.pair->first;
// if (symbol->type == Ast_Node_Type::Pair) {
// try {
// symbol = eval_expr(symbol, env);
// }
// }
// if (symbol->type != Ast_Node_Type::Symbol) {
// report_error(Error_Type::Type_Missmatch);
// }
// Ast_Node* value = arguments->value.pair->rest->value.pair->first;
// try {
// value = eval_expr(value, env);
// }
// define_macro_symbol(symbol, value, env);
// return value;
// });
defun("mutate", cLambda { defun("mutate", cLambda {
try { try {
evaluated_arguments = eval_arguments(arguments, env, &arguments_length); evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
@@ -500,7 +535,7 @@ void load_built_ins_into_environment(Environment* env) {
if (arguments_length < 1) if (arguments_length < 1)
report_error(Error_Type::Wrong_Number_Of_Arguments); report_error(Error_Type::Wrong_Number_Of_Arguments);
Environment* let_env = create_child_environment(env, Environment_Type::Let); Environment* let_env = create_child_environment(env);
Ast_Node* bindings = arguments->value.pair->first; Ast_Node* bindings = arguments->value.pair->first;
while (true) { while (true) {
if (bindings->type == Ast_Node_Type::Nil) { if (bindings->type == Ast_Node_Type::Nil) {
@@ -564,6 +599,7 @@ void load_built_ins_into_environment(Environment* env) {
/* if (lispOperator->value.built_in_function->type == Built_In_Macro) { */ /* if (lispOperator->value.built_in_function->type == Built_In_Macro) { */
/* function->is_macro = true; */ /* function->is_macro = true; */
/* } else { */ /* } else { */
function->parent_environment = env;
function->is_macro = false; function->is_macro = false;
/* } */ /* } */
@@ -614,6 +650,7 @@ void load_built_ins_into_environment(Environment* env) {
report_error(Error_Type::Wrong_Number_Of_Arguments); report_error(Error_Type::Wrong_Number_Of_Arguments);
Function* function = new(Function); Function* function = new(Function);
function->parent_environment = env;
function->is_macro = true; function->is_macro = true;
// if parameters were specified // if parameters were specified
@@ -962,7 +999,7 @@ void load_built_ins_into_environment(Environment* env) {
} }
Environment* create_built_ins_environment() { Environment* create_built_ins_environment() {
Environment* ret = create_child_environment(nullptr, Environment_Type::Let); Environment* ret = create_child_environment(nullptr);
load_built_ins_into_environment(ret); load_built_ins_into_environment(ret);
return ret; return ret;
} }
+58 -78
View File
@@ -1,12 +1,5 @@
enum struct Environment_Type {
Let,
Lambda,
Macro,
};
struct Environment { struct Environment {
struct Environment* parent; struct Environment* parent;
Environment_Type type;
int capacity; int capacity;
int next_index; int next_index;
@@ -15,12 +8,11 @@ struct Environment {
Ast_Node** values; Ast_Node** values;
}; };
Environment* create_child_environment(Environment* parent, Environment_Type type) { Environment* create_child_environment(Environment* parent) {
Environment* env = new(Environment); Environment* env = new(Environment);
int start_capacity = 16; int start_capacity = 16;
env->type = type;
env->parent = parent; env->parent = parent;
env->capacity = start_capacity; env->capacity = start_capacity;
env->next_index = 0; env->next_index = 0;
@@ -30,19 +22,19 @@ Environment* create_child_environment(Environment* parent, Environment_Type type
return env; return env;
} }
Environment* create_empty_environment(Environment_Type type) { Environment* create_empty_environment() {
return create_child_environment(nullptr, type); return create_child_environment(nullptr);
} }
void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
if (env->type == Environment_Type::Macro) { // if (env->type == Environment_Type::Macro) {
// NOTE(Felix): we know we have a parent because every // // NOTE(Felix): we know we have a parent because every
// environment has a parent except the top level environment. // // environment has a parent except the top level environment.
// However the top level environment is not a let-environment, // // However the top level environment is not a let-environment,
// so we would not land here // // so we would not land here
define_symbol(symbol, value, env->parent); // define_symbol(symbol, value, env->parent);
return; // return;
} // }
// NOTE(Felix): right now we are simply 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
@@ -60,16 +52,16 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
++env->next_index; ++env->next_index;
} }
void define_macro_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { // void define_macro_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
if (env->type != Environment_Type::Macro) { // if (env->type != Environment_Type::Macro) {
create_error(Error_Type::Unknown_Error, symbol->sourceCodeLocation); // create_error(Error_Type::Unknown_Error, symbol->sourceCodeLocation);
return; // return;
} // }
env->type = Environment_Type::Lambda; // env->type = Environment_Type::Lambda;
define_symbol(symbol, value, env); // define_symbol(symbol, value, env);
env->type = Environment_Type::Macro; // env->type = Environment_Type::Macro;
} // }
void print_environment(Environment* env); void print_environment(Environment* env);
@@ -80,41 +72,41 @@ Ast_Node* lookup_symbol_in_this_envt(Symbol* sym, Environment* env) {
return nullptr; return nullptr;
} }
Ast_Node* lookup_symbol_from_lambda_env(Symbol* sym, Environment* env) { // Ast_Node* lookup_symbol_from_lambda_env(Symbol* sym, Environment* env) {
Ast_Node* result; // Ast_Node* result;
do { // do {
if (env->type != Environment_Type::Lambda) { // if (env->type != Environment_Type::Lambda) {
result = lookup_symbol_in_this_envt(sym, env); // result = lookup_symbol_in_this_envt(sym, env);
if (result) return result; // if (result) return result;
} // }
env = env->parent; // env = env->parent;
} while (env); // } while (env);
return nullptr; // return nullptr;
} // }
Ast_Node* lookup_symbol_from_let_or_macro_env(Symbol* sym, Environment* env) { // Ast_Node* lookup_symbol_from_let_or_macro_env(Symbol* sym, Environment* env) {
Ast_Node* result; // Ast_Node* result;
do { // do {
result = lookup_symbol_in_this_envt(sym, env); // result = lookup_symbol_in_this_envt(sym, env);
if (result) return result; // if (result) return result;
if (env->type == Environment_Type::Lambda) // if (env->type == Environment_Type::Lambda)
break; // break;
env = env->parent; // env = env->parent;
} while (env); // } while (env);
if (env) { // if (env) {
do { // do {
if (env->type != Environment_Type::Lambda) { // if (env->type != Environment_Type::Lambda) {
result = lookup_symbol_in_this_envt(sym, env); // result = lookup_symbol_in_this_envt(sym, env);
if (result) return result; // if (result) return result;
} // }
env = env->parent; // env = env->parent;
} while (env); // } while (env);
} // }
return nullptr; // return nullptr;
} // }
Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) { Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) {
// first check current environment // first check current environment
@@ -125,11 +117,7 @@ Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) {
return result; return result;
if (env->parent) { if (env->parent) {
if (env->type == Environment_Type::Lambda) { result = lookup_symbol(node, env->parent);
result = lookup_symbol_from_lambda_env(sym, env->parent);
} else {
result = lookup_symbol_from_let_or_macro_env(sym, env->parent);
}
if (result) if (result)
return result; return result;
@@ -142,14 +130,6 @@ Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) {
return create_ast_node_t(); return create_ast_node_t();
} }
// we should not need this anymore when we have c lambdas as built
// in functions
/* result = create_ast_node_built_in_function(sym->identifier); */
/* result->sourceCodeLocation = node->sourceCodeLocation; */
/* if (result) */
/* return result; */
create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation); create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation);
/* printf("%s\n", sym->identifier); */ /* printf("%s\n", sym->identifier); */
return nullptr; return nullptr;
@@ -170,12 +150,12 @@ void print_environment_indent(Environment* env, int indent) {
if (env->parent) { if (env->parent) {
print_indent(indent); print_indent(indent);
printf("parent"); printf("parent");
if (env->parent->type == Environment_Type::Lambda) // if (env->parent->type == Environment_Type::Lambda)
printf(" (lambda)"); // printf(" (lambda)");
else if (env->parent->type == Environment_Type::Macro) // else if (env->parent->type == Environment_Type::Macro)
printf(" (macro)"); // printf(" (macro)");
else if (env->parent->type == Environment_Type::Let) // else if (env->parent->type == Environment_Type::Let)
printf(" (let)"); // printf(" (let)");
printf(":\n"); printf(":\n");
print_environment_indent(env->parent, indent+4); print_environment_indent(env->parent, indent+4);
} }
+2 -3
View File
@@ -6,7 +6,8 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
// switching between "define_symbol" and "define_macro_symbol" all // switching between "define_symbol" and "define_macro_symbol" all
// the time // the time
Environment* new_env = create_child_environment(parent, Environment_Type::Lambda); // Environment* new_env = create_child_environment(parent, Environment_Type::Lambda);
Environment* new_env = create_child_environment(function->parent_environment);
// positional arguments // positional arguments
for (int i = 0; i < function->positional_arguments->next_index; ++i) { for (int i = 0; i < function->positional_arguments->next_index; ++i) {
@@ -145,8 +146,6 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
// don't have to check every time if it is macro environment or // don't have to check every time if it is macro environment or
// not // not
if (function->is_macro)
new_env->type = Environment_Type::Macro;
try { try {
result = eval_expr(function->body, new_env); result = eval_expr(function->body, new_env);
+2 -2
View File
@@ -30,7 +30,7 @@ Ast_Node* interprete_file (char* file_name) {
program = parse_program(file_name, file_content); program = parse_program(file_name, file_content);
} }
Environment* env = create_empty_environment(Environment_Type::Let); Environment* env = create_empty_environment();
load_built_ins_into_environment(env); load_built_ins_into_environment(env);
try { try {
@@ -50,7 +50,7 @@ Ast_Node* interprete_file (char* file_name) {
int interprete_stdin () { int interprete_stdin () {
printf("Welcome to the lispy interpreter.\n"); printf("Welcome to the lispy interpreter.\n");
char* line; char* line;
Environment* env = create_empty_environment(Environment_Type::Let); Environment* env = create_empty_environment();
load_built_ins_into_environment(env); load_built_ins_into_environment(env);
built_in_load("pre.slime", env); built_in_load("pre.slime", env);