We have the beginning of a stdlib and can parse keyword and rest args
This commit is contained in:
@@ -0,0 +1,73 @@
|
|||||||
|
(define nil ())
|
||||||
|
|
||||||
|
(define nil?
|
||||||
|
(lambda (x)
|
||||||
|
"Checks if the argument is nil."
|
||||||
|
(= x nil)))
|
||||||
|
|
||||||
|
(define append
|
||||||
|
(lambda (obj sequence)
|
||||||
|
(if (nil? sequence)
|
||||||
|
(list obj)
|
||||||
|
(if (nil? (rest sequence))
|
||||||
|
))))
|
||||||
|
|
||||||
|
(define range
|
||||||
|
(lambda (:keys from :defaults-to 0 to)
|
||||||
|
"Returns a sequence of numbers starting with the number
|
||||||
|
defined by the key 'from' and ends with the number defined in
|
||||||
|
'to'."
|
||||||
|
(if (<= from to)
|
||||||
|
(pair from (range :from (+ 1 from) :to to))
|
||||||
|
nil)))
|
||||||
|
|
||||||
|
(define map
|
||||||
|
(lambda (function sequence)
|
||||||
|
"Takes a sequence and a function as arguments and returns a
|
||||||
|
new sequence which contains the results of using the first
|
||||||
|
sequences elemens as argument to that function."
|
||||||
|
(if (nil? sequence)
|
||||||
|
sequence
|
||||||
|
(pair (function (first sequence))
|
||||||
|
(map (rest sequence) function)))))
|
||||||
|
|
||||||
|
(define reduce
|
||||||
|
(lambda (function sequence)
|
||||||
|
"Takes a sequence and a function as arguments and applies the
|
||||||
|
function to the argument sequence. This only works correctly if the
|
||||||
|
given function accepts a variable amount of parameters. If your
|
||||||
|
funciton is limited to two arguments, use `reduce-binary' instead."
|
||||||
|
(eval (pair function sequence))))
|
||||||
|
|
||||||
|
(define reduce-binary
|
||||||
|
(lambda (function sequence)
|
||||||
|
"Takes a sequence and a function as arguments and applies the
|
||||||
|
function to the argument sequence. reduce-binary applies the
|
||||||
|
arguments `pair-wise' which means it works with binary functions
|
||||||
|
as compared to `reduce'."
|
||||||
|
(if (nil? (rest sequence))
|
||||||
|
(first sequence)
|
||||||
|
(function (first sequence)
|
||||||
|
(reduce-binary (rest sequence) function)))))
|
||||||
|
|
||||||
|
(define filter
|
||||||
|
(lambda (function sequence)
|
||||||
|
(if (nil? sequence)
|
||||||
|
nil
|
||||||
|
(if (function (first sequence))
|
||||||
|
(pair (first sequence)
|
||||||
|
(filter (rest sequence) function))
|
||||||
|
(filter (rest sequence) function)))))
|
||||||
|
|
||||||
|
(define printf
|
||||||
|
(lambda (:keys sep :defaults-to " " end :defaults-to "\n" :rest args)
|
||||||
|
(if (and (nil? (first args)) (nil? (rest args)))
|
||||||
|
(print end)
|
||||||
|
(prog
|
||||||
|
(print (first args))
|
||||||
|
(if (not (nil? (rest args)))
|
||||||
|
(print sep))
|
||||||
|
;; TODO(Felix): later we should use `extend' here:
|
||||||
|
;; (eval (extend (quote (printf :sep sep :end end)) (rest args)))
|
||||||
|
(eval (pair printf (pair :sep (pair sep (pair :end (pair end (rest args)))))))
|
||||||
|
nil))))
|
||||||
@@ -1,2 +1 @@
|
|||||||
(define operators (list + - * /))
|
(define operators (list + - * /))
|
||||||
(print ((first operators) 1 2 3))
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ pushd quickbuild
|
|||||||
taskkill /F /IM %exeName% > NUL 2> NUL
|
taskkill /F /IM %exeName% > NUL 2> NUL
|
||||||
|
|
||||||
echo ---------- Compiling ----------
|
echo ---------- Compiling ----------
|
||||||
call timecmd cl ../src/main.c /Fe%exeName% /W3 /TC /nologo /EHsc /Z7 /link /incremental /debug:fastlink
|
call timecmd cl ../src/main.c /Fe%exeName% /W3 /Ox /O2 /Oi /TC /nologo /EHsc /link
|
||||||
|
|
||||||
if %errorlevel% == 0 (
|
if %errorlevel% == 0 (
|
||||||
echo.
|
echo.
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
struct Ast_Node;
|
struct Ast_Node;
|
||||||
|
define_array_list(struct Ast_Node*, Ast_Node);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
Ast_Node_Type_Nil,
|
Ast_Node_Type_Nil,
|
||||||
@@ -36,13 +37,8 @@ typedef struct {
|
|||||||
} Pair;
|
} Pair;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct Ast_Node** data;
|
// TODO(Felix) use Ast_Node_symbols here instead, so we don't have
|
||||||
int length;
|
// to convert them to strings and back to symbols
|
||||||
int next_index;
|
|
||||||
} Ast_Node_Array_List;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char** identifiers;
|
char** identifiers;
|
||||||
int next_index;
|
int next_index;
|
||||||
int length;
|
int length;
|
||||||
@@ -58,8 +54,8 @@ typedef struct {
|
|||||||
} Keyword_Arguments;
|
} Keyword_Arguments;
|
||||||
|
|
||||||
|
|
||||||
Ast_Node_Array_List* create_Ast_Node_Array_List(int initial_length);
|
/* Ast_Node_Array_List* create_Ast_Node_Array_List(int initial_length); */
|
||||||
void append_to_Ast_Node_Array_List(Ast_Node_Array_List* list, struct Ast_Node* node);
|
/* void append_to_Ast_Node_Array_List(Ast_Node_Array_List* list, struct Ast_Node* node); */
|
||||||
|
|
||||||
Positional_Arguments* create_positional_argument_list(int initial_capacity) {
|
Positional_Arguments* create_positional_argument_list(int initial_capacity) {
|
||||||
Positional_Arguments* ret = new(Positional_Arguments);
|
Positional_Arguments* ret = new(Positional_Arguments);
|
||||||
@@ -80,7 +76,7 @@ void append_to_positional_argument_list(Positional_Arguments* args, char* identi
|
|||||||
Keyword_Arguments* create_keyword_argument_list(int initial_capacity) {
|
Keyword_Arguments* create_keyword_argument_list(int initial_capacity) {
|
||||||
Keyword_Arguments* ret = new(Keyword_Arguments);
|
Keyword_Arguments* ret = new(Keyword_Arguments);
|
||||||
ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*));
|
ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*));
|
||||||
ret->values = create_Ast_Node_Array_List(initial_capacity);
|
ret->values = create_Ast_Node_array_list(initial_capacity);
|
||||||
ret->next_index = 0;
|
ret->next_index = 0;
|
||||||
ret->length = initial_capacity;
|
ret->length = initial_capacity;
|
||||||
return ret;
|
return ret;
|
||||||
@@ -96,7 +92,7 @@ void append_to_keyword_argument_list(Keyword_Arguments* args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
args->identifiers[args->next_index++] = identifier;
|
args->identifiers[args->next_index++] = identifier;
|
||||||
append_to_Ast_Node_Array_List(args->values, default_value);
|
append_to_Ast_Node_array_list(args->values, default_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
Ast_Node* eval_expr(Ast_Node* node, Environment* env);
|
||||||
|
|
||||||
bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) {
|
bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) {
|
||||||
if (n1 == n2)
|
if (n1 == n2)
|
||||||
return true;
|
return true;
|
||||||
@@ -120,3 +122,24 @@ Ast_Node* built_in_divide(Ast_Node* operands) {
|
|||||||
}
|
}
|
||||||
return create_ast_node_number(quotient);
|
return create_ast_node_number(quotient);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Ast_Node* built_in_load(char* file_name, Environment* env) {
|
||||||
|
char* file_content = read_entire_file(file_name);
|
||||||
|
if (file_content) {
|
||||||
|
Ast_Node* result = create_ast_node_nil();
|
||||||
|
Ast_Node_Array_List* program;
|
||||||
|
try {
|
||||||
|
program = parse_program(file_content);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < program->next_index; ++i) {
|
||||||
|
try {
|
||||||
|
result = eval_expr(program->data[i], env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
create_error(Error_Type_Unknown_Error, create_ast_node_nil());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,5 +60,6 @@ Ast_Node* lookup_symbol(Symbol* sym, Environment* env) {
|
|||||||
return built_in;
|
return built_in;
|
||||||
|
|
||||||
create_error(Error_Type_Symbol_Not_Defined, create_ast_node_nil());
|
create_error(Error_Type_Symbol_Not_Defined, create_ast_node_nil());
|
||||||
|
printf("%s\n", sym->identifier);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
+155
-4
@@ -6,6 +6,9 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
// 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) {
|
||||||
if (arguments->type == Ast_Node_Type_Pair) {
|
if (arguments->type == Ast_Node_Type_Pair) {
|
||||||
|
// TODO(Felix): here we create new ast_node_symbols from
|
||||||
|
// their identifiers but before we converted them to
|
||||||
|
// strings from symbols... Wo maybe just use the symbols?
|
||||||
define_symbol(
|
define_symbol(
|
||||||
create_ast_node_symbol(function->positional_arguments->identifiers[i]),
|
create_ast_node_symbol(function->positional_arguments->identifiers[i]),
|
||||||
arguments->value.pair->first, new_env);
|
arguments->value.pair->first, new_env);
|
||||||
@@ -17,6 +20,122 @@ 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)
|
||||||
|
goto eval_time;
|
||||||
|
|
||||||
|
String_Array_List* read_in_keywords = create_String_array_list(16);
|
||||||
|
// keyword arguments: use all given ones and keep track of the
|
||||||
|
// added ones (array list), if end of parameters in encountered or
|
||||||
|
// something that is not a keyword is encountered or a keyword
|
||||||
|
// that is not recognized is encoutered, jump out of the loop.
|
||||||
|
|
||||||
|
while (arguments->value.pair->first->type == Ast_Node_Type_Keyword) {
|
||||||
|
// check if this one is even an accepted keyword
|
||||||
|
bool accepted = false;
|
||||||
|
for (int i = 0; i < function->keyword_arguments->next_index; ++i) {
|
||||||
|
if (string_equal(
|
||||||
|
arguments->value.pair->first->value.keyword->identifier,
|
||||||
|
function->keyword_arguments->identifiers[i]))
|
||||||
|
{
|
||||||
|
accepted = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!accepted) {
|
||||||
|
create_error(Error_Type_Ill_Formed_Arguments, arguments);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if it was already read in
|
||||||
|
for (int i = 0; i < read_in_keywords->next_index; ++i) {
|
||||||
|
if (string_equal(
|
||||||
|
arguments->value.pair->first->value.keyword->identifier,
|
||||||
|
read_in_keywords->data[i]))
|
||||||
|
{
|
||||||
|
// TODO(Felix): if we are actually done with all the
|
||||||
|
// necessary keywords then we have to count the rest
|
||||||
|
// as :rest here, instead od always creating an error
|
||||||
|
// (special case with default variables)
|
||||||
|
create_error(Error_Type_Ill_Formed_Arguments, arguments);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// okay so we found a keyword that has to be read in and was
|
||||||
|
// not already read in, is there a next element to actually
|
||||||
|
// set it to?
|
||||||
|
if (arguments->value.pair->rest->type != Ast_Node_Type_Pair) {
|
||||||
|
create_error(Error_Type_Ill_Formed_Arguments, arguments);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not set it and then add it to the array list
|
||||||
|
define_symbol(
|
||||||
|
create_ast_node_symbol(arguments->value.pair->first->value.keyword->identifier),
|
||||||
|
arguments->value.pair->rest->value.pair->first, new_env);
|
||||||
|
|
||||||
|
append_to_String_array_list(read_in_keywords, arguments->value.pair->first->value.keyword->identifier);
|
||||||
|
|
||||||
|
// overstep both for next one
|
||||||
|
arguments = arguments->value.pair->rest->value.pair->rest;
|
||||||
|
|
||||||
|
if (arguments->type == Ast_Node_Type_Nil) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// check if all necessary keywords have been read in
|
||||||
|
for (int i = 0; i < function->keyword_arguments->next_index; ++i) {
|
||||||
|
char* defined_keyword = function->keyword_arguments->identifiers[i];
|
||||||
|
bool was_set = false;
|
||||||
|
for (int j = 0; j < read_in_keywords->next_index; ++j) {
|
||||||
|
if (string_equal(
|
||||||
|
read_in_keywords->data[j],
|
||||||
|
defined_keyword))
|
||||||
|
{
|
||||||
|
was_set = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (function->keyword_arguments->values->data[i] == nullptr) {
|
||||||
|
// if this one does not have a default value
|
||||||
|
if (!was_set) {
|
||||||
|
create_error(Error_Type_Ill_Formed_Arguments, arguments);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// this one does have a default value, lets see if we have
|
||||||
|
// to use it or if the user supplied his own
|
||||||
|
if (!was_set) {
|
||||||
|
define_symbol(
|
||||||
|
create_ast_node_symbol(defined_keyword),
|
||||||
|
function->keyword_arguments->values->data[i], new_env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (arguments->type == Ast_Node_Type_Nil) {
|
||||||
|
if (function->rest_argument) {
|
||||||
|
define_symbol(
|
||||||
|
create_ast_node_symbol(function->rest_argument),
|
||||||
|
create_ast_node_nil(), new_env);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (function->rest_argument) {
|
||||||
|
define_symbol(
|
||||||
|
create_ast_node_symbol(function->rest_argument),
|
||||||
|
arguments, new_env);
|
||||||
|
} else {
|
||||||
|
// rest was not declared but additional arguments were found
|
||||||
|
create_error(Error_Type_Ill_Formed_Arguments, arguments);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eval_time:
|
||||||
Ast_Node* result;
|
Ast_Node* result;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -26,7 +145,16 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (define type (lambda (e) (if (and (= (old-type e) :pair) (= (first e) :my-type)) :my-type (old-type e)))) */
|
/*
|
||||||
|
(prog
|
||||||
|
(define type--before type)
|
||||||
|
(define type
|
||||||
|
(lambda (e)
|
||||||
|
(if (and (= (type--before e) :pair) (= (first e) :my-type))
|
||||||
|
:my-type
|
||||||
|
(type--before e))))
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This parses the argument specification of funcitons into their
|
This parses the argument specification of funcitons into their
|
||||||
@@ -281,7 +409,9 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
|||||||
return node;
|
return node;
|
||||||
case Ast_Node_Type_Pair: {
|
case Ast_Node_Type_Pair: {
|
||||||
Ast_Node* operator;
|
Ast_Node* operator;
|
||||||
if (node->value.pair->first->type != Ast_Node_Type_Built_In_Function) {
|
if (node->value.pair->first->type != Ast_Node_Type_Built_In_Function &&
|
||||||
|
node->value.pair->first->type != Ast_Node_Type_Function)
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
operator = eval_expr(node->value.pair->first, env);
|
operator = eval_expr(node->value.pair->first, env);
|
||||||
}
|
}
|
||||||
@@ -465,6 +595,23 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
|||||||
case Built_In_Equal: {
|
case Built_In_Equal: {
|
||||||
return built_in_equals(evaluated_arguments);
|
return built_in_equals(evaluated_arguments);
|
||||||
}
|
}
|
||||||
|
case Built_In_Load: {
|
||||||
|
try {
|
||||||
|
arguments_length = list_length(arguments);
|
||||||
|
}
|
||||||
|
if (arguments_length != 1)
|
||||||
|
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||||
|
|
||||||
|
if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_String)
|
||||||
|
report_error(Error_Type_Type_Missmatch);
|
||||||
|
|
||||||
|
Ast_Node* result;
|
||||||
|
try {
|
||||||
|
result = built_in_load(
|
||||||
|
evaluated_arguments->value.pair->first->value.string->value, env);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
case Built_In_Pair: {
|
case Built_In_Pair: {
|
||||||
if (arguments_length != 2) {
|
if (arguments_length != 2) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||||
@@ -525,7 +672,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
|||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
print(evaluated_arguments->value.pair->first);
|
print(evaluated_arguments->value.pair->first);
|
||||||
printf("\n");
|
/* printf("\n"); */
|
||||||
return arguments->value.pair->first;
|
return arguments->value.pair->first;
|
||||||
}
|
}
|
||||||
case Built_In_Read: {
|
case Built_In_Read: {
|
||||||
@@ -582,7 +729,9 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// assume it's lambda function and evaluate the arguments
|
// assume it's lambda function and evaluate the arguments
|
||||||
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
|
}
|
||||||
if (operator->type == Ast_Node_Type_Function) {
|
if (operator->type == Ast_Node_Type_Function) {
|
||||||
Ast_Node* result;
|
Ast_Node* result;
|
||||||
try {
|
try {
|
||||||
@@ -592,9 +741,11 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default: {
|
||||||
|
printf("alskjdalskdjaldskjalk");
|
||||||
report_error(Error_Type_Not_A_Function);
|
report_error(Error_Type_Not_A_Function);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#undef report_error
|
#undef report_error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,35 @@
|
|||||||
} \
|
} \
|
||||||
else label(body,__LINE__):
|
else label(body,__LINE__):
|
||||||
|
|
||||||
|
#define define_array_list(type, name) \
|
||||||
|
typedef struct { \
|
||||||
|
type* data; \
|
||||||
|
int length; \
|
||||||
|
int next_index; \
|
||||||
|
} name##_Array_List; \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
void append_to_##name##_array_list(name##_Array_List* arraylist, type element) { \
|
||||||
|
if (arraylist->next_index == arraylist->length) { \
|
||||||
|
arraylist->length *= 2; \
|
||||||
|
arraylist->data = \
|
||||||
|
(type*)realloc(arraylist->data, arraylist->length * sizeof(type)); \
|
||||||
|
} \
|
||||||
|
arraylist->data[arraylist->next_index++] = element; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
name##_Array_List* create_##name##_array_list(int initial_capacity) { \
|
||||||
|
name##_Array_List* ret = new(name##_Array_List); \
|
||||||
|
ret->data = (type*)malloc(initial_capacity * sizeof(type)); \
|
||||||
|
ret->next_index = 0; \
|
||||||
|
ret->length = initial_capacity; \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
|
||||||
|
define_array_list(char*, String);
|
||||||
|
|
||||||
|
|
||||||
typedef enum { false, true } bool;
|
typedef enum { false, true } bool;
|
||||||
|
|
||||||
int string_equal(char* a, char* b) {
|
int string_equal(char* a, char* b) {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ void print(Ast_Node* node) {
|
|||||||
printf("%f", node->value.number->value);
|
printf("%f", node->value.number->value);
|
||||||
} break;
|
} break;
|
||||||
case (Ast_Node_Type_String): {
|
case (Ast_Node_Type_String): {
|
||||||
printf("\"%s\"", node->value.string->value);
|
printf("%s", node->value.string->value);
|
||||||
} break;
|
} break;
|
||||||
case (Ast_Node_Type_Symbol): {
|
case (Ast_Node_Type_Symbol): {
|
||||||
printf("%s", node->value.symbol->identifier);
|
printf("%s", node->value.symbol->identifier);
|
||||||
|
|||||||
+15
-2
@@ -24,6 +24,13 @@ int interprete_file (char* file_content) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
Environment* env = create_empty_environment();
|
Environment* env = create_empty_environment();
|
||||||
|
|
||||||
|
built_in_load("pre.slime", env);
|
||||||
|
if (error) {
|
||||||
|
log_error();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
Ast_Node* result = create_ast_node_nil();
|
Ast_Node* result = create_ast_node_nil();
|
||||||
for (int i = 0; i < program->next_index; ++i) {
|
for (int i = 0; i < program->next_index; ++i) {
|
||||||
result = eval_expr(program->data[i], env);
|
result = eval_expr(program->data[i], env);
|
||||||
@@ -32,8 +39,7 @@ int interprete_file (char* file_content) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* print(result); */
|
|
||||||
/* printf("\n"); */
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,6 +47,13 @@ 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* env = create_empty_environment();
|
||||||
|
|
||||||
|
built_in_load("pre.slime", env);
|
||||||
|
if (error) {
|
||||||
|
log_error();
|
||||||
|
delete_error();
|
||||||
|
}
|
||||||
|
|
||||||
Ast_Node* parsed, * evaluated;
|
Ast_Node* parsed, * evaluated;
|
||||||
while (true) {
|
while (true) {
|
||||||
printf(">");
|
printf(">");
|
||||||
|
|||||||
Reference in New Issue
Block a user