Merge pull request #514 from alimpfard/jq-fix
[jackhill/mal.git] / impls / c / step1_read_print.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <unistd.h>
5
6 #include "types.h"
7 #include "readline.h"
8 #include "reader.h"
9
10 // read
11 MalVal *READ(char prompt[], char *str) {
12 char *line;
13 MalVal *ast;
14 if (str) {
15 line = str;
16 } else {
17 line = _readline(prompt);
18 if (!line) {
19 _error("EOF");
20 return NULL;
21 }
22 }
23 ast = read_str(line);
24 if (!str) { MAL_GC_FREE(line); }
25 return ast;
26 }
27
28 // eval
29 MalVal *EVAL(MalVal *ast, GHashTable *env) {
30 if (!ast || mal_error) return NULL;
31 return ast;
32 }
33
34 // print
35 char *PRINT(MalVal *exp) {
36 if (mal_error) {
37 return NULL;
38 }
39 return _pr_str(exp,1);
40 }
41
42 // repl
43
44 // read and eval
45 MalVal *RE(GHashTable *env, char *prompt, char *str) {
46 MalVal *ast, *exp;
47 ast = READ(prompt, str);
48 if (!ast || mal_error) return NULL;
49 exp = EVAL(ast, env);
50 if (ast != exp) {
51 malval_free(ast); // Free input structure
52 }
53 return exp;
54 }
55
56 int main()
57 {
58 MalVal *exp;
59 char *output;
60 char prompt[100];
61
62 MAL_GC_SETUP();
63
64 // Set the initial prompt
65 snprintf(prompt, sizeof(prompt), "user> ");
66
67 // repl loop
68 for(;;) {
69 exp = RE(NULL, prompt, NULL);
70 if (mal_error && strcmp("EOF", mal_error->val.string) == 0) {
71 return 0;
72 }
73 output = PRINT(exp);
74
75 if (mal_error) {
76 fprintf(stderr, "Error: %s\n", _pr_str(mal_error,1));
77 malval_free(mal_error);
78 mal_error = NULL;
79 } else if (output) {
80 puts(output);
81 MAL_GC_FREE(output); // Free output string
82 }
83
84 //malval_free(exp); // Free evaluated expression
85 }
86 }