summaryrefslogtreecommitdiffstats
path: root/parser.c
diff options
context:
space:
mode:
Diffstat (limited to 'parser.c')
-rw-r--r--parser.c174
1 files changed, 174 insertions, 0 deletions
diff --git a/parser.c b/parser.c
new file mode 100644
index 0000000..574d2ac
--- /dev/null
+++ b/parser.c
@@ -0,0 +1,174 @@
1#include "parser.h"
2#include "lexer.h"
3#include "types.h"
4#include <stdio.h>
5
6
7LISP_OBJECT *parser_parse_str(char *str)
8{
9 Lexer *lexer = lexer_tokenize(str);
10 lexer_tokens_reverse(lexer);
11
12 Token *token = lexer->tokens;
13 LISP_OBJECT *lisp_obj = NULL;
14 lisp_obj = parser_parse_tokens(&token);
15
16 lexer_free(lexer);
17
18 return lisp_obj;
19}
20
21LISP_OBJECT *parser_parse_tokens(Token **token)
22{
23 LISP_OBJECT *lisp_obj = NULL;
24 switch((*token)->type)
25 {
26 case TOKEN_TYPE_SPECIAL:
27 lisp_obj = parser_make_list(token);
28 break;
29 case TOKEN_TYPE_NUMBER:
30 lisp_obj = parser_make_number(token);
31 break;
32 case TOKEN_TYPE_STRING:
33 lisp_obj = parser_make_string(token);
34 break;
35 case TOKEN_TYPE_SYMBOL:
36 lisp_obj = parser_make_symbol(token);
37 break;
38 case TOKEN_TYPE_TRUE:
39 lisp_obj = parser_make_true(token);
40 break;
41 case TOKEN_TYPE_FALSE:
42 lisp_obj = parser_make_false(token);
43 break;
44 case TOKEN_TYPE_NIL:
45 lisp_obj = parser_make_nil(token);
46 break;
47 case TOKEN_TYPE_ERROR:
48 lisp_obj = lisp_object_make_error((*token)->value);
49 *token = (*token)->next;
50 break;
51 default:
52 *token = (*token)->next;
53 lisp_obj = lisp_object_make_error("Something bad happenend!");
54 }
55 return lisp_obj;
56}
57
58LISP_OBJECT *parser_make_list(Token **token)
59{
60 LISP_OBJECT *lisp_list_obj = lisp_object_make_list();
61 char close_delimiter = ( *(*token)->value == '(' ) ? ')' : ']';
62 *token = (*token)->next;
63 int is_close_delimiter = 1;
64
65 while(*token)
66 {
67 if((*token)->type==TOKEN_TYPE_SPECIAL &&
68 *(*token)->value==close_delimiter)
69 {
70 is_close_delimiter=0;
71 *token=(*token)->next;
72 break;
73 }
74
75 lisp_object_list_push(lisp_list_obj,
76 (void *)parser_parse_tokens(token));
77
78 }
79
80
81 List *list = list_reverse(lisp_list_obj->value.list);
82 lisp_list_obj->value.list = list;
83
84 if(is_close_delimiter != 0)
85 {
86 LISP_OBJECT *err_msg = lisp_object_make_error("Unbalanced parenthesis!");
87 lisp_object_list_push(lisp_list_obj, err_msg);
88 }
89
90 return lisp_list_obj;
91}
92
93
94LISP_OBJECT *parser_make_number(Token **token)
95{
96 LISP_OBJECT *lisp_obj = NULL;
97 char *number_str = (*token)->value;
98 union
99 {
100 long long natural;
101 double floating;
102
103 } number;
104
105 if((*token)->is_decimal_point)
106 {
107 sscanf(number_str, "%lf", &number.floating);
108 lisp_obj = lisp_object_make_number_float(number.floating);
109 }
110 else
111 {
112 sscanf(number_str, "%lld", &number.natural);
113 lisp_obj = lisp_object_make_number_natural(number.natural);
114 }
115
116
117 *token=(*token)->next;
118 return lisp_obj;
119}
120
121LISP_OBJECT *parser_make_string(Token **token)
122{
123 char *str = (*token)->value;
124 LISP_OBJECT *lisp_obj = lisp_object_make_string(str);
125
126 *token=(*token)->next;
127 return lisp_obj;
128}
129
130LISP_OBJECT *parser_make_symbol(Token **token)
131{
132 char *str = (*token)->value;
133 LISP_OBJECT *lisp_obj = lisp_object_make_symbol(str);
134
135 *token=(*token)->next;
136 return lisp_obj;
137}
138
139LISP_OBJECT *parser_make_true(Token **token)
140{
141 LISP_OBJECT *lisp_obj = lisp_object_make_true();
142
143 *token=(*token)->next;
144 return lisp_obj;
145}
146
147LISP_OBJECT *parser_make_false(Token **token)
148{
149 LISP_OBJECT *lisp_obj = lisp_object_make_false();
150
151 *token=(*token)->next;
152 return lisp_obj;
153}
154
155
156LISP_OBJECT *parser_make_nil(Token **token)
157{
158 LISP_OBJECT *lisp_obj = lisp_object_make_nil();
159
160 *token=(*token)->next;
161 return lisp_obj;
162}
163
164int main()
165{
166 char *test = "(display (string-append \"4*3+2=\" (number->string (+ (* 4 3) 1))))";
167
168
169 LISP_OBJECT *obj = NULL;
170
171 obj = parser_parse_str(test);
172 lisp_object_print(obj, 0);
173 lisp_object_free(obj);
174}