type node = L of string | R of node array | C of string array | B of node list | O of node | F of (unit -> node)
let punct = C[|
	"."; ",";
	"?"; " ?"; "??"; " ??"; " ? ?";
	"!"; " !"; "!!"; " !!"; " ! !";
	"…"; "..."; ". . . "; "...!";
	"!?"; " !?"; " ! ?"; " <3"; " ♥";
	"~"; " ~uwu~"; " XD"; " :D";
	" :P"; " ;)"; " :)"; " :("; 
	" ಠ_ಠ"; " ^_^"; " >_>";
	" >_<";
|]
let dimin = C [|
	"hon";
	"honey";
	"honeybunch";
	"dear";
	"dearie";
	"my dear";
	"sweetie";
	"sweetheart";
	"bro";
	"babe";
	"dude";
	"bruh";
	"my man";
	"sweetcheeks";
	"kiddo";
	"kid";
	"daddy";
	"folks";
	"girl";
	"my child";
	"my sweet summer child";
	"pumpkin";
	"punkin";
	"my boy";
	"little boy";
	"little girl";
	"punk";
	"bb";
	"genius";
	"cuck";
	"bitch";
	"buddy";
	"bud";
	"pal";
	"silly";
	"silly boy";
	"dummy";
|]
let writers = C[|
	(* miscellaneous assholes & multipurpose tools *)
	"lacan"; "derrida"; "chomsky"; "nietzsche"; "baudrillard"; "beaudrillard"; 
	"freud"; "pinker"; "žižek"; "zizek"; "foucault"; "deleuze"; "delueze"; "kant"; "hume";
	"russell"; "russel"; "descartes"; "guattari"; "guatari"; "richelieu"; "hegel"; "heidegger";
	"de tocqueville"; "de toqueville"; "friedman"; "keynes"; "hobbes"; "bacon"; "avicenna";
	"schopenhauer"; "camus"; "hamilton"; "schwarzenegger"; "rousseau"; "rawls"; "goethe";
	"hobbes"; "friedman"; "fromm"; "hubbard"; "johnson";
	(* greeks *)
	"plato"; "aristotle"; "socrates"; "aristophanes"; "democritus";
	(* commies *)
	"trotsky"; "comrade trotsky"; "lenin"; "comrade lenin"; "mao"; "marx";
	"hoxha";
	(* there are a lot of ways to misspell that man's name *)
	"kierkegaard"; "kierkegard"; "keirkegaard"; "keirkegard";
	(* names i just made up*)
	"o'dair"; "wilson"; "saint-madeleine"; "sampson-crusoe"; "lambert"; "hernández";
	"duchamp"; "roberts"; "michaud"; "bägelstein"; "braustwitz"; "lawrence"; "smith";
	(* elvish word generator *)
	"harviorha"; "vieluval"; "beceou"; "ilvëthiorá"; "lioralie"; "bainon"; "alherdor";
	"lenusá";
	(* fictional characters *)
	"dracula"; "voight-kampff"; "bond"; "thranduil"; "hood";
	(* me *)
	"hale";
|]
let interj = C [|
	"wow";
	"w o w";
	"lmao";
	"lmfao";
	"rofl";
	"no";
	"nope";
	"wrong";
	"nuh-uh";
	"lol";
	"haha";
	"um";
	"k";
	"okay";
	"ok";
	"amazing";
	"alright";
	"now";
	"jesus";
	"oh boy";
	"boy";
	"man";
	"oh man";
	"oh my";
	"oh god";
	"god";
	"oh wow";
	"oh my sweet summer child";
	"my sweet summer child";
	"yo";
	"but";
	"so";
	"no way";
	"fake";
	"holy shit";
	"holy crap";
	"what the fuck";
	"ugh";
	"ughhh";
	"ugghh";
	"uugh";
	"yuck";
	"ew";
	"gross";
	"try and keep up";
|]
let disagreements = C[|
	"well";
	"well maybe";
	"well, maybe";
	"well, no";
	"well, actually";
	"well actually";
	"okay well";
	"actually";
	"maybe";
	"but";
	"and";
	"so";
	"first off";
	"firstly";
	"okay so first off";
	"okay well firstly";
|]
let chance i = (Random.int i) = 0
let pick (r : 'a array) : 'a = r.(Random.int(Array.length r))
let quote x = F(fun () -> if chance 30 then R[|
	B[L"\""; x ;L"\""];
	B[L"“"; x ;L"”";];
|] else x)
type word = A of string | An of string
let rude_adjs = [|
	A "smelly"; A "gross"; A "far-right"; A "right-wing";
	A "whiny"; A "childish"; A "stupid"; A "thoughtless";
	A "worthless"; An "inane";  An "idiotic"; A "fucking";
	A "fuckin"; A "pissy"; A "dumbfuck"; A "thick";
	A "sad"; A "pathetic"; A "witless"; A"horny";
	A "useless"; An "irrational";
|]
let rude_nouns = [|
	A "dumbass"; An "asshole"; A "jerk"; A "dipshit";
	A "baby"; A "nazi"; A "chucklefuck"; A "pig";
	An "ass"; A "dork"; A "geek"; A "nerd"; A "loser";
	A "whiner"; A "wanker"; A "gobshite"; A "wingnut";
	A "boob"; A "fuck"; A "fucker"; A "cuck"; A "yokel";
	A "feeb"; A "thug"; A"gringo";
|]
let makeinsult () = let adj = if chance 2 then Some(pick rude_adjs) else None in
	let noun = pick rude_nouns in L(match adj, noun with
		| None, A(n) -> "a " ^ n
		| None, An(n) -> "an " ^ n
		| Some(A(a)), A(n) 
		| Some(A(a)), An(n) -> "a " ^ a ^ " " ^ n
		| Some(An(a)), A(n) 
		| Some(An(a)), An(n) -> "an " ^ a ^ " " ^ n);;
		
let starters = R[| interj; interj; disagreements; |]
let byes = C[| "thanks"; "thx"; "kthx"; "kthxbye"; "bye"; "bye now"; "goodbye"; "bye-bye"; "byeee"; "byeeee"; "love you too"; "byebye"; "pls and thx"; "please and thanks"; "please and thank you"; "okay"; "have a nice day"; "goodnight"; "if you know what i mean";|]
let closers = R[| byes; dimin; B[byes; O(punct); L" "; dimin;];|]
let ewe = C[| "you"; "u"; "you"; "u"; "you"; "u"; "you"; "u"; "you're";|]
let yore = R[| L"your"; L"you're"; L"ur"; L"yr"; L"u're"; B[ewe; L" are"]; B[ewe; L" r"];|]
let pleez = C[|"please"; "pls"; "plz";|]
let poscmds = R[|
	L "grow up";
	L "learn to read";
	B[L "listen to "; yore; O(L " "); L "self"];
	B[L "calm "; yore; R[|
		B[O(L " "); L "self"; O(L" down")];
		L" tits";
	|]];
	L"calm down";
	L"calm dowm";
	B[L "use "; yore; L " brain"];
	B[C[|"read"; "listen to"|]; L" what "; yore; C[|" sayin"; " saying"|]];
	B[L "think before "; ewe; L " speak"];
	L "try again";
	L "try harder";
	L "explain";
	B[L "explain "; yore; O(L " "); L "self"];
	B[L "explain "; yore; L " reasoning"];
	B[L "explain "; yore; L " logic"];
	B[L "explain "; yore; L " evidence"];
	B[L "show me "; yore; L " evidence"];
	L "go away";
	L "check the bible";
	L "pay attention";
	B[L "learn "; yore; L " place"];
	L "shut up";
	L "shut the fuck up";
	L "stop talking";
	L "shut your mouth";
	L "answer my question";
	L "read a book";
	B[L "read "; O(L"some "); writers];
	B[L "read "; O(L"some "); writers];
	B[L "read "; O(L"some "); writers];
	L "go to hell";
	L "burn in hell";
	L "go to jail";
	L "notice me senpai";
	B[L "stop contradicting "; yore; O(L " "); L "self"];
	L "alert the presses";
	L "get a job";
	L "learn to take a joke";
	L "stop projecting";
	L "speak english";
	L "face facts";
	L "pay me";
	L "die in a fire";
	B[L"stop being "; F makeinsult;];
	B[L"stop being such "; F makeinsult;];
	B[L"quit being "; F makeinsult;];
	B[C[|"learn ";"lern ";"lrn "|]; O(L"how "); C[|"to ";"2 ";"too ";"two "; "";|]; C[|"spell";"spel";"spele";"speling";"spelling"|]];
|]
let negcmds = R [|
	B[L"be "; F makeinsult;];
	B[L"be such "; F makeinsult;];
	B[L"act like such "; F makeinsult;];
	B[L"keep acting like such "; F makeinsult;];
	B[L"make "; F makeinsult; L " of "; yore; O(L " "); L "self"];
	B[L"make such "; F makeinsult; L " of "; yore; O(L " "); L "self"];
	L"be that way";
	L"talk like that";
	L"keep whining";
	L"whine";
	
|]
let commands = R[|
	poscmds;
	poscmds;
	poscmds;
	B[C[|"don't "; "dont "|]; negcmds];
|]
let thats = C[| "that is"; "that's"; "it's"; "it is";|]
let thathas = C[| "that has"; "that's"; "it has"; "it has";|]
let thatsnot = C[| "that isn't"; "that's not"; "it's not"; "it isn't"; "that is not"; "it is not";|]
let theirs = C[| "there is"; "there's"; "theirs"; "their's"; |]
let thathasnt = C[| "that hasn't"; "that's not"; "it's not"; "it hasn't"; "that has not"; "it has not";|]
let im = C[| "i'm"; "i am"; "I am"; "i'm"; "im"; "Im"; |]
let comments = R [|
	L "cool story"; 
	L "fuck me";
	L "fuck you";
	B[thats; L " wrong"];
	B[thats; L " not even wrong"];
	B[thats; L " so wrong"];
	B[thatsnot; L " correct"];
	B[thatsnot; L " right"];
	B[thats; L " incorrect"];
	B[thats; L " untrue"];
	B[thatsnot; L " true"];
	B[ewe; L " are wrong"];
	B[thats; L " never been true"];
	B[thathas; L " never been true"];
	B[thathasnt; L " ever been true"];
	B[ewe; L " have no evidence"];
	B[ewe; L " can't prove it"];
	B[ewe; L " can't prove that"];
	L "bored now";
	L "checkmate, atheists";
	L "i'm not really into pokemon";
	L "whatever";
	B[ O(L"how "); L"are "; ewe; O(L" even"); L" real" ];
	B[L"are "; ewe; O(L" even"); L" a person" ];
	B[L"are "; ewe; L" a bot" ];
	B[L"i think "; yore; O(L" actually"); O(L" just"); L" a bot"];
	L "you need jesus";
	L "you need Jesus";
	L "you need you some jesus";
	B[O(B[yore; L" "]); L"so edgy"];
	L "real edgy";
	B[thats; L" nice"];
	B[thats; O(L" so"); L" fake"];
	B[thats; L" cool"];
	B[L"good for "; ewe];
	B[O(L "watch out "); L "we got a";C[|" real ";"n "|]; L"edgelord here"];
	B[L "are "; ewe; C[|
		" okay";
		" alright";
		" well";
		" diseased";
		" sick";
		" ok";
		" OK";
	|]];
	B[L "do "; ewe; L" need help"];
	B[L "no "; ewe];
	B[O(L "it "); L"takes one to know one"];
	B[L"where do i even start"; O(B[L" with"; R[|ewe;L" this one"; L" this bullshit"|]])];
	B[im; L" not "; C[|"gonna";"going to"|]; C[|" repeat myself"; " say it again"|];];
	L"i won't repeat myself";
	L"i won't repeat myself again";
	L"i won't say it again";
	L"don't make me repeat myself";
	B[ewe; L" make me laugh"];
	B[ewe; L" are very funny"];
	B[ewe; L" should be a comedian"];
	B[yore; L" very funny"];
	B[yore; L" a terrible person"];
	B[yore; L" a terrible person, aren't "; ewe];
	B[yore; L" a terrible human being"];
	B[yore; L" a terrible excuse for human being, aren't "; ewe];
	B[O(L"and "); C[|"who";"what"|]; O(L" even"); L" are ";ewe;O(L" supposed to be")];
	B[L"delete ";yore;L" account"];
	B[L"who do ";ewe;L" think ";ewe;L" are";];
	B[L"what are ";ewe; O(L" even"); L" talking about"];
	B[ewe; L" mad"];
	L"umadbro";
	B[L"do "; ewe; O(L" actually"); O(L" even"); L" know what that word means"];
	L"blocked and reported";
	B[L"what are ";ewe; O(L" even"); C[|" on"; " smoking"|]];
	B[L"do ";ewe; O(L" even"); L" lift"];
	B[L"are ";ewe; O(L", like,"); L" high"; O(L" or something")];
	L"look who's Mad Online";
	B[L"are ";ewe; O(L" seriously"); L" Mad Online"; O(L " right now")];
	B[L"i like ";ewe];
	L"wait for it";
	B[ewe; L " still haven't answered my question"];
	B[yore; L " an idiot"];
	B[L "i will pray for "; ewe];
	L"let's do this";
	L"fight me irl";
	L"come at me";
	B[L"how can you ";ewe;
		C[| " say "; " think "; " believe " |];
		C[| "that"; "those things"; "such a thing";
		"something like that"; "things like that"; "lies"; "bullshit";|];
	];
	B[im; L" so sad for "; ewe];
	L"send nudes";
	L"jesus loves you";
	B[im; L" entitled to my opinion"];
	B[L "have "; ewe; L" even heard of the first amendment"];
	B[thats; L" called free speech"];
	L"a/s/l";
	B[L "do "; ewe; L" kik"];
	B[thats; L " hot"];
	B[ewe; L " have a conflict of interest"];
	B[L "why should i listen to "; ewe];
	B[yore; L " going to hell"];
	B[yore; L " going to go to hell"];
	B[theirs; L" a special place in hell for "; O(L"people like "); ewe];
	B[L"do "; ewe; O(L" even"); L" know who i am" ];
	B[L"it's like "; ewe; L" don't"; O(L" even"); L" know who i am" ];
	B[im; L" trying to remove it"];
	B[L "do "; ewe; L" need a safe space"];
	B[thats; L" just my opinion"];
	L"then what";
	L"seriously";
	B[L "how do "; ewe; L" know"; R[| L""; L" that"; B[L" "; thats; L " true";]|]];
	B[thats; L" circular reasoning"];
	L"https://yourlogicalfallacyis.com/bandwagon";
	L"https://yourlogicalfallacyis.com/appeal-to-authority";
	L"https://yourlogicalfallacyis.com/slippery-slope";
	L"https://yourlogicalfallacyis.com/strawman";
	L"https://yourlogicalfallacyis.com/ad-hominem";
	L"https://yourlogicalfallacyis.com/no-true-scotsman";
	L"https://yourlogicalfallacyis.com/personal-incredulity";
	L"https://yourlogicalfallacyis.com/begging-the-question";
	B[thats; L" a fallacy"];
	B[thats; L" incoherent"];
	B[thats; L" illogical"];
	B[thats; L" self-contradictory"];
	B[ewe; L" just said it wasn't"];
	B[ewe; L" just said that wasn't true"];
	B[L"now "; yore; L" just lying"];
	L"that makes no sense";
	L"what";
	L"wait back up";
	L"hold on";
	B[L"hold ";yore;L" horses"];
	B[yore; L" contradicting yourself"; O(L" again")];
	B[L "how old are "; ewe; O(L" really"); O(L" even")];
	B[O(L"i think "); yore; O(L" being"); L" intellectually dishonest"; O(L" again")];
	B[ewe; L " don't "; O(L"really "); O(L"even "); L"know what "; C[|"that word means";"those words mean";"words mean"|]; O(B[L", do ";ewe])];
	B[O(L"why do "); ewe; L" hate america"];
	B[O(L"someone "); L"alert the presses"];
	B[C[|"gravity";"evolution";"abortion";"atheism";"feminism";"misandry"|]; L" is "; O(L"still "); C[|"just";"only";"nothing but"|]; L" a theory";];
	B[yore; L" parents must be "; O(L"very "); C[|"proud of ";"ashamed of ";"angry at ";"sad for "|]; ewe];
	B[L"are "; ewe; L" being sarcastic"];
	B[L"are "; ewe; L" for real"];
	B[L"are "; ewe; L" actually serious"];
	B[L"no wonder "; ewe; L" don't have a girlfriend"];
	B[L"no wonder "; ewe; L" dont have a girlfriend"];
	B[L"no wonder "; ewe; L" haven't got a girlfriend"];
	B[L"can't "; ewe; C[|""; " people"; " all"; "ppl"|]; O(L " ever"); O(L " even"); O(L " just"); O(L " learn to"); L" take a joke"];
	B[L"can't take a joke can "; ewe];
	B[L"can't take a joke, can "; ewe];
	B[L"can't take a joke, can we"];
	B[yore; O(L " so"); L" mad"];
	B[im; O(L " so"); L" mad"];
	B[L"are ";ewe;L" projecting"];
	B[L"i think ";yore;L" projecting"];
	L"tits or gtfo";
	L"gtfo";
	B[thats; L" illegal"];
	B[thats; L" illegal"];
	B[thatsnot; L" legal"];
	B[thatsnot; L" lawful"];
	B[thats; L" problematic"; O(B[O(L","); L" for a couple reasons";]) ];
	L"so what";
	L"i don't care";
	L"i dont care";
	L"why should i care";
	B[
		R [|
			B[L"all "; yore; L" doing is"];
			B[yore; C[|"";" only";" just"|]];
		|];
		L" embarassing "; yore;
		R[|
			B[O(L " "); L "self"];
			B[O(L " own"); L " dumb ass"];
		|]
	];
	B[ewe; L" know i don't care, right"];
	B[L"i can't believe "; ewe; L" actually went there"];
	B[thats; L" a sin"];
	B[yore; L " sick"];
	L"time for some game theory";
	L"time 4 some game theory";
	B[
		O(B[O(L "maybe "); ewe; L"should "]); L"shut "; O(L"the fuck "); L "up";
		O(B[L" while "; C[|
			"other people ";
			"the adults ";
			"the grown-ups ";
			"smarter people ";
			"better people ";
			"the smart people ";
			|]; L"are talking";])
	];
	B[L"are "; ewe; L" always "; R[|
		B[L"this "; C[|
			"dense";
			"thick";
			"slow";
			"stupid";
			"annoying";
			"angry";
			"useless";
			"much of a cuck";
			"much of an asshole";
			"irritating";
			"irrational";
			"illogical";
			"dumb";
			"horny";
		|]];
		B[O(L"such "); C[|
			"a cuck";
			"a honkey";
			"a gringo";
			"a baby";
			"a pansy";
			"a loser";
			"an idiot";
			"an asshole";
			"a yokel";
			"a dumbfuck yokel";
			"an asshat";
			"a dumbfuck honkey";
			"a dumbfuck yokel asshat";
			"a piece of shit";
			"a turd";
			"a party-pooper";
			"a wanker";
			"a burden";
			"a hindrance";
			"an obstacle";
		|]];
	|]];
	B[ewe; L" have to tell me if "; yore; L" a bot"; O(B[O(punct); L" it's the law"])];
	L "this is america";
	B[thats; O(L" called"); L " a power move"];
	L "i can't even";
	L "i cant even";
	L "don't know, don't care";
	B[L "are "; ewe; L" "; O(L"actually "); O(L"just ");
		C[|"trying to"; "tryin to"; "tryna"|]; L" ";
		C[|"bore";"whine";"wheedle";"bitch";"cry"|]; L " me ";
		C[|"to death";"into submission"|]; O(L" or something")
	];
	B[C[|"its";"it's"|]; L" time for some game theory"];
|]

let insist = R[|
	B[ewe; L " need to"];
	L"try and";
	R[|
		L"do us a favor and";
		L"do us all a favor and";
		L"do us both a favor and";
		L"do everyone a favor and";
		L"do the world a favor and";
		L"do me a favor and";
		B[L "do "; yore; O(L " "); L "self a favor and"];
	|];
	L"try &";
	B[ewe; O(L" really"); L " gotta"];
	B[ewe; O(L" really"); L " should"];
	B[L "can "; ewe];
	B[L "why don't "; ewe];
	B[L "why dont "; ewe];
	B[L "y dont "; ewe];
	L "time to";
	B[L"time for ";ewe;L" to"];
	L "fuck you";
	L "fuck you,";
|]
let advs = O(O(C[|"";" already";" next time";" again";|]))
let insults = R[|
	commands;
	B[C[|"please "; "pls "; "plz "; ""|]; insist; L" "; quote poscmds; advs];
	B[insist; C[|" please "; " pls "; " plz "; " "|]; quote commands; advs];
	B[insist; L" "; quote poscmds; advs; C[|" please"; " pls"; " plz"; ""|];];
	B[
		C[|"pls 2 "; "lern2"|];
		quote poscmds;
	];
	B[O(B[ewe; L" "]); L"better "; quote poscmds;];
	B[O(B[ewe; L" "]); L"better not "; quote negcmds;];
	B[
		C[|"fine"; "okay"; "sure"; "whatever"; "w/e"; "k"; "ok"|]; O(punct); L " ";
		negcmds; O(punct);
		L " see if i care"; O(punct);
	]
|]
let rec realgrammar =  R [|
		B[starters; punct];
		B[starters; L ", "; quote dimin; punct];
		B[O(B[starters; L" ";]); insults; O(B[L ", "; quote dimin]); punct];
		B[O(B[starters; L" ";]); insults; O(B[L ", "; quote dimin]); punct];
		B[O(B[starters; L" ";]); insults; O(B[L ", "; quote dimin]); punct];
		B[O(B[interj; punct; L" ";]); quote comments; O(punct); O(B[L" ";closers])];
		(* extremely leftist voice *) B[
			O(B[starters; O(punct); L" "]);
			R[|
				B[L "have "; ewe; O(L" ever"); O(L" even"); L" read ";
					C[|"any ";"any ";"any ";"a single word of ";"";"";"";"";|];
					writers; O(L" at all")];
				B[
					C[|"i don't think"; "i don't believe"; "i doubt"; "doubt"; "really doubt"; "really gotta doubt"|];
					C[|" that ";" if "; " "|];
					ewe;
					O(L" have");
					O(L " even"); L" read "; C[|"any ";"any ";"any ";"a single word of ";"";"";"";"";|]; writers
				];
				B[L"maybe if ";ewe;C[|"";"'d";" had"|];L" read "; writers; L " you wouldn't be "; O(L"such "); F makeinsult;];
			|];
			O(B[O(L","); L" "; quote dimin]);
			O(punct);
		]
|]
let grammar = F (fun () -> match Random.int 32 with
	| 0 -> B[
		C[|
			"okay so (1/";
			"well first off (1/";
			"so (1/";
			"alright so (1/";
		|];
		F(fun () -> L(string_of_int ((Random.int 200)+53))); L")"];
	| 1 -> B[L"\""; realgrammar; L"\""];
	| 2 -> B[L"“"; realgrammar; L"”"];
	| 3 | 4 -> B[L"*"; yore;];
	| _ -> realgrammar);; (* this is horrific *)

let iter c fn = 
	let rec loop i = fn i; if i = c-1 then () else loop (i+1) in loop 0
let titcase x = 
	let len = String.length x in
	let buf = Bytes.of_string x in
	iter len (fun i ->
		if i = 0 then
			let c = Bytes.get buf (i) in
			if c <= 'z' && c >= 'a' then
				Bytes.set buf (i) (char_of_int ((int_of_char c)-32)) else ()
		else if i != len-1 && (Bytes.get buf i = ' ' || Bytes.get buf i = '*') then
			let c = Bytes.get buf (i+1) in
			if c <= 'z' && c >= 'a' then
				Bytes.set buf (i+1) (char_of_int ((int_of_char c)-32)) else ();
			else ();
	);
	Bytes.to_string buf;;
	
let randcap x = match Random.int 6 with
	| 0 -> String.uppercase_ascii x
	| 1 -> titcase x
	| _ -> x
let rec eval : node -> string = function
	| L(s) -> s
	| R(n) -> eval (pick n)
	| B(l) -> List.fold_left (fun x y -> x ^ (eval y)) "" l
	| C(a) -> pick a
	| O(n) -> if chance 2 then (eval n) else ""
	| F(f) -> eval (f ())
let () = Random.self_init ();
	print_string (randcap (eval grammar))
