-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparsing.c
132 lines (107 loc) · 3.31 KB
/
parsing.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "lval.h"
#include "mpc.h"
typedef struct {
mpc_parser_t* Number;
mpc_parser_t *Symbol;
mpc_parser_t *List;
mpc_parser_t *Sexpr;
mpc_parser_t *Qexpr;
mpc_parser_t *Expr;
mpc_parser_t *Lispy;
} lispy_lang_t;
static lispy_lang_t lispy_lang;
int create_parser(void)
{
/* Create Some Parsers */
lispy_lang.Number = mpc_new("number");
lispy_lang.Symbol = mpc_new("symbol");
lispy_lang.List = mpc_new("list");
lispy_lang.Sexpr = mpc_new("sexpr");
lispy_lang.Qexpr = mpc_new("qexpr");
lispy_lang.Lispy = mpc_new("lispy");
/* Define them with the following Language */
mpca_lang(MPCA_LANG_DEFAULT,
" \
number : /-?[0-9]+/ ; \
symbol : /[a-zA-Z0-9_+\\-*\\/\\\\=<>!&]+/ ; \
list : '(' <sexpr>* ')' ; \
sexpr : <number> | <symbol> | <list> | <qexpr> ; \
qexpr : '''<sexpr> ; \
lispy : /^/ <sexpr>* /$/ ; \
",
lispy_lang.Number, lispy_lang.Symbol, lispy_lang.List, lispy_lang.Sexpr,
lispy_lang.Qexpr, lispy_lang.Lispy);
return 0;
}
/* Read type num lval from AST */
lval* lval_read_num(mpc_ast_t* t) {
errno = 0;
long x = strtol(t->contents, NULL, 10);
return errno == 0?
lval_num(x) : lval_err(LERR_BAD_NUM, "Bad number");
}
/* Create internal structure from AST for evalution */
lval *lval_read(mpc_ast_t* t) {
/* If Symbol or Number return conversion to that type */
if (strstr(t->tag, "number")) { return lval_read_num(t); }
if (strstr(t->tag, "symbol")) { return lval_sym(t->contents); }
lval* x = NULL;
/* If root (>) or list then create empty list */
if ((strcmp(t->tag, ">") == 0) || (strstr(t->tag, "list")))
{
x = lval_list();
/* Fill this list with any valid expression contained within */
for (int i = 0; i < t->children_num; i++) {
if (strcmp(t->children[i]->contents, "(") == 0) { continue; }
if (strcmp(t->children[i]->contents, ")") == 0) { continue; }
if (strcmp(t->children[i]->tag, "regex") == 0) { continue; }
x = lval_list_add(x, lval_read(t->children[i]));
}
}
else if (strstr(t->tag, "qexpr")) {
mpc_ast_t* child = t->children[1]; /*Get 2nd children */
x = lval_qexpr();
lval* c = lval_read(child);
x = lval_qexpr_add(x, c);
}
else {
perror("Parsing fail: unpxprected tag");
exit(1);
}
return x;
}
extern lval* lval_eval(lenv* e, lval* v);
int parse_string(lenv* e, char *input)
{
static mpc_result_t r;
if (mpc_parse("<stdin>", input, lispy_lang.Lispy, &r)) {
mpc_ast_print(r.output);
/* Parse AST into List */
lval *llist = NULL;
llist = lval_read(r.output);
printf("Parsing result: ");lval_println(llist);
//lval_del(llist);
#if 1
/* Evaluate List */
lval *result;
result = lval_eval(e, llist);
printf("Evaluating result: ");lval_println(result);
lval_del(result);
#endif
mpc_ast_delete(r.output);
} else {
mpc_err_print(r.error);
mpc_err_delete(r.error);
}
return 0;
}
//todo 2/7
//
void clean_parser(void)
{
mpc_cleanup(4, lispy_lang.Number, lispy_lang.Symbol,
lispy_lang.List, lispy_lang.Sexpr, lispy_lang.Lispy);
}