git.haldean.org expel / cdf6cf5
move include/expel to include/ubik Haldean Brown 3 years ago
55 changed file(s) with 2223 addition(s) and 2223 deletion(s). Raw diff Collapse all Expand all
0 nobase_include_HEADERS = expel/bdagc.h expel/stream.h expel/timer.h expel/ast.h expel/const.h expel/assert.h expel/env.h expel/token.h expel/gen.h expel/natives.h expel/expel.h expel/dagc.h expel/uri.h expel/def-native.h expel/value.h expel/string.h expel/util.h expel/gc.h expel/compile.h expel/pointerset.h expel/schedule.h expel/parse.h expel/types.h expel/vector.h expel/resolve.h expel/closure.h expel/streamutil.h
0 nobase_include_HEADERS = ubik/bdagc.h ubik/stream.h ubik/timer.h ubik/ast.h ubik/const.h ubik/assert.h ubik/env.h ubik/token.h ubik/gen.h ubik/natives.h ubik/ubik.h ubik/dagc.h ubik/uri.h ubik/def-native.h ubik/value.h ubik/string.h ubik/util.h ubik/gc.h ubik/compile.h ubik/pointerset.h ubik/schedule.h ubik/parse.h ubik/types.h ubik/vector.h ubik/resolve.h ubik/closure.h ubik/streamutil.h
11
2 expel/const.h: ../res/const.txt
2 ubik/const.h: ../res/const.txt
33 $(AWK) -f ../res/compile-const.awk $< > $@
+0
-1
include/expel/.gitignore less more
0 const.h
+0
-39
include/expel/assert.h less more
0 /*
1 * assert.h: compile-conditional assertions
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef XL_RECKLESS
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "expel/util.h"
23
24 int
25 break_on_assert();
26
27 #define xl_assert(x) do { \
28 if (!(x)) { \
29 fprintf(stderr, \
30 "assertion %s:%d failed: %s\n", \
31 __FILE__, __LINE__, #x); \
32 break_on_assert(); \
33 xl_trace_print(); \
34 exit(EXIT_FAILURE); \
35 }} while (0)
36 #else
37 #define xl_assert(x)
38 #endif
+0
-244
include/expel/ast.h less more
0 /*
1 * ast.h: in-memory ast representation
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include "expel/expel.h"
21 #include "expel/vector.h"
22
23 #include <stdbool.h>
24
25 /* The maximum number of subexpressions any one expression can have. */
26 #define XL_MAX_SUBEXPRS 8
27
28 enum expr_type
29 {
30 EXPR_APPLY = 1,
31 EXPR_ATOM,
32 EXPR_LAMBDA,
33 EXPR_CONSTRUCTOR,
34 EXPR_CONDITIONAL,
35 EXPR_BLOCK
36 };
37
38 enum type_expr_type
39 {
40 TYPE_EXPR_APPLY = 1,
41 TYPE_EXPR_ATOM
42 };
43
44 enum atom_type
45 {
46 ATOM_INT = 1,
47 ATOM_NUM,
48 ATOM_NAME,
49 ATOM_QUALIFIED,
50 ATOM_TYPE_NAME,
51 ATOM_STRING
52 };
53
54 struct xl_ast;
55 struct xl_resolve_scope;
56 struct xl_resolve_name_loc;
57
58 enum type_type
59 {
60 TYPE_RECORD = 1,
61 };
62
63 struct xl_ast_loc
64 {
65 size_t line_start;
66 size_t line_end;
67 size_t col_start;
68 size_t col_end;
69 };
70
71 struct xl_ast_atom
72 {
73 union
74 {
75 char *str;
76 xl_word integer;
77 xl_float number;
78 struct
79 {
80 char *head;
81 char *tail;
82 } qualified;
83 };
84 enum atom_type atom_type;
85 struct xl_resolve_name_loc *name_loc;
86 struct xl_ast_loc loc;
87 };
88
89 struct xl_ast_arg_list
90 {
91 char *name;
92 struct xl_ast_arg_list *next;
93 struct xl_dagc_node *gen;
94 struct xl_ast_loc loc;
95 };
96
97 struct xl_ast_expr
98 {
99 union
100 {
101 struct xl_ast_atom *atom;
102 struct
103 {
104 struct xl_ast_expr *head;
105 struct xl_ast_expr *tail;
106 } apply;
107 struct
108 {
109 struct xl_ast_arg_list *args;
110 struct xl_ast_expr *body;
111 } lambda;
112 struct
113 {
114 char *type_name;
115 struct xl_ast *scope;
116 } constructor;
117 struct
118 {
119 struct xl_ast_expr *cond;
120 struct xl_ast_expr *implied;
121 struct xl_ast_expr *opposed;
122 } condition;
123 struct xl_ast *block;
124 };
125 enum expr_type expr_type;
126
127 struct xl_resolve_scope *scope;
128 struct xl_dagc_node *gen;
129 struct xl_ast_loc loc;
130 };
131
132 struct xl_ast_type_expr
133 {
134 union
135 {
136 char *name;
137 struct
138 {
139 struct xl_ast_type_expr *head;
140 struct xl_ast_type_expr *tail;
141 } apply;
142 };
143 enum type_expr_type type_expr_type;
144 struct xl_ast_loc loc;
145 };
146
147 struct xl_ast_binding
148 {
149 char *name;
150 struct xl_ast_expr *expr;
151 struct xl_ast_type_expr *type_expr;
152 struct xl_ast_loc loc;
153 };
154
155 struct xl_ast_import_list
156 {
157 char *name;
158 struct xl_ast_loc loc;
159 struct xl_ast_import_list *next;
160 };
161
162 struct xl_ast_member_list
163 {
164 char *name;
165 struct xl_ast_type_expr *type;
166 struct xl_ast_loc loc;
167 struct xl_ast_member_list *next;
168 };
169
170 struct xl_ast_type
171 {
172 union
173 {
174 struct xl_ast_member_list *members;
175 };
176 char *name;
177 enum type_type type;
178 struct xl_ast_loc loc;
179 };
180
181 struct xl_ast
182 {
183 /* members are struct xl_ast_binding pointers */
184 struct xl_vector bindings;
185 /* members are struct xl_ast_type pointers */
186 struct xl_vector types;
187 /* to run when ast is evaluted */
188 struct xl_ast_expr *immediate;
189 /* things this depends on existing */
190 struct xl_ast_import_list *imports;
191 /* everything in scope in this ast */
192 struct xl_resolve_scope *scope;
193 /* the location of this ast (useful because there are sub-ASTs whose
194 * location is actually interesting) */
195 struct xl_ast_loc loc;
196 };
197
198 /* Allocates a new AST. */
199 no_ignore xl_error
200 xl_ast_new(struct xl_ast **ast);
201
202 no_ignore xl_error
203 xl_ast_free(struct xl_ast *ast);
204
205 void
206 xl_ast_error_loc_free(struct xl_ast_loc *err_loc);
207
208 /* Prints the AST to stdout. */
209 no_ignore xl_error
210 xl_ast_print(struct xl_ast *ast);
211
212 no_ignore xl_error
213 xl_ast_bind(
214 struct xl_ast *ast,
215 struct xl_ast_binding *bind);
216
217 no_ignore xl_error
218 xl_ast_add_type(
219 struct xl_ast *ast,
220 struct xl_ast_type *type);
221
222 no_ignore xl_error
223 xl_ast_atom_new_qualified(
224 struct xl_ast_atom **atom,
225 char *name);
226
227 no_ignore xl_error
228 xl_ast_import(
229 struct xl_ast *ast,
230 struct xl_ast_import_list *import_list);
231
232 no_ignore xl_error
233 xl_ast_subexprs(
234 struct xl_ast **subast,
235 struct xl_ast_expr **subexprs,
236 size_t *n_subexprs,
237 struct xl_ast_expr *expr);
238
239 void
240 xl_ast_merge_loc(
241 struct xl_ast_loc *res,
242 struct xl_ast_loc *l1,
243 struct xl_ast_loc *l2);
+0
-46
include/expel/bdagc.h less more
0 /*
1 * bdagc.h: graph builder
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include "expel/dagc.h"
21 #include "expel/expel.h"
22
23 struct xl_graph_builder
24 {
25 struct xl_dagc_node **nodes;
26 size_t n_nodes;
27 size_t cap_nodes;
28
29 struct xl_dagc_node *result;
30 };
31
32 no_ignore xl_error
33 xl_bdagc_init(struct xl_graph_builder *b);
34
35 /* Adds a node to the graph. */
36 no_ignore xl_error
37 xl_bdagc_push_node(
38 struct xl_graph_builder *b,
39 struct xl_dagc_node *node);
40
41 /* Builds the graph. */
42 no_ignore xl_error
43 xl_bdagc_build(
44 struct xl_dagc **graph,
45 struct xl_graph_builder *b);
+0
-31
include/expel/closure.h less more
0 /*
1 * closure.h: closure transformation on ASTs
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include "expel/ast.h"
21 #include "expel/expel.h"
22 #include "expel/resolve.h"
23
24 /* Takes an AST and transforms closures into partially-applied functions. This
25 * transformation is explained in-depth in the "Code generation" portion of the
26 * architecture document. */
27 no_ignore xl_error
28 xl_reduce_closures(
29 struct xl_resolve_context *ctx,
30 struct xl_ast *ast);
+0
-53
include/expel/compile.h less more
0 /*
1 * compile.h: expel compilation
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include "expel/expel.h"
21 #include "expel/ast.h"
22
23
24 struct xl_compilation_env
25 {
26 char *scratch_dir;
27
28 char **include_dirs;
29 size_t n_include_dirs;
30 };
31
32 no_ignore xl_error
33 xl_compile_env_default(struct xl_compilation_env *cenv);
34
35 no_ignore xl_error
36 xl_compile_env_free(struct xl_compilation_env *cenv);
37
38 no_ignore xl_error
39 xl_compile(
40 struct xl_dagc ***graphs,
41 size_t *n_graphs,
42 char *source_name,
43 struct xl_stream *in_stream,
44 struct xl_compilation_env *cenv);
45
46 no_ignore xl_error
47 xl_compile_ast(
48 struct xl_dagc ***graphs,
49 size_t *n_graphs,
50 struct xl_ast *ast,
51 struct xl_compilation_env *cenv);
52
+0
-229
include/expel/dagc.h less more
0 /*
1 * dagc.h: directed acyclic graphs of computation
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef EXPEL_DAGC_H
20 #define EXPEL_DAGC_H
21
22 #include "expel/expel.h"
23
24 /* node is fully evaluated */
25 #define XL_DAGC_FLAG_COMPLETE 0x01
26 /* waiting on node's first dependency */
27 #define XL_DAGC_FLAG_WAIT_D1 0x02
28 /* waiting on node's second dependency */
29 #define XL_DAGC_FLAG_WAIT_D2 0x04
30 /* waiting on node's third dependency */
31 #define XL_DAGC_FLAG_WAIT_D3 0x08
32 /* waiting on evaluation */
33 #define XL_DAGC_FLAG_WAIT_EVAL 0x10
34 /* waiting on data to exist */
35 #define XL_DAGC_FLAG_WAIT_DATA 0x20
36 /* wait_d1 | wait_d2 | wait_d3 | wait_eval */
37 #define XL_DAGC_WAIT_MASK 0x2E
38
39 struct xl_dagc_adjacency
40 {
41 struct xl_dagc_node *child;
42 struct xl_dagc_node **parents;
43 size_t n_parents;
44 };
45
46 struct xl_dagc_apply
47 {
48 struct xl_dagc_node head;
49 /* Function to call */
50 struct xl_dagc_node *func;
51 /* Argument to apply to function */
52 struct xl_dagc_node *arg;
53 };
54
55 struct xl_dagc_const
56 {
57 struct xl_dagc_node head;
58 /* Type of constant */
59 struct xl_value *type;
60 /* Value of constant */
61 union xl_value_or_graph value;
62 };
63
64 struct xl_dagc_load
65 {
66 struct xl_dagc_node head;
67 /* Where to load from */
68 struct xl_uri *loc;
69 };
70
71 struct xl_dagc_store
72 {
73 struct xl_dagc_node head;
74 /* Location to store */
75 struct xl_uri *loc;
76 /* Value to store */
77 struct xl_dagc_node *value;
78 };
79
80 struct xl_dagc_input
81 {
82 struct xl_dagc_node head;
83 /* The argument that this corresponds to */
84 xl_word arg_num;
85 };
86
87 struct xl_dagc_ref
88 {
89 struct xl_dagc_node head;
90 /* The node to copy the value from */
91 struct xl_dagc_node *referrent;
92 };
93
94 /* The native_out node is a piece of magic that is enabled
95 * by the graph evaluator; if a graph has the native tag,
96 * then the evaluator evalutes the value of the graph using
97 * native code and populates the native node in the graph
98 * with the result. The native node is provided only as a
99 * thing for the caller to latch on to for the result. */
100 struct xl_dagc_native_out
101 {
102 struct xl_dagc_node head;
103 };
104
105 struct xl_dagc_cond
106 {
107 struct xl_dagc_node head;
108 /* The node that contains the condition */
109 struct xl_dagc_node *condition;
110 /* The node that contains the value that is used if
111 * the condition evaluates to true */
112 struct xl_dagc_node *if_true;
113 /* The node that contains the value that is used if
114 * the condition evaluates to false */
115 struct xl_dagc_node *if_false;
116 };
117
118 /* This syntax is terrible; it defines xl_native_evaluator_t as a
119 * function pointer that takes an env and a dagc and returns an
120 * xl_error. */
121 typedef xl_error (*xl_native_evaluator_t)(
122 struct xl_env *env, struct xl_dagc *graph);
123
124 struct xl_dagc_native
125 {
126 /* xl_dagc_native pointers are equivalent to an xl_dagc
127 * pointer */
128 struct xl_dagc graph;
129
130 /* The function used to evaluate this graph. */
131 xl_native_evaluator_t evaluator;
132 };
133
134 /* It can be anything you want it to be.
135 *
136 * It also happens to be the maximum size of all of the nodes,
137 * which has advantages for allocating big lists of nodes. */
138 union xl_dagc_any_node
139 {
140 struct xl_dagc_node node;
141 struct xl_dagc_apply as_apply;
142 struct xl_dagc_cond as_cond;
143 struct xl_dagc_const as_const;
144 struct xl_dagc_input as_input;
145 struct xl_dagc_load as_load;
146 struct xl_dagc_ref as_ref;
147 struct xl_dagc_store as_store;
148 };
149
150 /* Allocates a graph object in a memory region of the given size.
151 *
152 * If copy_from is not NULL, this also copies size bytes from
153 * copy_from into the graph before allocating all of the
154 * substructures of the graph. */
155 no_ignore xl_error
156 xl_dagc_alloc(
157 struct xl_dagc **graph,
158 size_t n_nodes,
159 size_t size,
160 void *copy_from);
161
162 /* Gets the dependencies of a node.
163 *
164 * For nodes with N dependencies, d1 through dN will be filled in
165 * and the result will be NULL. */
166 no_ignore xl_error
167 xl_dagc_get_deps(
168 struct xl_dagc_node **d1,
169 struct xl_dagc_node **d2,
170 struct xl_dagc_node **d3,
171 struct xl_dagc_node *n);
172
173 /* Modifies any references from the given node into the proto list
174 * of nodes to point at the corresponding node in the list of new
175 * nodes.
176 *
177 * This is useful when copying graphs or inserting nodes into
178 * graphs. */
179 no_ignore xl_error
180 xl_dagc_replace_node_refs(
181 struct xl_dagc_node *node,
182 struct xl_dagc_node **proto,
183 struct xl_dagc_node **new,
184 size_t n);
185
186 /* Retrieve the parents of the given node.
187 *
188 * Returns OK on success or a nonzero error code on error.
189 * It is imperative that callers do not modify the contents
190 * of the returned array.
191 *
192 * I know a triple-pointer seems ridiculous, but hear me
193 * out; we're returning a pointer to the caller, but we're
194 * returning multiple values so we want it as an outparam,
195 * which means we need to be passed a pointer to the
196 * pointer. The pointer we're returning is itself a pointer
197 * to a list of pointers. So we're asking you to pass us a
198 * pointer to a pointer of pointers. I'm sorry. */
199 no_ignore xl_error
200 xl_dagc_get_parents(
201 struct xl_dagc_node ***parents,
202 size_t *n_parents,
203 struct xl_dagc *graph,
204 struct xl_dagc_node *child);
205
206 /* Evaluates a node and marks it as complete. */
207 no_ignore xl_error
208 xl_dagc_node_eval(
209 struct xl_env *env,
210 struct xl_dagc_node *node);
211
212 /* Returns the size of the node structure in bytes. */
213 no_ignore xl_error
214 xl_dagc_node_sizeof(
215 size_t *size,
216 struct xl_dagc_node *node);
217
218 /* Performs a copy from proto to result.
219 *
220 * This is a deep copy of the nodes but not the values within
221 * them. This copies all information, including adjacency, and
222 * updates all internal references between nodes. */
223 no_ignore xl_error
224 xl_dagc_copy(
225 struct xl_dagc **result,
226 struct xl_dagc *proto);
227
228 #endif
+0
-145
include/expel/def-native.h less more
0 /*
1 * def-native.h: defines a native function
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef DEF_OP
20 #error "no DEF_OP specified, should be name of operation's _register method"
21 #endif
22
23 #ifndef DEF_OP_EVAL
24 #error "no DEF_OP_EVAL specified, should be name of graph evaluator"
25 #endif
26
27 #ifndef DEF_OP_URI
28 #error "no DEF_OP_URI specified, should be const char* of method name"
29 #endif
30
31 #ifndef DEF_ARG_TYPE
32 #error "no DEF_ARG_TYPE specified, should be name of type constructor for arguments"
33 #endif
34
35 #ifndef concat
36 #define concat(a, ...) concatr(a, __VA_ARGS__)
37 #define concatr(a, ...) a ## __VA_ARGS__
38 #endif
39
40 #define _op_name concat(_register_, DEF_OP)
41
42 #ifdef DEF_BINARY
43
44 no_ignore static xl_error
45 _op_name(struct xl_env *env)
46 {
47 xl_error err;
48
49 struct xl_dagc *ngraph;
50 struct xl_uri *uri;
51 struct xl_value *type;
52 union xl_value_or_graph ins;
53
54 ngraph = NULL;
55 err = _create_op(&ngraph, 2, DEF_OP_EVAL);
56 if (err != OK)
57 return err;
58
59 err = _native_uri(&uri, DEF_OP_URI);
60 if (err != OK)
61 return err;
62
63 ngraph->identity = uri;
64 err = xl_take(uri);
65 if (err != OK)
66 return err;
67
68 err = xl_value_new(&type);
69 if (err != OK)
70 return err;
71 /* TODO: set type here */
72
73 ins.graph = ngraph;
74 err = xl_env_set(env, uri, ins, type);
75 if (err != OK)
76 return err;
77
78 err = xl_release(type);
79 if (err != OK)
80 return err;
81 err = xl_release(ngraph);
82 if (err != OK)
83 return err;
84
85 return OK;
86 }
87
88 #elif defined(DEF_UNARY)
89
90 no_ignore static xl_error
91 _op_name(struct xl_env *env)
92 {
93 xl_error err;
94
95 struct xl_dagc *ngraph;
96 struct xl_uri *uri;
97 struct xl_value *type;
98 union xl_value_or_graph ins;
99
100 ngraph = NULL;
101 err = _create_op(&ngraph, 1, DEF_OP_EVAL);
102 if (err != OK)
103 return err;
104
105 err = _native_uri(&uri, DEF_OP_URI);
106 if (err != OK)
107 return err;
108
109 ngraph->identity = uri;
110 err = xl_take(uri);
111 if (err != OK)
112 return err;
113
114 err = xl_value_new(&type);
115 if (err != OK)
116 return err;
117 /* TODO: set type here */
118
119 ins.graph = ngraph;
120 err = xl_env_set(env, uri, ins, type);
121 if (err != OK)
122 return err;
123
124 err = xl_release(type);
125 if (err != OK)
126 return err;
127 err = xl_release(ngraph);
128 if (err != OK)
129 return err;
130
131 return OK;
132 }
133
134 #else
135 #error operation was not one of [DEF_BINARY, DEF_UNARY]
136 #endif
137
138 #undef DEF_OP
139 #undef DEF_OP_EVAL
140 #undef DEF_OP_URI
141 #undef DEF_BINARY
142 #undef DEF_UNARY
143 #undef DEF_ARG_TYPE
144 #undef _op_name
+0
-170
include/expel/env.h less more
0 /*
1 * env.h: expel environment definitions
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20
21 #include "expel/expel.h"
22 #include "expel/uri.h"
23
24 #include <stdbool.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27
28
29 typedef xl_error (*xl_env_cb)(
30 void *arg,
31 struct xl_env *env,
32 struct xl_uri *uri);
33
34 /* An association between a URI and a value */
35 struct xl_binding
36 {
37 struct xl_uri *uri;
38 union xl_value_or_graph value;
39 struct xl_value *type;
40 };
41
42 struct xl_env_watch
43 {
44 struct xl_uri *uri;
45 struct xl_env *target_env;
46 xl_env_cb cb;
47 void *arg;
48
49 /* Fired is set to true once the watcher has fired once; if this is
50 * true, it means means that the watcher is dead. */
51 bool fired;
52
53 /* The number of environments on which this watch was placed. */
54 xl_word refcount;
55 };
56
57 struct xl_env_watch_list
58 {
59 struct xl_env_watch *watch;
60
61 struct xl_env_watch_list *prev;
62 struct xl_env_watch_list *next;
63 };
64
65 /* A hash mapping from URI to value. */
66 struct xl_env
67 {
68 struct xl_binding *bindings;
69 size_t n;
70 size_t cap;
71 struct xl_env *parent;
72
73 struct xl_env_watch_list *watches;
74 };
75
76 /* Initializes a new environment struct. */
77 no_ignore xl_error
78 xl_env_init(struct xl_env *env);
79
80 /* Creates a child environment from the given env. */
81 no_ignore xl_error
82 xl_env_make_child(struct xl_env *child, struct xl_env *parent);
83
84 /* Returns the root environment.
85 *
86 * This environment is the parent of any environment that isn't
87 * explicitly created as a child. */
88 struct xl_env *
89 xl_env_get_root();
90
91 /* Frees memory associated with the environment struct.
92 *
93 * Returns OK if successful. If this method returns an error code,
94 * there is no guarantee that the environment is in a usable
95 * state. If OK is returned, the environment can still be used
96 * with xl_get and xl_set after calling xl_env_free; this is a
97 * clear operation that does not destroy the env. */
98 no_ignore xl_error
99 xl_env_free(struct xl_env *env);
100
101 /* Finds the value associated wth the given URI in the environment.
102 *
103 * If the value is found, OK is returned and the out pointer is
104 * set to the pointer to the assigned value. If the value is not
105 * found, ERR_ABSENT is returned and the out pointer is unchanged.
106 * */
107 no_ignore xl_error
108 xl_env_get(
109 union xl_value_or_graph *value,
110 struct xl_value **type,
111 struct xl_env *env,
112 struct xl_uri *uri);
113
114 /* Inserts the given value in at the given URI, overwriting an
115 * existing value if present.
116 *
117 * The URI is copied into the environment but the value is not;
118 * later modifications to the passed-in URI will not change the
119 * bindings but modifications to the value will modify the value
120 * stored in the environment. */
121 no_ignore xl_error
122 xl_env_overwrite(
123 struct xl_env *env,
124 struct xl_uri *uri,
125 union xl_value_or_graph value,
126 struct xl_value *type);
127
128 /* Inserts the given value in at the given URI if the URI is
129 * not already defined.
130 *
131 * If the URI is already bound, this will return ERR_PRESENT
132 * and the existing binding will not be modified.
133 *
134 * The URI is copied into the environment but the value is not;
135 * later modifications to the passed-in URI will not change the
136 * bindings but modifications to the value will modify the value
137 * stored in the environment. */
138 no_ignore xl_error
139 xl_env_set(
140 struct xl_env *env,
141 struct xl_uri *uri,
142 union xl_value_or_graph value,
143 struct xl_value *type);
144
145 /* Returns true if the provided URI is present in the environment. */
146 no_ignore xl_error
147 xl_env_present(
148 bool *is_present,
149 struct xl_env *env,
150 struct xl_uri *uri);
151
152 /* Calls the provided callback function once for every item. */
153 no_ignore xl_error
154 xl_env_iterate(
155 xl_env_cb callback,
156 struct xl_env *env,
157 void *callback_arg);
158
159 /* Calls the provided callback function when a URI is inserted or modified.
160 *
161 * Note that a watch is only ever triggered once; after being triggered it is
162 * removed from the list of watchers. */
163 no_ignore xl_error
164 xl_env_watch(
165 xl_env_cb callback,
166 struct xl_env *env,
167 struct xl_uri *uri,
168 void *callback_arg);
169
+0
-303
include/expel/expel.h less more
0 /*
1 * expel.h: minimal public API
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef EXPEL_EXPEL_H
20 #define EXPEL_EXPEL_H
21
22 #include <stddef.h>
23 #include <stdint.h>
24
25 #include "expel/const.h"
26
27 typedef uint16_t xl_tag;
28 typedef uint64_t xl_word;
29
30 #if __SIZEOF_DOUBLE__ == 8
31 typedef double xl_float;
32 #elif __SIZEOF_FLOAT__ == 8
33 typedef float xl_float;
34 #elif __SIZEOF_LONG_DOUBLE__ == 8
35 typedef long double xl_float;
36 #else
37 #error "word size and float size do not match"
38 #endif
39
40 #define TAG_TYPE_MASK 0xF000
41 #define TAG_VALUE 0x1000
42 #define TAG_GRAPH 0x2000
43 #define TAG_URI 0x3000
44
45 /* Tree tags */
46 #define TAG_LEFT_NODE 0x0010
47 #define TAG_LEFT_WORD 0x0020
48 #define TAG_LEFT_GRAPH 0x0040
49 #define TAG_RIGHT_NODE 0x0001
50 #define TAG_RIGHT_WORD 0x0002
51 #define TAG_RIGHT_GRAPH 0x0004
52
53 /* Graph tags */
54 #define TAG_GRAPH_NATIVE 0x0001
55 /* an unresolved graph is one that contains URIs that have not been resolved to
56 * a specific resource yet. */
57 #define TAG_GRAPH_UNRESOLVED 0x0002
58 /* a modinit graph represents a graph that should be run when bytecode is
59 * loaded. */
60 #define TAG_GRAPH_MODINIT 0x0004
61
62 /* The maximum Expel bytecode version that this library supports. */
63 #define CURRENT_ENCODING_VERSION 1
64
65 /* Private data structures referenced by public data structures. */
66 struct xl_alloc_page;
67 struct xl_env;
68 struct xl_stream;
69 struct xl_user;
70 struct xl_uri;
71 struct xl_dagc_adjacency;
72
73 struct xl_dagc;
74
75 /* Used to communicate errors through the stack. */
76 struct xl_error
77 {
78 xl_word error_code;
79 const char *tag;
80 const char *file;
81 const char *function;
82 uint32_t lineno;
83 };
84 typedef struct xl_error * xl_error;
85 #define OK ((xl_error) NULL)
86
87 #define no_ignore __attribute__((__warn_unused_result__))
88
89 union xl_atom
90 {
91 struct xl_value *t;
92 struct xl_dagc *g;
93 void *any;
94 xl_word w;
95 xl_float f;
96 };
97
98 /* The base type of all data in Expel; it's a cons cell. */
99 struct xl_value
100 {
101 /* A bitset of the TAG_ constants. One each of the
102 * TAG_LEFT_ and TAG_RIGHT_ bits must be set, along with
103 * the TAG_VALUE bit. */
104 xl_tag tag;
105
106 union xl_atom left;
107 union xl_atom right;
108
109 /* The page in which the value was allocated, used by the
110 * garbage collector. */
111 struct xl_alloc_page *alloc_page;
112 /* The number of references to the value, used by the
113 * garbage collector. Special hell awaits those who modify
114 * this value. */
115 uint64_t refcount;
116 };
117
118 struct xl_dagc;
119
120 union xl_value_or_graph
121 {
122 struct xl_value *tree;
123 struct xl_dagc *graph;
124 void *any;
125 xl_tag *tag;
126 };
127
128 struct xl_dagc_node
129 {
130 /* One of the DAGC_NODE constants */
131 xl_word node_type;
132 /* The unique identifier of this node */
133 xl_word id;
134 /* The evaluated type of the node, populated after the
135 * node is evaluated by xl_dagc_eval. */
136 struct xl_value *known_type;
137 /* The evaluated computation graph of the node, populated
138 * after the node is evaluated by xl_dagc_eval. The
139 * tag field tells you which member of the union to
140 * access. */
141 union xl_value_or_graph known;
142 /* Nonzero if we want the value of this node at the end of
143 * evaluation */
144 uint8_t is_terminal;
145 /* A bitsest of the XL_DAGC_FLAG constants */
146 uint8_t flags;
147 };
148
149 struct xl_dagc
150 {
151 /* Used to determine if a void* is a graph or a value.
152 * This is set by xl_dagc_init; users of the DAGC API
153 * should not touch it. */
154 xl_tag tag;
155
156 /* The identity of the graph, in URI form. */
157 struct xl_uri *identity;
158
159 /* The nodes participating in the graph. */
160 struct xl_dagc_node **nodes;
161 /* The number of nodes in the graph. */
162 size_t n;
163
164 /* Below this is only members that are populated by
165 * calling xl_dagc_init; callers should initialize nodes
166 * and n above and then call init to take care of
167 * everything else. */
168
169 /* Number of references held to this graph. */
170 uint64_t refcount;
171
172 /* A list of structs which encode backlinks from child to
173 * parent. */
174 struct xl_dagc_adjacency *adjacency;
175
176 /* The input nodes in the graph. */
177 struct xl_dagc_node **inputs;
178 size_t in_arity;
179
180 /* The terminal nodes in the graph. */
181 struct xl_dagc_node **terminals;
182 size_t out_arity;
183
184 /* The result node in the graph. */
185 struct xl_dagc_node *result;
186 };
187
188 /* Starts the expel runtime.
189 *
190 * Returns OK on success. */
191 no_ignore xl_error
192 xl_start();
193
194 /* Stops the expel runtime.
195 *
196 * Returns OK on success. */
197 no_ignore xl_error
198 xl_teardown();
199
200 /* Creates a new value.
201 *
202 * The returned value has a refcount of one; callers to xl_new do
203 * not need to take the result. This may result in an allocation
204 * but is not guaranteed to; xl_values are allocated in pages. */
205 no_ignore xl_error
206 xl_value_new(struct xl_value **v);
207
208 /* Takes a reference to the given tree or graph.
209 *
210 * Returns OK on success, or a nonzero error code on failure. */
211 no_ignore xl_error
212 xl_take(void *v);
213
214 /* Releases a reference to the given tree or graph.
215 *
216 * Returns OK on success, or a nonzero error code on failure. If
217 * passed a value, this may result in a free but is not guaranteed
218 * to; xl_values are garbage-collected periodically. If passed a
219 * graph and the releaser was the last owner of the graph, this
220 * will free the graph. */
221 no_ignore xl_error
222 xl_release(void *v);
223
224 /* Loads an expel bytecode blob from a stream.
225 *
226 * Returns OK on success, or a nonzero error word. */
227 no_ignore xl_error
228 xl_load(struct xl_dagc ***out, size_t *n_graphs, struct xl_stream *sp);
229
230 /* Saves a list of graphs and all accessible subgraphs to a stream.
231 *
232 * Returns OK on success, or a nonzero error word. */
233 no_ignore xl_error
234 xl_save(struct xl_stream *sp, struct xl_dagc **graphs, size_t n);
235
236 /* Loads a tree from a stream.
237 *
238 * Note that any contained graph references are initialized to the index
239 * of the graph in some other structure; if you're loading values with
240 * graph references you probably want to load the whole thing in one go
241 * with xl_load.
242 *
243 * The returned tree is not taken; it is up to the caller to take the
244 * tree. Returns OK on success, or a nonzero error word. */
245 no_ignore xl_error
246 xl_value_load(struct xl_value *out, struct xl_stream *sp);
247
248 /* Saves a tree to a stream.
249 *
250 * Note that this cannot save any values that contain any graph
251 * references; for that you'll need to serialize the entire structure
252 * with xl_save.
253 *
254 * Returns OK on success, or a nonzero error word. */
255 no_ignore xl_error
256 xl_value_save(struct xl_stream *sp, struct xl_value *in);
257
258 /* Allocates a graph object.
259 *
260 * All graph objects must be allocated on the heap; call into this
261 * method to allocate a graph of a given size. */
262 no_ignore xl_error
263 xl_dagc_new(struct xl_dagc **g, size_t n);
264
265 /* Initializes derived quantities on graphs.
266 *
267 * Callers should create a dagc struct, populate the nodes and the
268 * n fields, and then call this method to compute all derived
269 * quantities.
270 *
271 * This resets the refcount of the given graph to 1; initializers
272 * of graph structs do not need to take a reference to the graph
273 * after initialization. */
274 no_ignore xl_error
275 xl_dagc_init(struct xl_dagc *graph);
276
277 /* Creates a string representation of a node.
278 *
279 * Useful for debugging, but not much else. */
280 char *
281 xl_node_explain(struct xl_dagc_node *n);
282
283 /* Create an error object. */
284 xl_error
285 xl_error_new(
286 const xl_word code,
287 const char *tag,
288 const char *file,
289 const uint32_t lineno,
290 const char *function);
291
292 /* Creates a string representation of an error object. */
293 char *
294 xl_error_explain(xl_error err);
295
296 /* Raise an error with the current file and line populated. */
297 #define xl_raise(code, tag) \
298 xl_error_new((code), (tag), __FILE__, __LINE__, __FUNCTION__)
299
300 #define local(type) __attribute__((cleanup(xl_ ## type ## _free)))
301
302 #endif
+0
-58
include/expel/gc.h less more
0 /*
1 * gc.h: garbage collector introspection
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include "expel/expel.h"
20
21 struct xl_gc_info
22 {
23 #ifdef XL_GC_DEBUG
24 uint64_t n_val_allocs;
25 uint64_t n_val_frees;
26 uint64_t n_graph_allocs;
27 uint64_t n_graph_frees;
28 #endif
29 };
30
31 /* Initialize the garbage collector.
32 *
33 * This must be called before xl_new can be called. Calling this
34 * drops all existing GC state, and thus don't call it more than
35 * once unless you /really/ know what you're doing. */
36 void
37 xl_gc_start();
38
39 /* Teardown the garbage collector.
40 *
41 * Frees all memory known to the garbage collector. After calling
42 * this, ou must call xl_gc_start again if you want to use the
43 * runtime again. */
44 void
45 xl_gc_teardown();
46
47 /* Get garbage collector stats. */
48 void
49 xl_gc_get_stats(struct xl_gc_info *stats);
50
51 /* Free everything the garbage collector knows about.
52 *
53 * This will seriously fuck with the runtime, because pretty much
54 * every pointer becomes invalid. You have been warned. */
55 void
56 xl_gc_free_all();
57
+0
-58
include/expel/gen.h less more
0 /*
1 * gen.h: expel bytecode generation
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include "expel/expel.h"
21 #include "expel/ast.h"
22 #include "expel/uri.h"
23
24 struct xl_gen_requires
25 {
26 struct xl_uri *dependency;
27 struct xl_gen_requires *next;
28 };
29
30 enum xl_load_reason
31 {
32 LOAD_MAIN = 1,
33 LOAD_IMPORTED,
34 LOAD_BLOCK
35 };
36
37 /* Frees a requirement list. */
38 no_ignore xl_error
39 xl_gen_requires_free(struct xl_gen_requires *);
40
41 /* Compiles a single compilation unit down to a series of graphs.
42 *
43 * The graphs and n_graphs parameters are filled in with the result of
44 * compilation, as is the requires struct, which is created with a bunch of URIs
45 * that need to be satisfied for the compilation result to be valid. The ast
46 * parameter is the AST that's being compiled, the load_reason is the reason
47 * we're being compiled (some things behave differently if they're imported or
48 * they're the main event), and uri_source is the source prefix to put on all of
49 * the URIs for all the bindings in the AST. */
50 no_ignore xl_error
51 xl_compile_unit(
52 struct xl_dagc ***graphs,
53 size_t *n_graphs,
54 struct xl_gen_requires **requires,
55 struct xl_ast *ast,
56 enum xl_load_reason load_reason,
57 char *uri_source);
+0
-24
include/expel/natives.h less more
0 /*
1 * natives.h: built-in native methods
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include "expel/expel.h"
20
21 no_ignore xl_error
22 xl_natives_register(struct xl_env *env);
23
+0
-40
include/expel/parse.h less more
0 /*
1 * parse.h: expel language parser
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20
21 #include "expel/expel.h"
22 #include "expel/ast.h"
23 #include "expel/stream.h"
24 #include "expel/vector.h"
25
26 struct xl_parse_context
27 {
28 struct xl_ast *ast;
29
30 struct xl_ast_loc *err_loc;
31 char *err_msg;
32
33 /* we keep track of everything allocated during parsing so that we can
34 * clean up if the parse fails halfway through. */
35 struct xl_vector allocs;
36 };
37
38 no_ignore xl_error
39 xl_parse(struct xl_ast **ast, char *source_name, struct xl_stream *stream);
+0
-64
include/expel/pointerset.h less more
0 /*
1 * pointerset.h: ordered sets of pointers
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19
20 #include <stdbool.h>
21 #include <stdint.h>
22
23 #include "expel/expel.h"
24 #include "expel/vector.h"
25
26 /* Pointer sets represent sets of objects where the identity of an object is the
27 * address at which it is stored.
28 *
29 * To create a pointer set, it is sufficient to zero the struct entirely. This
30 * can be done with calloc or with a static '= {0}' initializer.
31 *
32 * Pointer sets are designed to be fast to perform a membership check, fast
33 * to iterate and indexable, while being slow to insert is okay. They
34 * have the property that every item in them is assigned an integer index, and
35 * the set of indeces in the set at any time is guaranteed to be sequential and
36 * rooted at zero. They are not multisets; a given pointer can only exist in the
37 * set once. They are intended for building sets of things that are indexed and
38 * then doing a number of queries to see what the index of a given item in the
39 * set is.
40 *
41 * With that in mind, pointer sets are stored in flat arrays in sorted order.
42 * The index of an item is naturally expressed as its position in the array.
43 * Membership searches for the item in the array using binary search and is thus
44 * O(n log n), as is finding the index of an object. Retrieving an item by index
45 * is O(1). Insertion is expensive, as it requires a full rebuild in general,
46 * and thus is O(n).
47 */
48
49 /* Adds item to the given pointer set. If added is not NULL, sets bool to true
50 * only if the item was not already present in the set. If the item is already
51 * present in the set, no mutation occurs on the pointer set and bool is set to
52 * false. */
53 no_ignore xl_error
54 xl_pointer_set_add(bool *added, struct xl_vector *, void *item);
55
56 /* Sets present to true or false if the item is or is not in the set. */
57 no_ignore xl_error
58 xl_pointer_set_present(bool *present, struct xl_vector *, void *item);
59
60 /* Sets index to the index of the given item. If the item does not exist in the
61 * set, raises ERR_ABSENT. */
62 no_ignore xl_error
63 xl_pointer_set_find(size_t *index, struct xl_vector *, void *item);
+0
-108
include/expel/resolve.h less more
0 /*
1 * resolve.h: name resolution at compile time
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include "expel/expel.h"
21 #include "expel/ast.h"
22 #include "expel/vector.h"
23
24 enum xl_resolve_type
25 {
26 /* if a name resolves locally, then the name should be accessed by using
27 * a ref node to the appropriate node for the name. */
28 RESOLVE_LOCAL = 1,
29 /* if a name resolves globally, then the name should be accessed by
30 * using a load node with the userdef scope. */
31 RESOLVE_GLOBAL,
32 /* if a name resolves through closure, then the ast needs to be
33 * transformed such that the name can be accessed as a local. */
34 RESOLVE_CLOSURE,
35 };
36
37 struct xl_resolve_name
38 {
39 char *name;
40 enum xl_resolve_type type;
41 struct xl_dagc_node *node;
42 };
43
44 struct xl_resolve_name_loc
45 {
46 enum xl_resolve_type type;
47 };
48
49 /* Scope boundaries are used to determine whether something is
50 * accessible in the current scope or not; it is useful for the closure
51 * transformation to know about things in enclosing but inaccessible
52 * scopes. If a scope has a BOUNDARY_BLOCK boundary type, then its
53 * parent is accessible (as it's just a scope object inside another
54 * scope). If a scope has a BOUNDARY_FUNCTION boundary type, its parent
55 * is not accessible as they exist in separate functions, and we need to
56 * close over its parents' values. If a scope has a BOUNDARY_GLOBAL boundary
57 * type, its members can be accessed using load nodes instead of ref nodes and
58 * thus they don't have to be closed over. */
59 enum xl_resolve_boundary_type
60 {
61 BOUNDARY_BLOCK = 1,
62 BOUNDARY_GLOBAL,
63 BOUNDARY_FUNCTION,
64 };
65
66 struct xl_resolve_scope
67 {
68 /* members of are struct xl_resolve_name pointers */
69 struct xl_vector names;
70
71 struct xl_resolve_scope *parent;
72 enum xl_resolve_boundary_type boundary;
73
74 /* This thing is complicated. There's a long explanation in closure.c
75 * about what it means. Go read that. */
76 bool needs_closure_appl;
77 };
78
79 enum xl_resolve_error_type
80 {
81 RESOLVE_ERR_NAME_NOT_FOUND = 1,
82 };
83
84 struct xl_resolve_error
85 {
86 enum xl_resolve_error_type err_type;
87 char *name;
88 struct xl_ast_loc loc;
89 };
90
91 struct xl_resolve_context
92 {
93 struct xl_resolve_scope *native_scope;
94 struct xl_vector scope_allocs;
95 struct xl_vector allocs;
96 struct xl_vector errors;
97 };
98
99 no_ignore xl_error
100 xl_resolve(
101 struct xl_ast *ast,
102 char *source_name,
103 struct xl_stream *stream,
104 struct xl_resolve_context *ctx);
105
106 void
107 xl_resolve_context_free(struct xl_resolve_context *ctx);
+0
-84
include/expel/schedule.h less more
0 /*
1 * schedule.h: definitions for the expel scheduler
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include "expel/expel.h"
20
21 struct xl_scheduler;
22 struct xl_exec_unit;
23
24 typedef xl_error (*xl_exec_notify_func)(
25 void *arg,
26 struct xl_scheduler *s,
27 struct xl_exec_unit *e);
28
29 struct xl_exec_notify
30 {
31 /* The function called when a unit of execution has completed */
32 xl_exec_notify_func notify;
33
34 /* The first argument provided to the function when called */
35 void *arg;
36 };
37
38 struct xl_exec_unit
39 {
40 /* The node to be evaluated */
41 struct xl_dagc_node *node;
42
43 /* The graph in which the node exists */
44 struct xl_dagc *graph;
45
46 /* The environment in which to execute the node */
47 struct xl_env *env;
48
49 /* The function to call once execution is complete */
50 struct xl_exec_notify *notify;
51
52 /* The next execution unit in the stack; callers to xl_schedule_push
53 * need not set this field, as the result will be overwritten anyawy. */
54 struct xl_exec_unit *next;
55 };
56
57 /* Creates a scheduler. */
58 no_ignore xl_error
59 xl_schedule_new(struct xl_scheduler **s);
60
61 /* Destroys a scheduler. */
62 no_ignore xl_error
63 xl_schedule_free(struct xl_scheduler *s);
64
65 /* Pushes a graph into the scheduler for execution. */
66 no_ignore xl_error
67 xl_schedule_push(
68 struct xl_scheduler *s,
69 struct xl_dagc *graph,
70 struct xl_env *env,
71 struct xl_exec_notify *notify);
72
73 /* Marks an execution unit complete. */
74 no_ignore xl_error
75 xl_schedule_complete(struct xl_scheduler *s, struct xl_exec_unit *e);
76
77 /* Runs all queued jobs on the scheduler. */
78 no_ignore xl_error
79 xl_schedule_run(struct xl_scheduler *s);
80
81 /* Dumps information about what's scheduled to stdout. */
82 no_ignore xl_error
83 xl_schedule_dump(struct xl_scheduler *s);
+0
-95
include/expel/stream.h less more
0 /*
1 * stream.h: stream interface
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef EXPEL_STREAM_H
20 #define EXPEL_STREAM_H
21
22 #include <stdio.h>
23
24 #include "expel/expel.h"
25
26 struct _xl_buf {
27 uint8_t *start;
28 uint8_t *read;
29 uint8_t *write;
30 uint8_t *end;
31 };
32
33 struct xl_stream {
34 union {
35 FILE *file;
36 struct _xl_buf *buffer;
37 };
38 xl_word stream_type;
39 };
40
41 /* Opens a stream for reading from the given file. */
42 no_ignore xl_error
43 xl_stream_rfile(struct xl_stream *sp, char *file);
44
45 /* Opens a stream for writing to the given file. */
46 no_ignore xl_error
47 xl_stream_wfile(struct xl_stream *sp, char *file);
48
49 /* Opens a stream for reading from the given file pointer. */
50 no_ignore xl_error
51 xl_stream_rfilep(struct xl_stream *sp, FILE *file);
52
53 /* Opens a stream for writing to the given file pointer. */
54 no_ignore xl_error
55 xl_stream_wfilep(struct xl_stream *sp, FILE *file);
56
57 /* Opens a stream backed by an in-memory buffer. */
58 no_ignore xl_error
59 xl_stream_buffer(struct xl_stream *sp);
60
61 /* Attempts to read the specified number of bytes from the stream, returning the
62 * number of bytes read. */
63 no_ignore size_t
64 xl_stream_read(void *dst, struct xl_stream *src, size_t len);
65
66 /* Attempts to write the specified number of bytes to the stream, returning the
67 * number of bytes written. */
68 no_ignore size_t
69 xl_stream_write(struct xl_stream *dst, void *src, size_t len);
70
71 /* Drops a number of bytes from the stream, returning the number of bytes
72 * dropped successfully. */
73 no_ignore size_t
74 xl_stream_drop(struct xl_stream *src, size_t len);
75
76 /* Gets a file pointer representing the contents of the stream.
77 *
78 * If the stream has been read from or written to, you should not make
79 * assumptions about the location of the read/write heads in this stream;
80 * instead, you should seek it to wherever you need the stream head to be. */
81 FILE *
82 xl_stream_fp(struct xl_stream *sp);
83
84 /* Resets a stream to the start.
85 *
86 * In some cases this may be equivalent to closing and reopening the stream. */
87 void
88 xl_stream_reset(struct xl_stream *sp);
89
90 /* Closes a stream. */
91 void
92 xl_stream_close(struct xl_stream *sp);
93
94 #endif
+0
-29
include/expel/streamutil.h less more
0 /*
1 * streamutil.h: generally useful stream helpers
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include "expel/stream.h"
20
21 /* Takes the line with index i from stream and copies it into the n-length
22 * buffer res. */
23 no_ignore xl_error
24 xl_streamutil_get_line(
25 char *res,
26 struct xl_stream *stream,
27 size_t i,
28 size_t n);
+0
-38
include/expel/string.h less more
0 /*
1 * string.h: extensions to the strings API provided by glibc
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include <strings.h>
20 #include "expel/expel.h"
21
22 /* Splits a NULL-terminated string into multiple smaller NULL-terminated
23 * strings, each separated by the delim character. */
24 no_ignore xl_error
25 xl_string_split(
26 char ***out,
27 size_t *n_out,
28 char *in,
29 size_t n_in,
30 char delim);
31
32 /* Joins two NULL-terminated path segments into a single path. */
33 no_ignore xl_error
34 xl_string_path_concat(
35 char **out,
36 char *first,
37 char *second);
+0
-31
include/expel/timer.h less more
0 /*
1 * timer.h: x-platform timing code
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include "expel/expel.h"
20
21 struct xl_timer;
22
23 no_ignore xl_error
24 xl_timer_new(struct xl_timer **t);
25
26 no_ignore xl_error
27 xl_timer_start(struct xl_timer *t);
28
29 no_ignore xl_error
30 xl_timer_elapsed(int64_t *microsec, struct xl_timer *t);
+0
-34
include/expel/token.h less more
0 /*
1 * token.h: expel language tokenizer
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include "expel/expel.h"
20 #include "expel/stream.h"
21
22 struct xl_token
23 {
24 int token_code;
25 char *text;
26 size_t text_len;
27 int line_no;
28 };
29
30 typedef xl_error (*xl_token_cb)(struct xl_token t);
31
32 no_ignore xl_error
33 xl_tokenize(xl_token_cb callback, struct xl_stream *stream);
+0
-74
include/expel/types.h less more
0 /*
1 * types.h: runtime type system for expel
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include <stdbool.h>
20
21 #include "expel/expel.h"
22
23 bool
24 xl_type_satisfied(
25 struct xl_value *constraint,
26 struct xl_value *type);
27
28 /* Creates a type object that is the result of applying a single argument to the
29 * given function type. */
30 no_ignore xl_error
31 xl_type_func_apply(
32 struct xl_value *result,
33 struct xl_value *func_type);
34
35 /* Given the value implementation of a function, returns the graph appropriate
36 * for an argument of the given type. */
37 no_ignore xl_error
38 xl_type_match_polyfunc(
39 struct xl_dagc **result,
40 struct xl_value *def,
41 struct xl_value *arg_type);
42
43 char *
44 xl_type_explain(struct xl_value *type);
45
46 /* Returns true if the values of the given type are "primitive words", meaning
47 * that their representation is entirely contained in the left value of their
48 * associated node. */
49 bool
50 xl_type_is_prim_word(struct xl_value *value);
51
52 no_ignore xl_error
53 xl_type_word(struct xl_value *value);
54
55 no_ignore xl_error
56 xl_type_string(struct xl_value *value);
57
58 no_ignore xl_error
59 xl_type_bool(struct xl_value *value);
60
61 no_ignore xl_error
62 xl_type_float(struct xl_value *value);
63
64 no_ignore xl_error
65 xl_type_tuple(
66 struct xl_value *product,
67 struct xl_value **field_types,
68 size_t n_field_types);
69
70 no_ignore xl_error
71 xl_type_builtin_from_name(
72 struct xl_value *value,
73 char *name);
+0
-91
include/expel/uri.h less more
0 /*
1 * uri.h: expel content identifiers
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include <stdbool.h>
21 #include <stdint.h>
22
23 #include "expel/expel.h"
24
25 /* Identifies values in the expel substrate */
26 struct xl_uri {
27 xl_tag tag;
28 xl_word hash;
29
30 char *name;
31 size_t name_len;
32 char *source;
33 size_t source_len;
34 xl_word version;
35 xl_word scope;
36
37 uint64_t refcount;
38
39 /* The value representation of the URI. Generated and cached by
40 * xl_uri_attach_value. */
41 struct xl_value *as_value;
42 };
43
44 /* Creates a URI for a resource of unknown scope. */
45 no_ignore xl_error
46 xl_uri_unknown(
47 struct xl_uri *uri,
48 char *name);
49
50 /* Creates a URI for a local resource. */
51 no_ignore xl_error
52 xl_uri_user(
53 struct xl_uri *uri,
54 char *name);
55
56 /* Creates a URI for a package-scoped resource. */
57 no_ignore xl_error
58 xl_uri_package(
59 struct xl_uri *uri,
60 char *package,
61 char *name);
62
63 /* Creates a URI for a global, runtime-provided resource. */
64 no_ignore xl_error
65 xl_uri_native(
66 struct xl_uri *uri,
67 char *name);
68
69 /* Creates a URI struct from a value-encoded URI. */
70 no_ignore xl_error
71 xl_uri_from_value(struct xl_uri *uri, struct xl_value *uri_val);
72
73 /* Returns true if the provided URIs are equal. */
74 bool
75 xl_uri_eq(struct xl_uri *u0, struct xl_uri *u1);
76
77 /* Generates a value representation for the URI and stores it in the URI's
78 * as_value field. If the field is already initialized, this function is a
79 * no-op. */
80 no_ignore xl_error
81 xl_uri_attach_value(struct xl_uri *uri);
82
83 /* Parses a URI string into a URI struct. Returns struct has no references;
84 * caller must take a reference to it. */
85 no_ignore xl_error
86 xl_uri_parse(struct xl_uri *uri, char *str);
87
88 /* Creates a string representation of a URI. */
89 char *
90 xl_uri_explain(struct xl_uri *uri);
+0
-51
include/expel/util.h less more
0 /*
1 * util.h: internal runtime utilities
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef EXPEL_UTIL_H__
20 #define EXPEL_UTIL_H__
21
22 #define unused(x) (void)(x)
23 #define likely(x) __builtin_expect((x), 1)
24 #define unlikely(x) __builtin_expect((x), 0)
25
26 #include "expel/expel.h"
27
28 size_t
29 size_max(size_t a, size_t b);
30
31 size_t
32 size_min(size_t a, size_t b);
33
34 /* Converts a word from host byte order to network byte order */
35 xl_word
36 htonw(xl_word);
37
38 /* Converts a word from network byte order to host byte order */
39 xl_word
40 ntohw(xl_word);
41
42 /* Prints a stack trace to stderr. */
43 void
44 xl_trace_print(void);
45
46 /* Converts a constant to its string value. */
47 char *
48 xl_word_explain(xl_word);
49
50 #endif
+0
-40
include/expel/value.h less more
0 /*
1 * value.h: encoding and decoding xl_values
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include <stdbool.h>
20
21 #include "expel/expel.h"
22
23 bool
24 xl_value_eq(struct xl_value *v1, struct xl_value *v2);
25
26 no_ignore xl_error
27 xl_value_print(struct xl_stream *out, struct xl_value *v);
28
29 no_ignore xl_error
30 xl_packed_read(uint8_t **dest, size_t *n, struct xl_value *src);
31
32 no_ignore xl_error
33 xl_string_read(char **dest, size_t *n, struct xl_value *src);
34
35 no_ignore xl_error
36 xl_value_as_bool(bool *res, struct xl_value *v);
37
38 no_ignore xl_error
39 xl_value_pack_string(struct xl_value *dest, char *src, size_t n);
+0
-41
include/expel/vector.h less more
0 /*
1 * vector.h: growable arrays
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include <stdint.h>
21 #include "expel/expel.h"
22
23 struct xl_vector
24 {
25 void **elems;
26 size_t n;
27 size_t cap;
28 };
29
30 /* Ensures that the vector has the capacity to hold at least the given size. */
31 no_ignore xl_error
32 xl_vector_ensure_size(struct xl_vector *, size_t size);
33
34 /* Appends an element onto the list. */
35 no_ignore xl_error
36 xl_vector_append(struct xl_vector *, void *elem);
37
38 /* Frees all memory associated with a vector. */
39 void
40 xl_vector_free(struct xl_vector *);
0 /*
1 * assert.h: compile-conditional assertions
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef XL_RECKLESS
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include "ubik/util.h"
23
24 int
25 break_on_assert();
26
27 #define xl_assert(x) do { \
28 if (!(x)) { \
29 fprintf(stderr, \
30 "assertion %s:%d failed: %s\n", \
31 __FILE__, __LINE__, #x); \
32 break_on_assert(); \
33 xl_trace_print(); \
34 exit(EXIT_FAILURE); \
35 }} while (0)
36 #else
37 #define xl_assert(x)
38 #endif
0 /*
1 * ast.h: in-memory ast representation
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include "ubik/expel.h"
21 #include "ubik/vector.h"
22
23 #include <stdbool.h>
24
25 /* The maximum number of subexpressions any one expression can have. */
26 #define XL_MAX_SUBEXPRS 8
27
28 enum expr_type
29 {
30 EXPR_APPLY = 1,
31 EXPR_ATOM,
32 EXPR_LAMBDA,
33 EXPR_CONSTRUCTOR,
34 EXPR_CONDITIONAL,
35 EXPR_BLOCK
36 };
37
38 enum type_expr_type
39 {
40 TYPE_EXPR_APPLY = 1,
41 TYPE_EXPR_ATOM
42 };
43
44 enum atom_type
45 {
46 ATOM_INT = 1,
47 ATOM_NUM,
48 ATOM_NAME,
49 ATOM_QUALIFIED,
50 ATOM_TYPE_NAME,
51 ATOM_STRING
52 };
53
54 struct xl_ast;
55 struct xl_resolve_scope;
56 struct xl_resolve_name_loc;
57
58 enum type_type
59 {
60 TYPE_RECORD = 1,
61 };
62
63 struct xl_ast_loc
64 {
65 size_t line_start;
66 size_t line_end;
67 size_t col_start;
68 size_t col_end;
69 };
70
71 struct xl_ast_atom
72 {
73 union
74 {
75 char *str;
76 xl_word integer;
77 xl_float number;
78 struct
79 {
80 char *head;
81 char *tail;
82 } qualified;
83 };
84 enum atom_type atom_type;
85 struct xl_resolve_name_loc *name_loc;
86 struct xl_ast_loc loc;
87 };
88
89 struct xl_ast_arg_list
90 {
91 char *name;
92 struct xl_ast_arg_list *next;
93 struct xl_dagc_node *gen;
94 struct xl_ast_loc loc;
95 };
96
97 struct xl_ast_expr
98 {
99 union
100 {
101 struct xl_ast_atom *atom;
102 struct
103 {
104 struct xl_ast_expr *head;
105 struct xl_ast_expr *tail;
106 } apply;
107 struct
108 {
109 struct xl_ast_arg_list *args;
110 struct xl_ast_expr *body;
111 } lambda;
112 struct
113 {
114 char *type_name;
115 struct xl_ast *scope;
116 } constructor;
117 struct
118 {
119 struct xl_ast_expr *cond;
120 struct xl_ast_expr *implied;
121 struct xl_ast_expr *opposed;
122 } condition;
123 struct xl_ast *block;
124 };
125 enum expr_type expr_type;
126
127 struct xl_resolve_scope *scope;
128 struct xl_dagc_node *gen;
129 struct xl_ast_loc loc;
130 };
131
132 struct xl_ast_type_expr
133 {
134 union
135 {
136 char *name;
137 struct
138 {
139 struct xl_ast_type_expr *head;
140 struct xl_ast_type_expr *tail;
141 } apply;
142 };
143 enum type_expr_type type_expr_type;
144 struct xl_ast_loc loc;
145 };
146
147 struct xl_ast_binding
148 {
149 char *name;
150 struct xl_ast_expr *expr;
151 struct xl_ast_type_expr *type_expr;
152 struct xl_ast_loc loc;
153 };
154
155 struct xl_ast_import_list
156 {
157 char *name;
158 struct xl_ast_loc loc;
159 struct xl_ast_import_list *next;
160 };
161
162 struct xl_ast_member_list
163 {
164 char *name;
165 struct xl_ast_type_expr *type;
166 struct xl_ast_loc loc;
167 struct xl_ast_member_list *next;
168 };
169
170 struct xl_ast_type
171 {
172 union
173 {
174 struct xl_ast_member_list *members;
175 };
176 char *name;
177 enum type_type type;
178 struct xl_ast_loc loc;
179 };
180
181 struct xl_ast
182 {
183 /* members are struct xl_ast_binding pointers */
184 struct xl_vector bindings;
185 /* members are struct xl_ast_type pointers */
186 struct xl_vector types;
187 /* to run when ast is evaluted */
188 struct xl_ast_expr *immediate;
189 /* things this depends on existing */
190 struct xl_ast_import_list *imports;
191 /* everything in scope in this ast */
192 struct xl_resolve_scope *scope;
193 /* the location of this ast (useful because there are sub-ASTs whose
194 * location is actually interesting) */
195 struct xl_ast_loc loc;
196 };
197
198 /* Allocates a new AST. */
199 no_ignore xl_error
200 xl_ast_new(struct xl_ast **ast);
201
202 no_ignore xl_error
203 xl_ast_free(struct xl_ast *ast);
204
205 void
206 xl_ast_error_loc_free(struct xl_ast_loc *err_loc);
207
208 /* Prints the AST to stdout. */
209 no_ignore xl_error
210 xl_ast_print(struct xl_ast *ast);
211
212 no_ignore xl_error
213 xl_ast_bind(
214 struct xl_ast *ast,
215 struct xl_ast_binding *bind);
216
217 no_ignore xl_error
218 xl_ast_add_type(
219 struct xl_ast *ast,
220 struct xl_ast_type *type);
221
222 no_ignore xl_error
223 xl_ast_atom_new_qualified(
224 struct xl_ast_atom **atom,
225 char *name);
226
227 no_ignore xl_error
228 xl_ast_import(
229 struct xl_ast *ast,
230 struct xl_ast_import_list *import_list);
231
232 no_ignore xl_error
233 xl_ast_subexprs(
234 struct xl_ast **subast,
235 struct xl_ast_expr **subexprs,
236 size_t *n_subexprs,
237 struct xl_ast_expr *expr);
238
239 void
240 xl_ast_merge_loc(
241 struct xl_ast_loc *res,
242 struct xl_ast_loc *l1,
243 struct xl_ast_loc *l2);
0 /*
1 * bdagc.h: graph builder
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include "ubik/dagc.h"
21 #include "ubik/expel.h"
22
23 struct xl_graph_builder
24 {
25 struct xl_dagc_node **nodes;
26 size_t n_nodes;
27 size_t cap_nodes;
28
29 struct xl_dagc_node *result;
30 };
31
32 no_ignore xl_error
33 xl_bdagc_init(struct xl_graph_builder *b);
34
35 /* Adds a node to the graph. */
36 no_ignore xl_error
37 xl_bdagc_push_node(
38 struct xl_graph_builder *b,
39 struct xl_dagc_node *node);
40
41 /* Builds the graph. */
42 no_ignore xl_error
43 xl_bdagc_build(
44 struct xl_dagc **graph,
45 struct xl_graph_builder *b);
0 /*
1 * closure.h: closure transformation on ASTs
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include "ubik/ast.h"
21 #include "ubik/expel.h"
22 #include "ubik/resolve.h"
23
24 /* Takes an AST and transforms closures into partially-applied functions. This
25 * transformation is explained in-depth in the "Code generation" portion of the
26 * architecture document. */
27 no_ignore xl_error
28 xl_reduce_closures(
29 struct xl_resolve_context *ctx,
30 struct xl_ast *ast);
0 /*
1 * compile.h: expel compilation
2 * Copyright (C) 2016, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20 #include "ubik/expel.h"
21 #include "ubik/ast.h"
22
23
24 struct xl_compilation_env
25 {
26 char *scratch_dir;
27
28 char **include_dirs;
29 size_t n_include_dirs;
30 };
31
32 no_ignore xl_error
33 xl_compile_env_default(struct xl_compilation_env *cenv);
34
35 no_ignore xl_error
36 xl_compile_env_free(struct xl_compilation_env *cenv);
37
38 no_ignore xl_error
39 xl_compile(
40 struct xl_dagc ***graphs,
41 size_t *n_graphs,
42 char *source_name,
43 struct xl_stream *in_stream,
44 struct xl_compilation_env *cenv);
45
46 no_ignore xl_error
47 xl_compile_ast(
48 struct xl_dagc ***graphs,
49 size_t *n_graphs,
50 struct xl_ast *ast,
51 struct xl_compilation_env *cenv);
52
0 /*
1 * dagc.h: directed acyclic graphs of computation
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef EXPEL_DAGC_H
20 #define EXPEL_DAGC_H
21
22 #include "ubik/expel.h"
23
24 /* node is fully evaluated */
25 #define XL_DAGC_FLAG_COMPLETE 0x01
26 /* waiting on node's first dependency */
27 #define XL_DAGC_FLAG_WAIT_D1 0x02
28 /* waiting on node's second dependency */
29 #define XL_DAGC_FLAG_WAIT_D2 0x04
30 /* waiting on node's third dependency */
31 #define XL_DAGC_FLAG_WAIT_D3 0x08
32 /* waiting on evaluation */
33 #define XL_DAGC_FLAG_WAIT_EVAL 0x10
34 /* waiting on data to exist */
35 #define XL_DAGC_FLAG_WAIT_DATA 0x20
36 /* wait_d1 | wait_d2 | wait_d3 | wait_eval */
37 #define XL_DAGC_WAIT_MASK 0x2E
38
39 struct xl_dagc_adjacency
40 {
41 struct xl_dagc_node *child;
42 struct xl_dagc_node **parents;
43 size_t n_parents;
44 };
45
46 struct xl_dagc_apply
47 {
48 struct xl_dagc_node head;
49 /* Function to call */
50 struct xl_dagc_node *func;
51 /* Argument to apply to function */
52 struct xl_dagc_node *arg;
53 };
54
55 struct xl_dagc_const
56 {
57 struct xl_dagc_node head;
58 /* Type of constant */
59 struct xl_value *type;
60 /* Value of constant */
61 union xl_value_or_graph value;
62 };
63
64 struct xl_dagc_load
65 {
66 struct xl_dagc_node head;
67 /* Where to load from */
68 struct xl_uri *loc;
69 };
70
71 struct xl_dagc_store
72 {
73 struct xl_dagc_node head;
74 /* Location to store */
75 struct xl_uri *loc;
76 /* Value to store */
77 struct xl_dagc_node *value;
78 };
79
80 struct xl_dagc_input
81 {
82 struct xl_dagc_node head;
83 /* The argument that this corresponds to */
84 xl_word arg_num;
85 };
86
87 struct xl_dagc_ref
88 {
89 struct xl_dagc_node head;
90 /* The node to copy the value from */
91 struct xl_dagc_node *referrent;
92 };
93
94 /* The native_out node is a piece of magic that is enabled
95 * by the graph evaluator; if a graph has the native tag,
96 * then the evaluator evalutes the value of the graph using
97 * native code and populates the native node in the graph
98 * with the result. The native node is provided only as a
99 * thing for the caller to latch on to for the result. */
100 struct xl_dagc_native_out
101 {
102 struct xl_dagc_node head;
103 };
104
105 struct xl_dagc_cond
106 {
107 struct xl_dagc_node head;
108 /* The node that contains the condition */
109 struct xl_dagc_node *condition;
110 /* The node that contains the value that is used if
111 * the condition evaluates to true */
112 struct xl_dagc_node *if_true;
113 /* The node that contains the value that is used if
114 * the condition evaluates to false */
115 struct xl_dagc_node *if_false;
116 };
117
118 /* This syntax is terrible; it defines xl_native_evaluator_t as a
119 * function pointer that takes an env and a dagc and returns an
120 * xl_error. */
121 typedef xl_error (*xl_native_evaluator_t)(
122 struct xl_env *env, struct xl_dagc *graph);
123
124 struct xl_dagc_native
125 {
126 /* xl_dagc_native pointers are equivalent to an xl_dagc
127 * pointer */
128 struct xl_dagc graph;
129
130 /* The function used to evaluate this graph. */
131 xl_native_evaluator_t evaluator;
132 };
133
134 /* It can be anything you want it to be.
135 *
136 * It also happens to be the maximum size of all of the nodes,
137 * which has advantages for allocating big lists of nodes. */
138 union xl_dagc_any_node
139 {
140 struct xl_dagc_node node;
141 struct xl_dagc_apply as_apply;
142 struct xl_dagc_cond as_cond;
143 struct xl_dagc_const as_const;
144 struct xl_dagc_input as_input;
145 struct xl_dagc_load as_load;
146 struct xl_dagc_ref as_ref;
147 struct xl_dagc_store as_store;
148 };
149
150 /* Allocates a graph object in a memory region of the given size.
151 *
152 * If copy_from is not NULL, this also copies size bytes from
153 * copy_from into the graph before allocating all of the
154 * substructures of the graph. */
155 no_ignore xl_error
156 xl_dagc_alloc(
157 struct xl_dagc **graph,
158 size_t n_nodes,
159 size_t size,
160 void *copy_from);
161
162 /* Gets the dependencies of a node.
163 *
164 * For nodes with N dependencies, d1 through dN will be filled in
165 * and the result will be NULL. */
166 no_ignore xl_error
167 xl_dagc_get_deps(
168 struct xl_dagc_node **d1,
169 struct xl_dagc_node **d2,
170 struct xl_dagc_node **d3,
171 struct xl_dagc_node *n);
172
173 /* Modifies any references from the given node into the proto list
174 * of nodes to point at the corresponding node in the list of new
175 * nodes.
176 *
177 * This is useful when copying graphs or inserting nodes into
178 * graphs. */
179 no_ignore xl_error
180 xl_dagc_replace_node_refs(
181 struct xl_dagc_node *node,
182 struct xl_dagc_node **proto,
183 struct xl_dagc_node **new,
184 size_t n);
185
186 /* Retrieve the parents of the given node.
187 *
188 * Returns OK on success or a nonzero error code on error.
189 * It is imperative that callers do not modify the contents
190 * of the returned array.
191 *
192 * I know a triple-pointer seems ridiculous, but hear me
193 * out; we're returning a pointer to the caller, but we're
194 * returning multiple values so we want it as an outparam,
195 * which means we need to be passed a pointer to the
196 * pointer. The pointer we're returning is itself a pointer
197 * to a list of pointers. So we're asking you to pass us a
198 * pointer to a pointer of pointers. I'm sorry. */
199 no_ignore xl_error
200 xl_dagc_get_parents(
201 struct xl_dagc_node ***parents,
202 size_t *n_parents,
203 struct xl_dagc *graph,
204 struct xl_dagc_node *child);
205
206 /* Evaluates a node and marks it as complete. */
207 no_ignore xl_error
208 xl_dagc_node_eval(
209 struct xl_env *env,
210 struct xl_dagc_node *node);
211
212 /* Returns the size of the node structure in bytes. */
213 no_ignore xl_error
214 xl_dagc_node_sizeof(
215 size_t *size,
216 struct xl_dagc_node *node);
217
218 /* Performs a copy from proto to result.
219 *
220 * This is a deep copy of the nodes but not the values within
221 * them. This copies all information, including adjacency, and
222 * updates all internal references between nodes. */
223 no_ignore xl_error
224 xl_dagc_copy(
225 struct xl_dagc **result,
226 struct xl_dagc *proto);
227
228 #endif
0 /*
1 * def-native.h: defines a native function
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef DEF_OP
20 #error "no DEF_OP specified, should be name of operation's _register method"
21 #endif
22
23 #ifndef DEF_OP_EVAL
24 #error "no DEF_OP_EVAL specified, should be name of graph evaluator"
25 #endif
26
27 #ifndef DEF_OP_URI
28 #error "no DEF_OP_URI specified, should be const char* of method name"
29 #endif
30
31 #ifndef DEF_ARG_TYPE
32 #error "no DEF_ARG_TYPE specified, should be name of type constructor for arguments"
33 #endif
34
35 #ifndef concat
36 #define concat(a, ...) concatr(a, __VA_ARGS__)
37 #define concatr(a, ...) a ## __VA_ARGS__
38 #endif
39
40 #define _op_name concat(_register_, DEF_OP)
41
42 #ifdef DEF_BINARY
43
44 no_ignore static xl_error
45 _op_name(struct xl_env *env)
46 {
47 xl_error err;
48
49 struct xl_dagc *ngraph;
50 struct xl_uri *uri;
51 struct xl_value *type;
52 union xl_value_or_graph ins;
53
54 ngraph = NULL;
55 err = _create_op(&ngraph, 2, DEF_OP_EVAL);
56 if (err != OK)
57 return err;
58
59 err = _native_uri(&uri, DEF_OP_URI);
60 if (err != OK)
61 return err;
62
63 ngraph->identity = uri;
64 err = xl_take(uri);
65 if (err != OK)
66 return err;
67
68 err = xl_value_new(&type);
69 if (err != OK)
70 return err;
71 /* TODO: set type here */
72
73 ins.graph = ngraph;
74 err = xl_env_set(env, uri, ins, type);
75 if (err != OK)
76 return err;
77
78 err = xl_release(type);
79 if (err != OK)
80 return err;
81 err = xl_release(ngraph);
82 if (err != OK)
83 return err;
84
85 return OK;
86 }
87
88 #elif defined(DEF_UNARY)
89
90 no_ignore static xl_error
91 _op_name(struct xl_env *env)
92 {
93 xl_error err;
94
95 struct xl_dagc *ngraph;
96 struct xl_uri *uri;
97 struct xl_value *type;
98 union xl_value_or_graph ins;
99
100 ngraph = NULL;
101 err = _create_op(&ngraph, 1, DEF_OP_EVAL);
102 if (err != OK)
103 return err;
104
105 err = _native_uri(&uri, DEF_OP_URI);
106 if (err != OK)
107 return err;
108
109 ngraph->identity = uri;
110 err = xl_take(uri);
111 if (err != OK)
112 return err;
113
114 err = xl_value_new(&type);
115 if (err != OK)
116 return err;
117 /* TODO: set type here */
118
119 ins.graph = ngraph;
120 err = xl_env_set(env, uri, ins, type);
121 if (err != OK)
122 return err;
123
124 err = xl_release(type);
125 if (err != OK)
126 return err;
127 err = xl_release(ngraph);
128 if (err != OK)
129 return err;
130
131 return OK;
132 }
133
134 #else
135 #error operation was not one of [DEF_BINARY, DEF_UNARY]
136 #endif
137
138 #undef DEF_OP
139 #undef DEF_OP_EVAL
140 #undef DEF_OP_URI
141 #undef DEF_BINARY
142 #undef DEF_UNARY
143 #undef DEF_ARG_TYPE
144 #undef _op_name
0 /*
1 * env.h: expel environment definitions
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #pragma once
20
21 #include "ubik/expel.h"
22 #include "ubik/uri.h"
23
24 #include <stdbool.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27
28
29 typedef xl_error (*xl_env_cb)(
30 void *arg,
31 struct xl_env *env,
32 struct xl_uri *uri);
33
34 /* An association between a URI and a value */
35 struct xl_binding
36 {
37 struct xl_uri *uri;
38 union xl_value_or_graph value;
39 struct xl_value *type;
40 };
41
42 struct xl_env_watch
43 {
44 struct xl_uri *uri;
45 struct xl_env *target_env;
46 xl_env_cb cb;
47 void *arg;
48
49 /* Fired is set to true once the watcher has fired once; if this is
50 * true, it means means that the watcher is dead. */
51 bool fired;
52
53 /* The number of environments on which this watch was placed. */
54 xl_word refcount;
55 };
56
57 struct xl_env_watch_list
58 {
59 struct xl_env_watch *watch;
60
61 struct xl_env_watch_list *prev;
62 struct xl_env_watch_list *next;
63 };
64
65 /* A hash mapping from URI to value. */
66 struct xl_env
67 {
68 struct xl_binding *bindings;
69 size_t n;
70 size_t cap;
71 struct xl_env *parent;
72
73 struct xl_env_watch_list *watches;
74 };
75
76 /* Initializes a new environment struct. */
77 no_ignore xl_error
78 xl_env_init(struct xl_env *env);
79
80 /* Creates a child environment from the given env. */
81 no_ignore xl_error
82 xl_env_make_child(struct xl_env *child, struct xl_env *parent);
83
84 /* Returns the root environment.
85 *
86 * This environment is the parent of any environment that isn't
87 * explicitly created as a child. */
88 struct xl_env *
89 xl_env_get_root();
90
91 /* Frees memory associated with the environment struct.
92 *
93 * Returns OK if successful. If this method returns an error code,
94 * there is no guarantee that the environment is in a usable
95 * state. If OK is returned, the environment can still be used
96 * with xl_get and xl_set after calling xl_env_free; this is a
97 * clear operation that does not destroy the env. */
98 no_ignore xl_error
99 xl_env_free(struct xl_env *env);
100
101 /* Finds the value associated wth the given URI in the environment.
102 *
103 * If the value is found, OK is returned and the out pointer is
104 * set to the pointer to the assigned value. If the value is not
105 * found, ERR_ABSENT is returned and the out pointer is unchanged.
106 * */
107 no_ignore xl_error
108 xl_env_get(
109 union xl_value_or_graph *value,
110 struct xl_value **type,
111 struct xl_env *env,
112 struct xl_uri *uri);
113
114 /* Inserts the given value in at the given URI, overwriting an
115 * existing value if present.
116 *
117 * The URI is copied into the environment but the value is not;
118 * later modifications to the passed-in URI will not change the
119 * bindings but modifications to the value will modify the value
120 * stored in the environment. */
121 no_ignore xl_error
122 xl_env_overwrite(
123 struct xl_env *env,
124 struct xl_uri *uri,
125 union xl_value_or_graph value,
126 struct xl_value *type);
127
128 /* Inserts the given value in at the given URI if the URI is
129 * not already defined.
130 *
131 * If the URI is already bound, this will return ERR_PRESENT
132 * and the existing binding will not be modified.
133 *
134 * The URI is copied into the environment but the value is not;
135 * later modifications to the passed-in URI will not change the
136 * bindings but modifications to the value will modify the value
137 * stored in the environment. */
138 no_ignore xl_error
139 xl_env_set(
140 struct xl_env *env,
141 struct xl_uri *uri,
142 union xl_value_or_graph value,
143 struct xl_value *type);
144
145 /* Returns true if the provided URI is present in the environment. */
146 no_ignore xl_error
147 xl_env_present(
148 bool *is_present,
149 struct xl_env *env,
150 struct xl_uri *uri);
151
152 /* Calls the provided callback function once for every item. */
153 no_ignore xl_error
154 xl_env_iterate(
155 xl_env_cb callback,
156 struct xl_env *env,
157 void *callback_arg);
158
159 /* Calls the provided callback function when a URI is inserted or modified.
160 *
161 * Note that a watch is only ever triggered once; after being triggered it is
162 * removed from the list of watchers. */
163 no_ignore xl_error
164 xl_env_watch(
165 xl_env_cb callback,
166 struct xl_env *env,
167 struct xl_uri *uri,
168 void *callback_arg);
169
0 /*
1 * expel.h: minimal public API
2 * Copyright (C) 2015, Haldean Brown
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifndef EXPEL_EXPEL_H
20 #define EXPEL_EXPEL_H
21
22 #include <stddef.h>
23 #include <stdint.h>
24
25 #include "ubik/const.h"
26
27 typedef uint16_t xl_tag;
28 typedef uint64_t xl_word;
29
30 #if __SIZEOF_DOUBLE__ == 8
31 typedef double xl_float;
32 #elif __SIZEOF_FLOAT__ == 8
33 typedef float xl_float;
34 #elif __SIZEOF_LONG_DOUBLE__ == 8
35 typedef long double xl_float;
36 #else
37 #error "word size and float size do not match"
38 #endif
39
40 #define TAG_TYPE_MASK 0xF000
41 #define TAG_VALUE 0x1000
42 #define TAG_GRAPH 0x2000
43 #define TAG_URI 0x3000
44
45 /* Tree tags */
46 #define TAG_LEFT_NODE 0x0010
47 #define TAG_LEFT_WORD 0x0020
48 #define TAG_LEFT_GRAPH 0x0040
49 #define TAG_RIGHT_NODE 0x0001
50 #define TAG_RIGHT_WORD 0x0002
51 #define TAG_RIGHT_GRAPH 0x0004
52
53 /* Graph tags */
54 #define TAG_GRAPH_NATIVE 0x0001
55 /* an unresolved graph is one that contains URIs that have not been resolved to
56 * a specific resource yet. */
57 #define TAG_GRAPH_UNRESOLVED 0x0002
58 /* a modinit graph represents a graph that should be run when bytecode is
59 * loaded. */
60 #define TAG_GRAPH_MODINIT 0x0004
61
62 /* The maximum Expel bytecode version that this library supports. */
63 #define CURRENT_ENCODING_VERSION 1
64
65 /* Private data structures referenced by public data structures. */
66 struct xl_alloc_page;
67 struct xl_env;
68 struct xl_stream;
69 struct xl_user;
70 struct xl_uri;
71 struct xl_dagc_adjacency;
72
73 struct xl_dagc;
74
75 /* Used to communicate errors through the stack. */
76 struct xl_error
77 {
78 xl_word error_code;
79 const char *tag;
80 const char *file;
81 const char *function;
82 uint32_t lineno;
83 };
84 typedef struct xl_error * xl_error;
85 #define OK ((xl_error) NULL)
86
87 #define no_ignore __attribute__((__warn_unused_result__))
88
89 union xl_atom
90 {
91 struct xl_value *t;
92 struct xl_dagc *g;
93 void *any;
94 xl_word w;
95 xl_float f;
96 };
97
98 /* The base type of all data in Expel; it's a cons cell. */
99 struct xl_value
100 {
101 /* A bitset of the TAG_ constants. One each of the
102 * TAG_LEFT_ and TAG_RIGHT_ bits must be set, along with
103 * the TAG_VALUE bit. */
104 xl_tag tag;
105
106 union xl_atom left;
107 union xl_atom right;
108
109 /* The page in which the value was allocated, used by the
110 * garbage collector. */
111 struct xl_alloc_page *alloc_page;
112 /* The number of references to the value, used by the
113 * garbage collector. Special hell awaits those who modify
114 * this value. */
115 uint64_t refcount;
116 };
117
118 struct xl_dagc;
119
120 union xl_value_or_graph
121 {
122 struct xl_value *tree;
123 struct xl_dagc *graph;
124 void *any;
125 xl_tag *tag;
126 };
127
128 struct xl_dagc_node
129 {
130 /* One of the DAGC_NODE constants */
131 xl_word node_type;
132 /* The unique identifier of this node */
133 xl_word id;
134 /* The evaluated type of the node, populated after the
135 * node is evaluated by xl_dagc_eval. */
136 struct xl_value *known_type;
137 /* The evaluated computation graph of the node, populated
138 * after the node is evaluated by xl_dagc_eval. The
139 * tag field tells you which member of the union to
140 * access. */
141 union xl_value_or_graph known;
142 /* Nonzero if we want the value of this node at the end of
143 * evaluation */
144 uint8_t is_terminal;
145 /* A bitsest of the XL_DAGC_FLAG constants */
146 uint8_t flags;
147 };
148
149 struct xl_dagc
150 {
151 /* Used to determine if a void* is a graph or a value.
152 * This is set by xl_dagc_init; users of the DAGC API
153 * should not touch it. */
154 xl_tag tag;
155
156 /* The identity of the graph, in URI form. */
157 struct xl_uri *identity;
158
159 /* The nodes participating in the graph. */
160 struct xl_dagc_node **nodes;
161 /* The number of nodes in the graph. */
162 size_t n;
163
164 /* Below this is only members that are populated by
165 * calling xl_dagc_init; callers should initialize nodes
166 * and n above and then call init to take care of
167 * everything else. */
168
169 /* Number of references held to this graph. */
170 uint64_t refcount;
171
172 /* A list of structs which encode backlinks from child to
173 * parent. */
174 struct xl_dagc_adjacency *adjacency;
175
176 /* The input nodes in the graph. */
177 struct xl_dagc_node **inputs;
178 size_t in_arity;
179
180 /* The terminal nodes in the graph. */
181 struct xl_dagc_node **terminals;
182 size_t out_arity;
183
184 /* The result node in the graph. */
185 struct xl_dagc_node *result;
186 };
187
188 /* Starts the expel runtime.
189 *
190 * Returns OK on success. */
191 no_ignore xl_error
192 xl_start();
193
194 /* Stops the expel runtime.
195 *
196 * Returns OK on success. */
197 no_ignore xl_error
198 xl_teardown();
199
200 /* Creates a new value.
201 *
202 * The returned value has a refcount of one; callers to xl_new do
203 * not need to take the result. This may result in an allocation
204 * but is not guaranteed to; xl_values are allocated in pages. */
205 no_ignore xl_error
206 xl_value_new(struct xl_value **v);
207
208 /* Takes a reference to the given tree or graph.
209 *
210 * Returns OK on success, or a nonzero error code on failure. */
211 no_ignore xl_error
212 xl_take(void *v);
213
214 /* Releases a reference to the given tree or graph.
215 *
216 * Returns OK on success, or a nonzero error code on failure. If
217 * passed a value, this may result in a free but is not guaranteed
218 * to; xl_values are garbage-collected periodically. If passed a
219 * graph and the releaser was the last owner of the graph, this
220 * will free the graph. */
221 no_ignore xl_error
222 xl_release(void *v);
223
224 /* Loads an expel bytecode blob from a stream.
225 *
226 * Returns OK on success, or a nonzero error word. */
227 no_ignore xl_error
228 xl_load(struct xl_dagc ***out, size_t *n_graphs, struct xl_stream *sp);
229
230 /* Saves a list of graphs and all accessible subgraphs to a stream.
231 *
232 * Returns OK on success, or a nonzero error word. */
233 no_ignore xl_error
234 xl_save(struct xl_stream *sp, struct xl_dagc **graphs, size_t n);
235
236 /* Loads a tree from a stream.
237 *
238 * Note that any contained graph references are initialized to the index
239 * of the graph in some other structure; if you're loading values with
240 * graph references you probably want to load the whole thing in one go
241 * with xl_load.
242 *
243 * The returned tree is not taken; it is up to the caller to take the
244 * tree. Returns OK on success, or a nonzero error word. */
245 no_ignore xl_error
246 xl_value_load(struct xl_value *out, struct xl_stream *sp);
247
248 /* Saves a tree to a stream.
249 *
250 * Note that this cannot save any values that contain any graph
251 * references; for that you'll need to serialize the entire structure
252 * with xl_save.
253 *
254 * Returns OK on success, or a nonzero error word. */
255 no_ignore xl_error
256 xl_value_save(struct xl_stream *sp, struct xl_value *in);
257
258 /* Allocates a graph object.
259 *
260 * All graph objects must be allocated on the heap; call into this
261 * method to allocate a graph of a given size. */
262 no_ignore xl_error
263 xl_dagc_new(struct xl_dagc **g, size_t n);
264
265 /* Initializes derived quantities on graphs.
266 *
267 * Callers should create a dagc struct, populate the nodes and the
268 * n fields, and then call this method to compute all derived
269 * quantities.
270 *
271 * This resets the refcount of the given graph to 1; initializers
272 * of graph structs do not need to take a reference to the graph
273 * after initialization. */
274 no_ignore xl_error
275 xl_dagc