diff options
Diffstat (limited to 'thac.h')
| -rw-r--r-- | thac.h | 323 |
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__ */ |