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(opstacks, opstack);
90 struct opstack {
91 TAILQ_ENTRY(opstack) entry;
92 struct op base;
93 struct op *last;
94 int counter;
95 };
97 TAILQ_HEAD(procs, proc);
98 struct proc {
99 TAILQ_ENTRY(proc) entry;
100 char *name;
101 int minargs;
102 int varargs;
103 char *args[MAXWELEM];
104 struct op *body;
105 int (*nativefn)(int);
106 };
108 TAILQ_HEAD(tests, test);
109 struct test {
110 TAILQ_ENTRY(test) entry;
111 char *name;
112 char *dir;
113 struct op *body;
114 };
116 enum {
117 EVAL_OK,
118 EVAL_ERR,
119 EVAL_SKIP,
120 };
122 void global_set(char *, struct op *);
124 struct op *newop(int);
125 void free_op(struct op *);
126 struct op *op_assign(char *, struct op *);
127 struct op *op_assert(struct op *);
128 struct op *op_var(char *);
129 struct op *op_lit_str(char *);
130 struct op *op_lit_num(uint64_t);
131 struct op *op_cmp_eq(struct op *, struct op *);
132 struct op *op_cast(struct op *, int);
134 void ppf_val(FILE *, struct value *);
135 void pp_val(struct value *);
136 int val_trueish(struct value *);
137 int val_eq(struct value *, struct value *);
138 int val_cast(struct value *, int);
139 void pp_op(struct op *);
140 void pp_block(struct op *);
141 int eval(struct op *);
143 /* funcall */
144 void prepare_funcall(void);
145 void push_arg(struct op *);
146 struct op *op_funcall(struct proc *);
148 /* proc */
149 void add_builtin_proc(const char *name, int (*)(int));
150 void prepare_proc(void);
151 /* push_arg works on procs too */
152 int proc_setup_body(void);
153 void proc_done(char *name);
154 void block_push(struct op *);
155 struct proc *proc_by_name(const char *);
157 /* testing */
158 void prepare_test(void);
159 void test_done(char *, char *);
161 /* np.y */
162 void loadfile(const char *);
164 #endif