Browse Source

Add chapter 6

T. Meissner 7 months ago
parent
commit
84abd5e5eb
2 changed files with 97 additions and 0 deletions
  1. 13
    0
      chapter_06/Makefile
  2. 84
    0
      chapter_06/parsing.c

+ 13
- 0
chapter_06/Makefile View File

@@ -0,0 +1,13 @@
1
+MPC_DIR := ../mpc
2
+
3
+
4
+all: parsing
5
+
6
+
7
+%: %.c
8
+	cc -std=c11 -Wall $@.c ${MPC_DIR}/mpc.c -ledit -o $@
9
+
10
+
11
+.PHONY: clean
12
+clean:
13
+	rm -rf parsing

+ 84
- 0
chapter_06/parsing.c View File

@@ -0,0 +1,84 @@
1
+#include <stdio.h>
2
+#include <stdlib.h>
3
+#include "../mpc/mpc.h"
4
+
5
+
6
+/* If we are on Windows compile these functions */
7
+#ifdef _WIN32
8
+#include <string.h>
9
+#include <assert.h>
10
+
11
+static char buffer[2048];
12
+
13
+/* Fake readline function */
14
+char* readline(char* prompt) {
15
+    fputs(prompt, stdout);
16
+    fgets(buffer, 2048, stdin);
17
+    char* cpy = malloc(strlen(buffer)+1);
18
+    assert(cpy != NULL)
19
+    strcpy(cpy, buffer);
20
+    cpy[strlen(cpy)-1] = '\0';
21
+    return cpy;
22
+}
23
+
24
+/* Fake add_history function */
25
+void add_history(char* unused) {}
26
+
27
+/* Otherwise include the editline headers
28
+   could use __APPLE__ for detection of OSX */
29
+#else
30
+#include <editline/readline.h>
31
+#endif
32
+
33
+
34
+int main(int argc, char const *argv[])
35
+{
36
+    /* Create some parsers */
37
+    mpc_parser_t* Number = mpc_new("number");
38
+    mpc_parser_t* Operator = mpc_new("operator");
39
+    mpc_parser_t* Expr = mpc_new("expr");
40
+    mpc_parser_t* Lispy = mpc_new("lispy");
41
+
42
+    /* Define them with the following language */
43
+    mpca_lang(MPCA_LANG_DEFAULT,
44
+        "                                                        \
45
+            number   : /-?[0-9]+/ ;                              \
46
+            operator : '+' | '-' | '*' | '/' ;                   \
47
+            expr     : <number> |  '(' <operator> <expr>+ ')' ;  \
48
+            lispy    : /^/ <operator> <expr>+ /$/ ;              \
49
+        ",
50
+        Number, Operator, Expr, Lispy);
51
+
52
+    /* Print version and exit information */
53
+    puts("Lispy version 0.0.0.0.1");
54
+    puts("Press Ctrl+c to exit\n");
55
+
56
+    /* In a never ending loop */
57
+    while (1) {
58
+        /* Output our prompt and get input */
59
+        char* input = readline("lispy> ");
60
+
61
+        /* Add input to history */
62
+        add_history(input);
63
+
64
+        /* Attempt to parse the user input */
65
+        mpc_result_t r;
66
+        if (mpc_parse("<stdin>", input, Lispy, &r)) {
67
+            /* On success print the AST */
68
+            mpc_ast_print(r.output);
69
+            mpc_ast_delete(r.output);
70
+        } else {
71
+            /* Otherwise print the error */
72
+            mpc_err_print(r.error);
73
+            mpc_err_delete(r.error);
74
+        }
75
+
76
+        /* Free retrieved input */
77
+        free(input);
78
+    }
79
+
80
+    /* Undefine and delete our parsers */
81
+    mpc_cleanup(4, Number, Operator, Expr, Lispy);
82
+
83
+    return 0;
84
+}