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_QID,
35 /* casted */
36 V_U8,
37 V_U16,
38 V_U32,
39 };
41 struct value {
42 int type;
43 union {
44 char *str;
45 uint64_t num;
46 uint8_t qid[QIDSIZE];
47 } v;
48 };
50 enum {
51 OP_ASSIGN,
52 OP_ASSERT,
53 OP_FUNCALL,
54 OP_LITERAL,
55 OP_VAR,
56 OP_CAST,
57 OP_CMP_EQ,
58 };
60 struct proc;
62 struct op {
63 struct op *next;
64 int type;
65 union {
66 struct {
67 char *name;
68 struct op *expr;
69 } assign;
70 struct op *assert;
71 struct {
72 struct proc *proc;
73 struct op *argv;
74 int argc;
75 } funcall;
76 struct value literal;
77 char *var;
78 struct {
79 struct op *expr;
80 int totype;
81 } cast;
82 struct {
83 struct op *a;
84 struct op *b;
85 } cmp_eq;
86 } v;
87 };
89 TAILQ_HEAD(bindings, binding);
90 struct binding {
91 char *name;
92 struct value val;
93 TAILQ_ENTRY(binding) entry;
94 };
96 TAILQ_HEAD(envs, env);
97 struct env {
98 TAILQ_ENTRY(env) entry;
99 struct bindings bindings;
100 };
102 TAILQ_HEAD(opstacks, opstack);
103 struct opstack {
104 TAILQ_ENTRY(opstack) entry;
105 struct op base;
106 struct op *last;
107 int counter;
108 };
110 TAILQ_HEAD(procs, proc);
111 struct proc {
112 TAILQ_ENTRY(proc) entry;
113 char *name;
114 int minargs;
115 int varargs;
116 char *args[MAXWELEM];
117 struct op *body;
118 int (*nativefn)(int);
119 };
121 TAILQ_HEAD(tests, test);
122 struct test {
123 TAILQ_ENTRY(test) entry;
124 char *name;
125 char *dir;
126 struct op *body;
127 };
129 enum {
130 EVAL_OK,
131 EVAL_ERR,
132 EVAL_SKIP,
133 };
135 int global_set(char *, struct op *);
137 struct op *newop(int);
138 void free_op(struct op *);
139 struct op *op_assign(char *, struct op *);
140 struct op *op_assert(struct op *);
141 struct op *op_var(char *);
142 struct op *op_lit_str(char *);
143 struct op *op_lit_num(uint64_t);
144 struct op *op_cmp_eq(struct op *, struct op *);
145 struct op *op_cast(struct op *, int);
147 void ppf_val(FILE *, struct value *);
148 void pp_val(struct value *);
149 int val_trueish(struct value *);
150 int val_eq(struct value *, struct value *);
151 int val_cast(struct value *, int);
152 void pp_op(struct op *);
153 void pp_block(struct op *);
154 int eval(struct op *);
156 /* funcall */
157 void prepare_funcall(void);
158 void push_arg(struct op *);
159 struct op *op_funcall(struct proc *);
161 /* proc */
162 void add_builtin_proc(const char *name, int (*)(int), int);
163 void prepare_proc(void);
164 /* push_arg works on procs too */
165 int proc_setup_body(void);
166 void proc_done(char *name);
167 void block_push(struct op *);
168 struct proc *proc_by_name(const char *);
170 /* testing */
171 void prepare_test(void);
172 void test_done(char *, char *);
174 /* np.y */
175 void loadfile(const char *);
177 #endif