about summary refs log tree commit diff stats
path: root/modal
diff options
context:
space:
mode:
authorelioat <hi@eli.li>2024-04-19 14:58:08 -0400
committerelioat <hi@eli.li>2024-04-19 14:58:08 -0400
commit424301cbbe01a608cf7df8f4b3c9c2f856aa1740 (patch)
treeb73e2e06c559d3b7ec391861458f202bb15bb977 /modal
parente80d2a31862110c8913358027905cbcf905274ce (diff)
downloadtour-424301cbbe01a608cf7df8f4b3c9c2f856aa1740.tar.gz
*
Diffstat (limited to 'modal')
-rw-r--r--modal/.gitignore1
-rw-r--r--modal/logic.modal4
-rw-r--r--modal/modal.c252
3 files changed, 257 insertions, 0 deletions
diff --git a/modal/.gitignore b/modal/.gitignore
new file mode 100644
index 0000000..d08a843
--- /dev/null
+++ b/modal/.gitignore
@@ -0,0 +1 @@
+modal
\ No newline at end of file
diff --git a/modal/logic.modal b/modal/logic.modal
new file mode 100644
index 0000000..7699841
--- /dev/null
+++ b/modal/logic.modal
@@ -0,0 +1,4 @@
+<> (eq ?x ?x) (#t)
+<> (eq ?x ?y) (#f)
+
+.. (eq fox bat)
\ No newline at end of file
diff --git a/modal/modal.c b/modal/modal.c
new file mode 100644
index 0000000..c7bf0f8
--- /dev/null
+++ b/modal/modal.c
@@ -0,0 +1,252 @@
+/* 
+	by https://wryl.tech/
+ 	from https://wiki.xxiivv.com/site/modal
+ 	cc modal.c -o modal
+*/
+
+#include <stdio.h>
+
+typedef struct {
+	int id;
+	char *a, *b;
+} Rule;
+
+static int flip, rmin = 0xff, rmax = 0x00, cycles = 0x10000;
+static Rule rules[0x1000], lambda, *rules_ = rules;
+static char dict[0x8000], *dict_ = dict;
+static char bank_a[0x4000], *src_ = bank_a;
+static char bank_b[0x4000], *dst_ = bank_b;
+static char *regs[0x100];
+
+#define spacer(c) (c <= ' ' || c == '(' || c == ')')
+
+static char *
+walk(char *s)
+{
+	char c;
+	int depth = 0;
+	if(*s == '(') {
+		while((c = *s++)) {
+			if(c == '(') depth++;
+			if(c == ')') --depth;
+			if(!depth) return s;
+		}
+	}
+	while((c = *s) && !spacer(c)) s++;
+	return s;
+}
+
+static int
+set_reg(int r, char *b)
+{
+	if(regs[r]) {
+		char *a = regs[r], *aa = walk(a), *bb = walk(b);
+		while(a < aa && b < bb)
+			if(*a++ != *b++) return 0;
+	} else {
+		regs[r] = b;
+		if(r < rmin) rmin = r;
+		if(r > rmax) rmax = r;
+	}
+	return 1;
+}
+
+static void
+put_reg(char r)
+{
+	char c, *s = regs[(int)r], *ss;
+	if(!s) {
+		*dst_++ = '?', *dst_++ = r;
+		return;
+	}
+	ss = walk(s);
+	if(r == '*') {
+		int i, depth = 0;
+		if(*s == '(') { /* special explode tuple */
+			s++;
+			while(s < ss) {
+				while((c = *s) && !spacer(c))
+					*dst_++ = c, s++;
+				*dst_++ = ' ';
+				*dst_++ = '(', s++, depth++;
+			}
+		} else { /* special explode token */
+			while((c = *s++) && !spacer(c))
+				*dst_++ = c, *dst_++ = ' ', *dst_++ = '(', depth++;
+		}
+		for(i = 0; i < depth; i++)
+			*dst_++ = ')';
+	} else if(r == '.') { /* special unpack */
+		if(*s == '(') s++, --ss;
+		while(s < ss) *dst_++ = *s++;
+	} else if(r == '^') { /* special join */
+		if(*s == '(') s++, --ss;
+		while(s < ss && (c = *s++))
+			if(!spacer(c)) *dst_++ = c;
+	} else if(r == '~') { /* special stdin */
+		while(fread(&c, 1, 1, stdin) && c >= ' ')
+			*dst_++ = c;
+	} else if(r == ':') { /* special stdout */
+		if(*s == '(') s++, --ss;
+		while(s < ss) {
+			c = *s++;
+			if(c == '\\') {
+				switch(*s++) {
+				case 't': putc(0x09, stdout); break;
+				case 'n': putc(0x0a, stdout); break;
+				case 's': putc(0x20, stdout); break;
+				}
+			} else
+				putc(c, stdout);
+		}
+	} else
+		while(s < ss) *dst_++ = *s++;
+}
+
+static char *
+match_rule(Rule *r, char *p)
+{
+	int i;
+	char c, last = 0, *a = r->a, *b = p;
+	if(rmax) {
+		for(i = rmin; i <= rmax; i++)
+			regs[i] = 0;
+		rmin = 0xff, rmax = 0x00;
+	}
+	while((c = *a)) {
+		if(spacer(last) && c == '?') {
+			if(!set_reg(*(++a), b)) return NULL;
+			a++, b = walk(b);
+			continue;
+		}
+		if(c != *b) return NULL;
+		a++, b++, last = c;
+	}
+	c = *b;
+	return spacer(c) ? b : NULL;
+}
+
+static int
+commit_rule(Rule *r, char *s, int create)
+{
+	while((*dst_++ = *s++))
+		;
+	*dst_++ = 0;
+	if((flip = !flip))
+		src_ = bank_b, dst_ = bank_a;
+	else
+		src_ = bank_a, dst_ = bank_b;
+	if(create)
+		fprintf(stderr, "<> (%s) (%s)\n", r->a, r->b);
+	else
+		fprintf(stderr, "%02d %s\n", r->id, src_);
+	return 1;
+}
+
+static int
+write_rule(Rule *r, char last, char *res)
+{
+	char c, *b = r->b, *origin = dst_;
+	while((c = *b++))
+		if(spacer(last) && c == '?')
+			put_reg(*b++);
+		else
+			*dst_++ = c, last = c;
+	if(dst_ == origin) {
+		while(*res == ' ') res++;
+		if(*res == ')' && *(dst_ - 1) == ' ') dst_--;
+	}
+	return commit_rule(r, res, 0);
+}
+
+static char *
+parse_frag(char *s)
+{
+	char c, *ss;
+	while((c = *s) && c <= ' ') s++;
+	if(*s != ')' && !(*s == '<' && s[1] == '>')) {
+		ss = walk(s);
+		if(*s == '(') {
+			s++;
+			while(s < ss - 1) *dict_++ = *s++;
+			s++;
+		} else
+			while(s < ss) *dict_++ = *s++;
+	}
+	*dict_++ = 0;
+	return s;
+}
+
+static char *
+create_rule(Rule *r, int id, char *s)
+{
+	r->id = id, s += 2;
+	r->a = dict_, s = parse_frag(s);
+	r->b = dict_, s = parse_frag(s);
+	return s;
+}
+
+static int
+rewrite(void)
+{
+	char c, last = 0, *cap, *s = src_, *res;
+	while((c = *s) && c <= ' ') s++;
+	while((c = *s)) {
+		if(spacer(last)) {
+			Rule *r;
+			if(*s == '<' && s[1] == '>') {
+				r = rules_++;
+				s = create_rule(r, rules_ - rules - 1, s);
+				while((c = *s) && c <= ' ') s++;
+				return commit_rule(r, s, 1);
+			}
+			if(*s == '?' && s[1] == '(') {
+				r = &lambda, cap = walk(s + 1);
+				create_rule(&lambda, -1, s), s = cap;
+				while((c = *s) && c <= ' ') s++;
+				if((res = match_rule(&lambda, s)) != NULL)
+					return write_rule(&lambda, last, res);
+			}
+			for(r = rules; r < rules_; r++)
+				if((res = match_rule(r, s)) != NULL)
+					return write_rule(r, last, res);
+		}
+		*dst_++ = last = c;
+		s++;
+	}
+	*dst_++ = 0;
+	return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+	FILE *f;
+	int i;
+	char c, *w = bank_a;
+	if(argc < 2)
+		return !printf("usage: modal [-vqn] source.modal\n");
+	for(i = 1; i < argc && *argv[i] == '-'; i++) {
+		switch(argv[i][1]) {
+		case 'v': /* version */ return !printf("Modal Interpreter, 18 Apr 2024.\n");
+		case 'q': /* quiet */ fclose(stderr); break;
+		case 'n': /* infinite */ cycles = 0xffffffff; break;
+		}
+	}
+	if(!(f = fopen(argv[i], "r")))
+		return !fprintf(stdout, "Invalid Modal file: %s.\n", argv[i]);
+	while(fread(&c, 1, 1, f)) {
+		c = c <= 0x20 ? 0x20 : c;
+		if(w > bank_a) {
+			if(c == ' ' && *(w - 1) == '(') continue;
+			if(c == ')' && *(w - 1) == ' ') w--;
+			if(c == ' ' && *(w - 1) == ' ') w--;
+		}
+		*w++ = c;
+	}
+	while(*(--w) <= ' ') *w = 0;
+	fclose(f);
+	while(rewrite())
+		if(!cycles--) return !fprintf(stdout, "Modal rewrites exceeded.\n");
+	return 0;
+}
\ No newline at end of file
ss="cm"> * * Copyright (C) 2012 - 2014 James Booth <boothj5@gmail.com> * * This file is part of Profanity. * * Profanity is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Profanity is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Profanity. If not, see <http://www.gnu.org/licenses/>. * */ #ifndef COMMANDS_H #define COMMANDS_H // Command help strings typedef struct cmd_help_t { const gchar *usage; const gchar *short_help; const gchar *long_help[50]; } CommandHelp; /* * Command structure * * cmd - The command string including leading '/' * func - The function to execute for the command * parser - The function used to parse arguments * min_args - Minimum number of arguments * max_args - Maximum number of arguments * help - A help struct containing usage info etc */ typedef struct cmd_t { gchar *cmd; gboolean (*func)(gchar **args, struct cmd_help_t help); gchar** (*parser)(const char * const inp, int min, int max, gboolean *result); int min_args; int max_args; void (**setting_func)(void); CommandHelp help; } Command; gboolean cmd_about(gchar **args, struct cmd_help_t help); gboolean cmd_account(gchar **args, struct cmd_help_t help); gboolean cmd_autoaway(gchar **args, struct cmd_help_t help); gboolean cmd_autoconnect(gchar **args, struct cmd_help_t help); gboolean cmd_autoping(gchar **args, struct cmd_help_t help); gboolean cmd_away(gchar **args, struct cmd_help_t help); gboolean cmd_beep(gchar **args, struct cmd_help_t help); gboolean cmd_caps(gchar **args, struct cmd_help_t help); gboolean cmd_chat(gchar **args, struct cmd_help_t help); gboolean cmd_chlog(gchar **args, struct cmd_help_t help); gboolean cmd_clear(gchar **args, struct cmd_help_t help); gboolean cmd_close(gchar **args, struct cmd_help_t help); gboolean cmd_connect(gchar **args, struct cmd_help_t help); gboolean cmd_decline(gchar **args, struct cmd_help_t help); gboolean cmd_disco(gchar **args, struct cmd_help_t help); gboolean cmd_disconnect(gchar **args, struct cmd_help_t help); gboolean cmd_dnd(gchar **args, struct cmd_help_t help); gboolean cmd_duck(gchar **args, struct cmd_help_t help); gboolean cmd_flash(gchar **args, struct cmd_help_t help); gboolean cmd_gone(gchar **args, struct cmd_help_t help); gboolean cmd_grlog(gchar **args, struct cmd_help_t help); gboolean cmd_group(gchar **args, struct cmd_help_t help); gboolean cmd_help(gchar **args, struct cmd_help_t help); gboolean cmd_history(gchar **args, struct cmd_help_t help); gboolean cmd_info(gchar **args, struct cmd_help_t help); gboolean cmd_intype(gchar **args, struct cmd_help_t help); gboolean cmd_invite(gchar **args, struct cmd_help_t help); gboolean cmd_invites(gchar **args, struct cmd_help_t help); gboolean cmd_join(gchar **args, struct cmd_help_t help); gboolean cmd_leave(gchar **args, struct cmd_help_t help); gboolean cmd_log(gchar **args, struct cmd_help_t help); gboolean cmd_mouse(gchar **args, struct cmd_help_t help); gboolean cmd_msg(gchar **args, struct cmd_help_t help); gboolean cmd_nick(gchar **args, struct cmd_help_t help); gboolean cmd_notify(gchar **args, struct cmd_help_t help); gboolean cmd_online(gchar **args, struct cmd_help_t help); gboolean cmd_otr(gchar **args, struct cmd_help_t help); gboolean cmd_outtype(gchar **args, struct cmd_help_t help); gboolean cmd_prefs(gchar **args, struct cmd_help_t help); gboolean cmd_priority(gchar **args, struct cmd_help_t help); gboolean cmd_quit(gchar **args, struct cmd_help_t help); gboolean cmd_reconnect(gchar **args, struct cmd_help_t help); gboolean cmd_rooms(gchar **args, struct cmd_help_t help); gboolean cmd_bookmark(gchar **args, struct cmd_help_t help); gboolean cmd_roster(gchar **args, struct cmd_help_t help); gboolean cmd_software(gchar **args, struct cmd_help_t help); gboolean cmd_splash(gchar **args, struct cmd_help_t help); gboolean cmd_states(gchar **args, struct cmd_help_t help); gboolean cmd_status(gchar **args, struct cmd_help_t help); gboolean cmd_statuses(gchar **args, struct cmd_help_t help); gboolean cmd_sub(gchar **args, struct cmd_help_t help); gboolean cmd_theme(gchar **args, struct cmd_help_t help); gboolean cmd_tiny(gchar **args, struct cmd_help_t help); gboolean cmd_titlebar(gchar **args, struct cmd_help_t help); gboolean cmd_vercheck(gchar **args, struct cmd_help_t help); gboolean cmd_who(gchar **args, struct cmd_help_t help); gboolean cmd_win(gchar **args, struct cmd_help_t help); gboolean cmd_wins(gchar **args, struct cmd_help_t help); gboolean cmd_xa(gchar **args, struct cmd_help_t help); gboolean cmd_alias(gchar **args, struct cmd_help_t help); gboolean cmd_xmlconsole(gchar **args, struct cmd_help_t help); #endif