+#include <math.h>
+
+const char *type_name[TYPE_COUNT] = {
+ "void",
+ "string",
+ "float",
+ "vector",
+ "entity",
+ "field",
+ "function",
+ "pointer",
+#if 0
+ "integer",
+#endif
+ "variant"
+};
+
+bool opts_debug = false;
+bool opts_memchk = false;
+
+#define CheckArgs(num) do { \
+ if (prog->argc != (num)) { \
+ prog->vmerror++; \
+ printf("ERROR: invalid number of arguments for %s: %i, expected %i\n", \
+ __FUNCTION__, prog->argc, (num)); \
+ return -1; \
+ } \
+} while (0)
+
+#define GetGlobal(idx) ((qcany*)(prog->globals + (idx)))
+#define GetArg(num) GetGlobal(OFS_PARM0 + 3*(num))
+#define Return(any) *(GetGlobal(OFS_RETURN)) = (any)
+
+static int qc_print(qc_program *prog)
+{
+ size_t i;
+ for (i = 0; i < prog->argc; ++i) {
+ qcany *str = (qcany*)(prog->globals + OFS_PARM0 + 3*i);
+ printf("%s", prog_getstring(prog, str->string));
+ }
+ return 0;
+}
+
+static int qc_error(qc_program *prog)
+{
+ printf("*** VM raised an error:\n");
+ qc_print(prog);
+ prog->vmerror++;
+ return -1;
+}
+
+static int qc_ftos(qc_program *prog)
+{
+ char buffer[512];
+ qcany *num;
+ qcany str;
+ CheckArgs(1);
+ num = GetArg(0);
+ snprintf(buffer, sizeof(buffer), "%g", num->_float);
+ str.string = prog_tempstring(prog, buffer);
+ Return(str);
+ return 0;
+}
+
+static int qc_vtos(qc_program *prog)
+{
+ char buffer[512];
+ qcany *num;
+ qcany str;
+ CheckArgs(1);
+ num = GetArg(0);
+ snprintf(buffer, sizeof(buffer), "`%g %g %g`", num->vector[0], num->vector[1], num->vector[2]);
+ str.string = prog_tempstring(prog, buffer);
+ Return(str);
+ return 0;
+}
+
+static int qc_spawn(qc_program *prog)
+{
+ qcany ent;
+ CheckArgs(0);
+ ent.edict = prog_spawn_entity(prog);
+ Return(ent);
+ return (ent.edict ? 0 : -1);
+}
+
+static int qc_kill(qc_program *prog)
+{
+ qcany *ent;
+ CheckArgs(1);
+ ent = GetArg(0);
+ prog_free_entity(prog, ent->edict);
+ return 0;
+}
+
+static int qc_vlen(qc_program *prog)
+{
+ qcany *vec, len;
+ CheckArgs(1);
+ vec = GetArg(0);
+ len._float = sqrt(vec->vector[0] * vec->vector[0] +
+ vec->vector[1] * vec->vector[1] +
+ vec->vector[2] * vec->vector[2]);
+ Return(len);
+ return 0;
+}
+
+static prog_builtin qc_builtins[] = {
+ NULL,
+ &qc_print, /* 1 */
+ &qc_ftos, /* 2 */
+ &qc_spawn, /* 3 */
+ &qc_kill, /* 4 */
+ &qc_vtos, /* 5 */
+ &qc_error, /* 6 */
+ &qc_vlen /* 7 */
+};
+static size_t qc_builtins_count = sizeof(qc_builtins) / sizeof(qc_builtins[0]);
+
+static const char *arg0 = NULL;
+
+void usage()
+{
+ printf("usage: [-debug] %s file\n", arg0);
+ exit(1);
+}
+