forked from nsf/ancient
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parser.h
141 lines (120 loc) · 2.64 KB
/
parser.h
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
131
132
133
134
135
136
137
138
139
140
141
#pragma once
#include <llvm-c/Core.h>
#include "array.h"
#ifdef __cplusplus
extern "C" {
#endif
const char *tokname(int token);
struct token {
int type; // for types see grammar.h, it is generated by lemon
union {
double num;
struct {
char *beg;
int len;
} ident;
};
};
struct expr;
struct args {
DECLARE_ARRAY(struct expr*, v);
};
enum expr_type {
EXPR_NUM,
EXPR_BIN,
EXPR_IDENT,
EXPR_CALL,
};
struct expr {
enum expr_type type;
union {
double num;
struct {
int tok;
struct expr *lhs;
struct expr *rhs;
} bin;
struct {
char *beg;
int len;
} ident;
struct {
struct expr *ident;
struct args *args;
} call;
};
};
enum stmt_type {
STMT_EXPR,
STMT_ASSIGN,
STMT_BLOCK,
STMT_IFELSE,
STMT_FOR,
STMT_FUNC,
STMT_VAR,
STMT_RETURN,
};
struct stmts;
struct stmt {
enum stmt_type type;
union {
struct expr *expr;
struct {
struct expr *ident;
struct expr *rhs;
} assign;
struct stmts *block;
struct {
struct expr *cond;
struct stmt *block;
struct stmt *elseblock; // optional
} ifelse;
struct {
struct expr *cond;
struct stmt *block;
} forloop;
struct {
struct expr *ident;
struct args *args; // optional
// by convention if there are no block, this AST node
// means foreign function declaration
struct stmt *block;
} func;
struct {
struct expr *ident;
struct expr *init; // optional
} var;
struct expr *ret; // optional
};
};
struct stmts {
DECLARE_ARRAY(struct stmt*, v);
};
struct expr *new_num_expr(double num);
struct expr *new_binary_expr(int tok, struct expr *lhs, struct expr *rhs);
struct expr *new_ident_expr(char *beg, int len);
struct expr *new_call_expr(struct expr *ident, struct args *args);
struct stmt *new_expr_stmt(struct expr *e);
struct stmt *new_assign_stmt(struct expr *ident, struct expr *rhs);
struct stmt *new_block_stmt(struct stmts *block);
struct stmt *new_ifelse_stmt(struct expr *cond, struct stmt *b1, struct stmt *b2);
struct stmt *new_for_stmt(struct expr *cond, struct stmt *block);
struct stmt *new_func_stmt(struct expr *ident, struct args *args, struct stmt *b);
struct stmt *new_var_stmt(struct expr *ident, struct expr *init);
struct stmt *new_return_stmt(struct expr *e);
struct stmts *new_stmts(struct stmt *s);
struct args *new_args(struct expr *e);
void print_ast(struct stmts *top);
//------------------------------------------------------------------------------
struct parser_context {
void *lemon;
int line;
int lasttoken;
char *ts;
char *buf;
};
void print_syntax_error(struct parser_context *ctx, const char *msg, ...);
LLVMModuleRef codegen(struct stmts *ss);
#ifdef __cplusplus
} // extern "C"
#endif