aboutsummaryrefslogtreecommitdiff
path: root/lib/forlan.h
blob: 424cea8811cc2fcc2483d14ab83e973be5b72807 (plain)
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/* This file is part of Eclat.
   Copyright (C) 2012 Sergey Poznyakoff.
 
   Eclat is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.
 
   Eclat is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
 
   You should have received a copy of the GNU General Public License
   along with Eclat.  If not, see <http://www.gnu.org/licenses/>. */

#define FORLAN_DBG_LEX  3
#define FORLAN_DBG_GRAM 2
#define FORLAN_DBG_EVAL 1

typedef struct forlan_eval_env *forlan_eval_env_t;

extern int forlan_dbg;

void forlan_init();
void forlan_lex_from_buffer(const char *input, size_t length,
			    struct grecs_locus_point *pt);
void forlan_lex_from_file(FILE *fp, struct grecs_locus_point *pt);

void forlan_lex_end(void);
forlan_eval_env_t forlan_parse_buffer(const char *input, size_t length,
				      struct grecs_locus_point *pt);
forlan_eval_env_t forlan_parse_file(FILE *fp, struct grecs_locus_point *pt);

union forlan_node; /* Declared below */

enum forlan_type {
	forlan_type_null,  /* Unknown/unset type */
	forlan_type_comp,  /* A path component */  
	forlan_type_test,	/* Value test (f[X]) */ 
	forlan_type_func,	/* Function call */     
	forlan_type_cond,	/* Conditional */       
	forlan_type_stmt,	/* Statement */         
	forlan_type_lit,	/* Literal */           
	forlan_type_expr,       /* Boolean expression */
	forlan_type_last,       /* Return last evaluated grecs_node */
	forlan_type_asgn,       /* Variable assignment */
	forlan_type_var,        /* Variable reference */
	forlan_type_loop,       /* Loop */
	forlan_type_continue,   /* continue statement */
	forlan_type_break,      /* break statement */
	forlan_type_stop        /* stop statement */
};

/* A path component */
struct forlan_node_comp {
	enum forlan_type type;
	union forlan_node *root;
	int wildcards;
	int argc;
	char **argv;
	struct grecs_value **labelv;
};

/* Path test: .path.comp[value] */
struct forlan_node_test {
	enum forlan_type type;
	char *comp;
	char *value;
};

/* Function call */
struct forlan_node_func {
	enum forlan_type type;
	struct forlan_function *fp;
	struct grecs_list *args; /* Arguments are struct forlan_node * */
};

/* Conditional */
struct forlan_node_cond {
	enum forlan_type type;
	union forlan_node *expr;      /* Controlling expression */
	union forlan_node *iftrue;    /* Run this if expr yields true */
	union forlan_node *iffalse;   /* Run this if expr yields false */
};

/* Statement or statement list */
struct forlan_node_stmt {
	enum forlan_type type;
	union forlan_node *stmt;
	union forlan_node *next, *prev;
};

/* Literal string */
struct forlan_node_lit {
	enum forlan_type type;
	char *string;
};

/* Variable assignment */
struct forlan_node_asgn {
	enum forlan_type type;
	size_t idx;
	union forlan_node *node;
};

/* Variable reference */
struct forlan_node_var {
	enum forlan_type type;
	size_t idx;
};

/* Loop */
struct forlan_node_loop {
	enum forlan_type type;
	size_t idx;                 /* index of the controlling variable */
	union forlan_node *node;    /* controlling expression */
	union forlan_node *stmt;    /* statement */
};

/* Boolean opcodes */
enum forlan_opcode {
	forlan_opcode_node,  /* Evaluate node, set 'last' */
	forlan_opcode_and,   /* Boolean AND */
	forlan_opcode_or,    /* Boolean OR */
	forlan_opcode_not    /* Boolean NOT */
};

/* Boolean expression */
struct forlan_node_expr {           
	enum forlan_type type;
	enum forlan_opcode opcode;
	union forlan_node *arg[2];
};

/* Now get all this together */
union forlan_node {
	enum forlan_type type;
	struct forlan_node_comp comp; /* A path component */
	struct forlan_node_test test; /* Value test (f[X]) */
	struct forlan_node_func func; /* Function call */
	struct forlan_node_cond cond; /* Conditional */
	struct forlan_node_stmt stmt; /* Statement */
	struct forlan_node_lit  lit;  /* Literal */
	struct forlan_node_expr expr; /* Boolean expression */
	/* forlan_type_last needs no additional data */
	struct forlan_node_asgn asgn;
	struct forlan_node_var var;
	struct forlan_node_loop loop;
};

union forlan_node *forlan_node_create(enum forlan_type type);
void forlan_node_free(union forlan_node *);
struct grecs_list *forlan_stmt_list(void);
struct grecs_list *forlan_complist(void);
union forlan_node *forlan_stmt_from_list(struct grecs_list *list);

void forlan_dump_node(FILE *fp, union forlan_node *p, int *num, int lev);
void forlan_dump_tree(FILE *fp, forlan_eval_env_t env);

enum forlan_value_type {
	forlan_value_void,
	forlan_value_node,
	forlan_value_literal,
	forlan_value_boolean
};

struct forlan_value {
	enum forlan_value_type type;
	union {
		char *string;
		struct grecs_node *node;
		int num;
	} v;
};

struct forlan_variable {
	char *name;       /* Variable name */
	int idx;          /* Offset in the variable segment */ 
};

struct forlan_function {
	char *name;
	enum forlan_value_type rettype;
	char *argtypes;
	int minargs;
	int maxargs;
	void (*func)(forlan_eval_env_t, struct grecs_list *list);
};

struct forlan_function *forlan_find_function(const char *name);

void forlan_eval(struct forlan_eval_env *env, union forlan_node *p);
int forlan_run(forlan_eval_env_t env, struct grecs_node *tree);
forlan_eval_env_t forlan_create_environment(union forlan_node *parse_tree,
					    size_t varcount);
void forlan_free_environment(forlan_eval_env_t env);

Return to:

Send suggestions and report system problems to the System administrator.