Blob


1 /*
2 * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
17 #ifndef SCRIPT_H
18 #define SCRIPT_H
20 #include "compat.h"
22 #include <stdio.h>
24 #include "kamid.h"
26 enum {
27 /* literals */
28 V_SYM,
29 V_STR,
30 V_NUM,
32 /* foreign */
33 V_MSG,
34 V_QID,
36 /* casted */
37 V_U8,
38 V_U16,
39 V_U32,
40 };
42 struct value {
43 int type;
44 union {
45 char *str;
46 int64_t num;
47 uint8_t u8;
48 uint16_t u16;
49 uint32_t u32;
50 struct {
51 uint8_t *msg;
52 size_t len;
53 } msg;
54 uint8_t qid[QIDSIZE];
55 } v;
56 };
58 enum {
59 OP_REST,
60 OP_ASSIGN,
61 OP_ASSERT,
62 OP_FUNCALL,
63 OP_LITERAL,
64 OP_VAR,
65 OP_CAST,
66 OP_CMP_EQ,
67 OP_FACCESS,
68 OP_SFAIL,
69 };
71 struct proc;
73 struct op {
74 struct op *next;
75 int type;
76 union {
77 struct {
78 char *name;
79 struct op *expr;
80 } assign;
81 struct op *assert;
82 struct {
83 struct proc *proc;
84 struct op *argv;
85 int argc;
86 } funcall;
87 struct value literal;
88 char *var;
89 struct {
90 struct op *expr;
91 int totype;
92 } cast;
93 struct {
94 struct op *a;
95 struct op *b;
96 } cmp_eq;
97 struct {
98 struct op *expr;
99 char *field;
100 } faccess;
101 struct {
102 char *msg;
103 struct op *expr;
104 } sfail;
105 } v;
106 };
108 TAILQ_HEAD(bindings, binding);
109 struct binding {
110 TAILQ_ENTRY(binding) entry;
111 char *name;
112 struct value val;
114 /*
115 * Hack to support varargs. We set a special variable named
116 * "..." that contains the list of ops that will evaluate to
117 * the arguments.
118 */
119 struct op *raw;
120 };
122 TAILQ_HEAD(envs, env);
123 struct env {
124 TAILQ_ENTRY(env) entry;
125 struct bindings bindings;
126 };
128 TAILQ_HEAD(opstacks, opstack);
129 struct opstack {
130 TAILQ_ENTRY(opstack) entry;
131 struct op base;
132 struct op *last;
133 int counter;
134 };
136 TAILQ_HEAD(procs, proc);
137 struct proc {
138 TAILQ_ENTRY(proc) entry;
139 char *name;
140 int minargs;
141 int vararg;
142 char *args[MAXWELEM];
143 struct op *body;
144 int (*nativefn)(int);
145 };
147 TAILQ_HEAD(tests, test);
148 struct test {
149 TAILQ_ENTRY(test) entry;
150 int shouldfail;
151 char *name;
152 char *dir;
153 struct op *body;
154 };
156 enum {
157 EVAL_OK,
158 EVAL_ERR,
159 EVAL_SKIP,
160 };
162 int global_set(char *, struct op *);
164 struct op *newop(int);
165 void free_op(struct op *);
166 struct op *op_rest(void);
167 struct op *op_assign(char *, struct op *);
168 struct op *op_assert(struct op *);
169 struct op *op_var(char *);
170 struct op *op_lit_str(char *);
171 struct op *op_lit_num(uint64_t);
172 struct op *op_cmp_eq(struct op *, struct op *);
173 struct op *op_cast(struct op *, int);
174 struct op *op_faccess(struct op *, char *);
175 struct op *op_sfail(struct op *, char *);
177 void ppf_val(FILE *, struct value *);
178 void pp_val(struct value *);
179 int val_trueish(struct value *);
180 int val_eq(struct value *, struct value *);
181 int val_cast(struct value *, int);
182 int val_faccess(struct value *, const char *, struct value *);
183 void pp_op(struct op *);
184 void pp_block(struct op *);
185 int eval(struct op *);
187 /* funcall */
188 void prepare_funcall(void);
189 void push_arg(struct op *);
190 struct op *op_funcall(struct proc *);
192 /* proc */
193 void add_builtin_proc(const char *name, int (*)(int), int, int);
194 void prepare_proc(void);
195 /* push_arg works on procs too */
196 int proc_setup_body(void);
197 void proc_done(char *name);
198 void block_push(struct op *);
199 struct proc *proc_by_name(const char *);
201 /* testing */
202 void prepare_test(void);
203 void test_done(int, char *, char *);
205 /* np.y */
206 void loadfile(const char *);
208 #endif