Kaynağa Gözat

okay

master
FelixBrendel 7 yıl önce
ebeveyn
işleme
dd2be2cb87
11 değiştirilmiş dosya ile 108 ekleme ve 43 silme
  1. +1
    -0
      bin/test.lsp
  2. +1
    -1
      build.bat
  3. +4
    -3
      src/env.c
  4. +3
    -0
      src/error.c
  5. +4
    -5
      src/eval.c
  6. +34
    -1
      src/helpers.c
  7. +6
    -1
      src/io.c
  8. +38
    -9
      src/main.c
  9. +11
    -3
      src/parse.c
  10. +0
    -13
      src/test.lsp
  11. +6
    -7
      todo.org

+ 1
- 0
bin/test.lsp Dosyayı Görüntüle

@@ -0,0 +1 @@
(/ (+ 1 (- 100 7 3)) 2)

+ 1
- 1
build.bat Dosyayı Görüntüle

@@ -19,7 +19,7 @@ if %errorlevel% == 0 (
move %exeName% ..\%binDir%\ > NUL
pushd ..\%binDir%
echo ---------- Running ----------
call timecmd %exeName%
call timecmd %exeName% test.lsp
del %exeName% /S /Q > NUL
popd
) else (


+ 4
- 3
src/env.c Dosyayı Görüntüle

@@ -54,9 +54,10 @@ Ast_Node* lookup_symbol(Symbol* sym, Environment* env) {
}
}

char* message;
asprintf(&message, "Symbol not defined: %s\n", sym->identifier);
panic(message);
create_error(Error_Type_Symbol_Not_Defined, create_ast_node_nil());
/* char* message; */
/* asprintf(&message, "Symbol not defined: %s\n", sym->identifier); */
/* panic(message); */

return nullptr;
}

+ 3
- 0
src/error.c Dosyayı Görüntüle

@@ -6,6 +6,7 @@ typedef enum {
Error_Type_Not_A_Function,
Error_Type_Not_Yet_Implemented,
Error_Type_Syntax_Error,
Error_Type_Unexpected_Eof,
Error_Type_Unknown_Error,
} Error_Type;

@@ -40,6 +41,8 @@ char* Error_Type_to_string(Error_Type type) {
case Error_Type_Type_Missmatch: return "Type Missmatch";
case Error_Type_Not_Yet_Implemented: return "Not yet implemented";
case Error_Type_Syntax_Error: return "Syntax Error";
case Error_Type_Unexpected_Eof: return "Unexpected EOF";
default: return "Unknown Error";
}
}


+ 4
- 5
src/eval.c Dosyayı Görüntüle

@@ -43,6 +43,8 @@ void eval_operands(Ast_Node* operands, Environment* env) {
Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
#define report_error(_type) { \
create_error(_type, node); \
log_error(); \
exit(1); \
return nullptr; \
}

@@ -56,7 +58,6 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
case Ast_Node_Type_Number:
case Ast_Node_Type_String:
return node;

case Ast_Node_Type_Pair: {
Ast_Node* operator = eval_expr(node->value.pair->first, env);
Ast_Node* operands = node->value.pair->rest;
@@ -81,9 +82,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
} else if (string_equal("if", operator_name)) {
int operands_length = list_length(operands);
if (operands_length != 2 && operands_length != 3) {
if (!error)
create_error(Error_Type_Wrong_Number_Of_Arguments, operands);
return nullptr;
report_error(Error_Type_Wrong_Number_Of_Arguments);
}

Ast_Node* condition = operands->value.pair->first;
@@ -144,7 +143,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
}

default:
report_error(Error_Type_Unknown_Error);
report_error(Error_Type_Not_A_Function);
}
#undef report_error
}


+ 34
- 1
src/helpers.c Dosyayı Görüntüle

@@ -57,10 +57,11 @@ char* read_entire_file (char* filename) {
}

/* Allocate our buffer to that size. */
fileContent = malloc(sizeof(char) * (bufsize));
fileContent = malloc(sizeof(char) * (bufsize) +1);

/* Read the entire file into memory. */
size_t newLen = fread(fileContent, sizeof(char), bufsize, fp);
fileContent[bufsize-1] = '\0';
if ( ferror( fp ) != 0 ) {
fputs("Error reading file", stderr);
}
@@ -72,3 +73,35 @@ char* read_entire_file (char* filename) {
return fileContent;
/* Don't forget to call free() later! */
}

char* read_line() {
char * line = malloc(100), * linep = line;
size_t lenmax = 100, len = lenmax;
int c;

if(line == NULL)
return NULL;

for(;;) {
c = fgetc(stdin);
if(c == EOF)
break;

if(--len == 0) {
len = lenmax;
char * linen = realloc(linep, lenmax *= 2);

if(linen == NULL) {
free(linep);
return NULL;
}
line = linen + (line - linep);
linep = linen;
}

if((*line++ = c) == '\n')
break;
}
*line = '\0';
return linep;
}

+ 6
- 1
src/io.c Dosyayı Görüntüle

@@ -77,9 +77,14 @@ void print(Ast_Node* node) {
Ast_Node* head = node;
printf("(");

while (1) {
// NOTE(Felix): We cold do a while true here, however in case
// we want to print a broken list (for logging the error) we
// should do mo checks.
while (head) {
print(head->value.pair->first);
head = head->value.pair->rest;
if (!head)
return;
if (head->type != Ast_Node_Type_Pair)
break;
printf(" ");


+ 38
- 9
src/main.c Dosyayı Görüntüle

@@ -17,16 +17,45 @@
#include "./testing.c"

int main (int argc, char *argv[]) {
/* if (argc > 1) { */
/* char* fileContent = read_entire_file(argv[1]); */
/* if (fileContent) { */
/* printf("File: %s\n", fileContent); */
/* } */
/* } else { */
/* printf("No source provided.\n"); */
/* } */
if (argc > 1) {
char* fileContent = read_entire_file(argv[1]);
if (fileContent) {
Ast_Node_Array_List* program = parse_program(fileContent);
if (error) {
log_error();
exit(1);
}
Environment* env = create_empty_environment();
Ast_Node* result = create_ast_node_nil();
for (int i = 0; i < program->next_index; ++i) {
result = eval_expr(program->data[i], env);
if (error) {
log_error();
exit(1);
}
}
print(result);
printf("\n");
} else {
printf("The file could not be read\n");
}
} else {
run_all_tests();

printf("Welcome to the lispy interpreter.\n");
char* line;
Environment* env = create_empty_environment();
Ast_Node* parsed, * evaluated;
while (true) {
printf(">");
line = read_line();
parsed = parse_single_expression(line);
evaluated = eval_expr(parsed, env);
print(evaluated);
printf("\n");
}
}

run_all_tests();

return 0;
}

+ 11
- 3
src/parse.c Dosyayı Görüntüle

@@ -196,6 +196,11 @@ Ast_Node* parse_expression(char* text, int* index_in_text) {
}

eat_until_code(text, index_in_text);
if (text[(*index_in_text)] == '\0') {
create_error(Error_Type_Unexpected_Eof, expression);
return nullptr;
}


if (text[(*index_in_text)] == ')') {
head->value.pair->rest = create_ast_node_nil();
@@ -237,8 +242,10 @@ Ast_Node_Array_List* parse_program(char* text) {
while (text[index_in_text] != '\0') {
switch (text[index_in_text]) {
case '(': {
append_to_Ast_Node_Array_List(
program, parse_expression(text, &index_in_text));
Ast_Node* parsed = parse_expression(text, &index_in_text);
if (error)
return nullptr;
append_to_Ast_Node_Array_List(program, parsed);
} break;
case ';': {
eat_comment_line(text, &index_in_text);
@@ -249,8 +256,9 @@ Ast_Node_Array_List* parse_program(char* text) {
++index_in_text;
} break;
default:
create_error(Error_Type_Syntax_Error, nullptr);
/* syntax error */
create_error(Error_Type_Syntax_Error, create_ast_node_nil());
return nullptr;
}
}
return program;


+ 0
- 13
src/test.lsp Dosyayı Görüntüle

@@ -1,13 +0,0 @@
(+ 1 (- 100 7) 3)

(defun unpack (&rest args)
(car args))
(unpack '(1 2))

(defun add (&rest args)
(if args
(+ (first args)
(apply 'add 'args)))
0)

(add 2 123 99)

+ 6
- 7
todo.org Dosyayı Görüntüle

@@ -15,9 +15,12 @@

** DONE if
CLOSED: [2018-09-18 Di 12:14]
** TODO and (short circuiting)
** TODO or
** TODO not
** DONE and (short circuiting)
CLOSED: [2018-10-05 Fr 22:21]
** DONE or
CLOSED: [2018-10-05 Fr 22:21]
** DONE not
CLOSED: [2018-10-05 Fr 22:21]
#+begin_src emacs-lisp
(not 1) ;; == (not . (1 . nil))
(not (expression 1 3)) ;; == (not . ((expression . (1 . (3 . nil))) . nil))
@@ -34,16 +37,12 @@

** TODO load (import)
** TODO define

** TODO lambda
** TODO progn

** TODO eval
** TODO quote

** TODO print
** TODO read

** TODO help

* Types


Yükleniyor…
İptal
Kaydet