summary refs log tree commit diff
path: root/thac.h
diff options
context:
space:
mode:
authorNakidai <nakidai@disroot.org>2026-04-05 19:51:14 +0300
committerNakidai <nakidai@disroot.org>2026-04-05 20:01:32 +0300
commit8afa976e073c7bc29c878230eead6dddfdcc08a1 (patch)
tree044b8ddf87b9a3c8b5a229b27e84e870468fb950 /thac.h
downloadthac-5e9fb4d28f49aa4a17b38f436a63b5a7a764457b.tar.gz
thac-5e9fb4d28f49aa4a17b38f436a63b5a7a764457b.zip
Add code v0.1.0
Diffstat (limited to 'thac.h')
-rw-r--r--thac.h323
1 files changed, 323 insertions, 0 deletions
diff --git a/thac.h b/thac.h
new file mode 100644
index 0000000..37dd9f5
--- /dev/null
+++ b/thac.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2026 Nakidai Perumenei <nakidai at disroot dot org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __THAC_H__
+#define __THAC_H__
+
+#define _POSIX_SOURCE
+
+#include <stdio.h>
+
+
+enum
+{
+	GENVARLEN = 16,
+};
+
+typedef unsigned long ulong;
+typedef long long vlong;
+
+#define lengthof(X) (sizeof(X)/sizeof(*(X)))
+#define max(X, Y) ((X) > (Y) ? (X) : (Y))
+#define min(X, Y) ((X) < (Y) ? (X) : (Y))
+
+#define ENUMGEN(X) X,
+
+#define TOKTYPES(X) \
+	X(TEOF) \
+	X(TAMPER) /* & */ \
+	X(TAND) /* && */ \
+	X(TARRLEFT) /* <- */ \
+	X(TASSAMPER) /* &= */ \
+	X(TASSASTER) /* *= */ \
+	X(TASSCARET) /* ^= */ \
+	X(TASSIGN) /* = */ \
+	X(TASSLSHIFT) /* <<= */ \
+	X(TASSMINUS) /* -= */ \
+	X(TASSPERC) /* %= */ \
+	X(TASSPIPE) /* |= */ \
+	X(TASSPLUS) /* += */ \
+	X(TASSRSHIFT) /* >>= */ \
+	X(TASSSLASH) /* /= */ \
+	X(TASTER) /* * */ \
+	X(TCARET) /* ^ */ \
+	X(TCLBRACE) /* } */ \
+	X(TCLBRACK) /* ] */ \
+	X(TCLPAREN) /* ) */ \
+	X(TCOL) /* : */ \
+	X(TCOMMA) /* , */ \
+	X(TCONCAT) /* >< */ \
+	X(TDECR) /* -- */ \
+	X(TEQ) /* == */ \
+	X(TEXCLAM) /* ! */ \
+	X(TID) /* <identifier> */ \
+	X(TINCR) /* ++ */ \
+	X(TKEYASSERT) /* assert */ \
+	X(TKEYBREAK) /* break */ \
+	X(TKEYCONT) /* continue */ \
+	X(TKEYELSE) /* else */ \
+	X(TKEYFOR) /* for */ \
+	X(TKEYFOREACH) /* foreach */ \
+	X(TKEYIF) /* if */ \
+	X(TKEYLEN) /* len */ \
+	X(TKEYMOD) /* mod */ \
+	X(TKEYNODE) /* node */ \
+	X(TKEYWITH) /* with */ \
+	X(TLESS) /* < */ \
+	X(TLESSEQ) /* <= */ \
+	X(TLSHIFT) /* << */ \
+	X(TMINUS) /* - */ \
+	X(TGREAT) /* > */ \
+	X(TGREATEQ) /* >= */ \
+	X(TNEQ) /* != */ \
+	X(TNUM) /* <number> */ \
+	X(TOPBRACE) /* { */ \
+	X(TOPBRACK) /* [ */ \
+	X(TOPPAREN) /* ( */ \
+	X(TOR) /* || */ \
+	X(TPERC) /* % */ \
+	X(TPIPE) /* | */ \
+	X(TPLUS) /* + */ \
+	X(TPOW) /* ** */ \
+	X(TQUEST) /* ? */ \
+	X(TRSHIFT) /* >> */ \
+	X(TSEMICOL) /* ; */ \
+	X(TSLASH) /* / */ \
+	X(TTILDE) /* ~ */ \
+	/* TOKTYPES */
+
+#define NODETYPES(X) \
+	X(NCOMP) /* compound statement */ \
+	X(NCOND) /* if statement */ \
+	X(NFOR) /* for statement */ \
+	X(NFOREACH) /* for statement */ \
+	X(NMOD) /* module expression */ \
+	X(NNUM) /* number */ \
+	X(NNODE) /* node expression */ \
+	X(NOPER) /* (unary (m) / binary (l r) / ternary (l m r)) operator */ \
+	X(NWITH) /* module invocation */ \
+	X(NVAR) /* variable reference */ \
+	X(NBREAK) /* break statement to exit the loop */ \
+	X(NCONT) /* continue statement to go to next loop iteration */ \
+	/* NODETYPES */
+
+#define NOPERTYPES(X) \
+	X(OLEN) \
+	X(OASSERT) \
+	X(OCONNECT) \
+	X(OINDEX) \
+	X(OSLICE) \
+	X(OARRAY) \
+	X(OCONCAT) \
+	/* binary logic */ \
+	X(OBAND) \
+	X(OBOR) \
+	X(OBXOR) \
+	X(OLSHIFT) \
+	X(ORSHIFT) \
+	X(OINV) \
+	/* logic */ \
+	X(OAND) \
+	X(ONOT) \
+	X(OOR) \
+	X(OCOND) \
+	/* relations */ \
+	X(OEQ) \
+	X(ONEQ) \
+	X(OLESS) \
+	X(OLESSEQ) \
+	X(OGREAT) \
+	X(OGREATEQ) \
+	/* algebraic */ \
+	X(OPOSTDECR) \
+	X(OPOSTINCR) \
+	X(OPREDECR) \
+	X(OPREINCR) \
+	X(OSUM) \
+	X(OSUB) \
+	X(OMUL) \
+	X(ODIV) \
+	X(OMOD) \
+	X(OPOW) \
+	/* assignment */ \
+	X(OASSBAND) \
+	X(OASSMUL) \
+	X(OASSBXOR) \
+	X(OASSIGN) \
+	X(OASSLSHIFT) \
+	X(OASSSUB) \
+	X(OASSMOD) \
+	X(OASSBOR) \
+	X(OASSSUM) \
+	X(OASSRSHIFT) \
+	X(OASSDIV) \
+	/* NOPERTYPES */
+
+#define VALTYPES(X) \
+	X(VNIL) \
+	X(VBREAK) \
+	X(VCONT) \
+	X(VNUM) \
+	X(VVAR) \
+	X(VARR) \
+	/* VALTYPES */
+
+struct tok
+{
+	enum tok_t {TOKTYPES(ENUMGEN)} type;
+	struct tinfo
+	{
+		char *p;
+		ulong len, cap;
+	} info;
+};
+
+struct node
+{
+	enum node_t {NODETYPES(ENUMGEN)} type;
+	union
+	{
+		struct ncomp
+		{
+			struct node **stmts;
+			ulong len;
+		} ncomp;
+		struct ncond
+		{
+			struct node *cond, *t, *f;
+		} ncond;
+		struct nfor
+		{
+			struct node *before, *cond, *between, *code;
+		} nfor;
+		struct nforeach
+		{
+			struct node *obj, *code;
+		} nforeach;
+		struct nmod
+		{
+			struct node *code;
+			char **params;
+			ulong len;
+		} nmod;
+		vlong nnum;
+		struct nnode
+		{
+			struct node **params;
+			ulong len;
+		} nnode;
+		struct noper
+		{
+			enum noper_t {NOPERTYPES(ENUMGEN)} type;
+			struct node *l, *m, *r;
+		} noper;
+		struct nwith
+		{
+			struct node *mod, **args, *code;
+			ulong len;
+		} nwith;
+		char *nvar;
+	};
+};
+
+struct val
+{
+	enum val_t {VALTYPES(ENUMGEN)} type;
+	union
+	{
+		char *name; /* VVAR */
+		vlong num; /* VNUM */
+		struct /* VARR; */
+		{
+			struct val *arr;
+			ulong len;
+		};
+	};
+};
+
+struct scope
+{
+	struct scope *parent;
+	struct var
+	{
+		char *name;
+		struct val val;
+	} *vars;
+	ulong len;
+};
+
+struct vertex
+{
+	struct
+	{
+		vlong *arr;
+		ulong len;
+	} props;
+	struct
+	{
+		ulong *arr;
+		ulong len;
+	} nbrs;
+};
+
+extern FILE *curfile;
+extern char *curname, *progname;
+extern ulong curline;
+
+extern struct scope basescope;
+extern struct tok curtok;
+extern struct val nil;
+
+void complain(int code, char *, ...);
+void say(char *, ...);
+void die(int code, char *, ...);
+void dieno(int code, char *, ...);
+
+enum tok_t gettok(void);
+void ungettok(void);
+#define exptok(...) _exptok(__VA_ARGS__, TEOF)
+int _exptok(enum tok_t, ...);
+
+struct node *getstmt(void);
+struct val eval(struct node *, struct scope *);
+
+long findvar(char *, struct scope **);
+ulong assignvar(char *, struct val, struct scope **);
+int varnextchar(struct scope *);
+ulong varnextnum(struct scope *);
+void delvarscope(struct scope *, ulong);
+
+struct val deref(struct val, struct scope *);
+struct val getval(enum val_t, struct val, struct scope *, int);
+struct val copyval(struct val old);
+void freeval(struct val);
+struct val connectval(struct val, struct val, struct scope *);
+
+ulong mkvert(void);
+void addprop(ulong, vlong);
+void addedge(ulong, ulong);
+void showverts(void);
+
+void walkval(struct val *, ulong);
+void walknode(struct node *, ulong);
+void walkscope(struct scope *, ulong);
+
+char *tokname(enum tok_t);
+char *nodename(enum node_t);
+char *valname(enum val_t);
+char *nopername(enum noper_t);
+
+#endif /* __THAC_H__ */