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_QIDVEC,
35 V_QID,
37 /* casted */
38 V_U8,
39 V_U16,
40 V_U32,
41 };
43 struct value {
44 int type;
45 union {
46 char *str;
47 int64_t num;
48 uint8_t u8;
49 uint16_t u16;
50 uint32_t u32;
51 struct {
52 uint8_t *msg;
53 size_t len;
54 } msg;
55 struct {
56 uint8_t *start;
57 size_t len;
58 } qidvec;
59 uint8_t qid[QIDSIZE];
60 } v;
61 };
63 enum {
64 OP_REST,
65 OP_ASSIGN,
66 OP_ASSERT,
67 OP_FUNCALL,
68 OP_LITERAL,
69 OP_VAR,
70 OP_CAST,
71 OP_CMP_EQ,
72 OP_CMP_LEQ,
73 OP_FACCESS,
74 OP_SFAIL,
75 OP_VARGS,
76 };
78 struct proc;
80 struct op {
81 struct op *next;
82 int type;
83 union {
84 struct {
85 char *name;
86 struct op *expr;
87 } assign;
88 struct op *assert;
89 struct {
90 struct proc *proc;
91 struct op *argv;
92 int argc;
93 } funcall;
94 struct value literal;
95 char *var;
96 struct {
97 struct op *expr;
98 int totype;
99 } cast;
100 struct {
101 struct op *a;
102 struct op *b;
103 } bin_cmp;
104 struct {
105 struct op *expr;
106 char *field;
107 } faccess;
108 struct {
109 char *msg;
110 struct op *expr;
111 } sfail;
112 } v;
113 };
115 TAILQ_HEAD(bindings, binding);
116 struct binding {
117 TAILQ_ENTRY(binding) entry;
118 char *name;
119 struct value val;
121 /*
122 * Hack to support varargs. We set a special variable named
123 * "..." that contains the list of ops that will evaluate to
124 * the arguments.
125 */
126 struct op *raw;
127 };
129 TAILQ_HEAD(envs, env);
130 struct env {
131 TAILQ_ENTRY(env) entry;
132 struct bindings bindings;
133 };
135 TAILQ_HEAD(opstacks, opstack);
136 struct opstack {
137 TAILQ_ENTRY(opstack) entry;
138 struct op base;
139 struct op *last;
140 int counter;
141 };
143 TAILQ_HEAD(procs, proc);
144 struct proc {
145 TAILQ_ENTRY(proc) entry;
146 char *name;
147 int minargs;
148 int vararg;
149 char *args[MAXWELEM];
150 struct op *body;
151 int (*nativefn)(int);
152 };
154 TAILQ_HEAD(tests, test);
155 struct test {
156 TAILQ_ENTRY(test) entry;
157 int shouldfail;
158 char *name;
159 char *dir;
160 struct op *body;
161 };
163 enum {
164 EVAL_OK,
165 EVAL_ERR,
166 EVAL_SKIP,
167 };
169 int global_set(char *, struct op *);
171 struct op *newop(int);
172 void free_op_rec(struct op *);
173 void free_op(struct op *);
174 struct op *op_rest(void);
175 struct op *op_assign(char *, struct op *);
176 struct op *op_assert(struct op *);
177 struct op *op_var(char *);
178 struct op *op_lit_str(char *);
179 struct op *op_lit_num(uint64_t);
180 struct op *op_cmp_eq(struct op *, struct op *);
181 struct op *op_cmp_leq(struct op *, struct op *);
182 struct op *op_cast(struct op *, int);
183 struct op *op_faccess(struct op *, char *);
184 struct op *op_sfail(struct op *, char *);
185 struct op *op_vargs(void);
187 void ppf_val(FILE *, struct value *);
188 void pp_val(struct value *);
189 void pp_val(struct value *);
190 const char *val_type(struct value *);
191 int val_trueish(struct value *);
192 int val_isnum(struct value *);
193 int64_t val_tonum(struct value *);
194 int val_eq(struct value *, struct value *);
195 int val_leq(struct value *, struct value *);
196 int val_cast(struct value *, int);
197 int val_faccess(struct value *, const char *, struct value *);
198 void pp_op(struct op *);
199 void pp_block(struct op *);
200 int eval(struct op *);
202 /* funcall */
203 void prepare_funcall(void);
204 void push_arg(struct op *);
205 struct op *op_funcall(struct proc *);
207 /* proc */
208 void add_builtin_proc(const char *name, int (*)(int), int, int);
209 void prepare_proc(void);
210 /* push_arg works on procs too */
211 int proc_setup_body(void);
212 void proc_done(char *name);
213 void block_push(struct op *);
214 struct proc *proc_by_name(const char *);
216 /* testing */
217 void prepare_test(void);
218 void test_done(int, char *, char *);
220 /* np.y */
221 void loadfile(const char *);
223 #endif