We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

Meow (None1)

From Esolang
Jump to navigation Jump to search

Meow (the name has nothing to do with the language, except for the comments) is the one and only pre-2023 esolang (which was invented on Oct. 31st, 2022) invented by User:None1 and developed in 7 months. The author's aim was not to write an esolang but a normal language, but it has been more and more esoteric that it became an esolang.

Virtual Machine

Meow runs on a virtual machine which consists of:

  • Memory: A map that maps variables to there values (Yes, Meow doesn't use addresses at all!). All variables are long doubles.
  • A call stack.
  • An argument queue that's used to pass arguments to functions.

Commands

Meow is an assembly-like esolang that allows comments, functions variables, libraries and do-while loops. Invalid commands are ignored.

It also has a REPL.

Arithmetic

Meow supports: add, sub, mul, div and mod. The syntax is:

op val1 val2 var

Which does the operator op with the operands val1 and val2. Then, store the result in the variable var.

Variable management

del var

deletes the variable var.

I/O

Meow has a lot of commands for I/O:

read var

Reads an integer into var.

out val

Output the value val as integer.

readc/scanc var

Reads a character and stores the result into var. The difference between readc and scanc is that readc "eats" the trailing line feed but scanc doesn't.

outc val

Output the value val as ASCII.

prtstr string

Prints the string.

ctrl string

Prints \e[string (where \e is the escape character with an ASCII value of 27). It's useful for special effects. For example, ctrl 34m turns the text blue.

All output commands print without trailing whitespace.

Comments

meow comment

Single line comments.

Control flow

exit

Exits the program.

Conditionals

condition
CODE
end

If condition, do CODE. Valid conditions are:

equal/big/small val1 val2

which check if val1 is equal to, greater than, less than val2 respectively.

Loops

Meow doesn't really have loops. The do-while loop is actually implemented internally with functions, so use functions for more complex control flow.

The do-while loop is like:

do
CODE
while condition

The format of condition is the same as that of conditionals.

Functions

Functions are the main source of control flow in Meow.

func funcname
CODE
endf

Defines a function that executes CODE.

run funcname

Calls the function.

Argument/return value manipulation
addarg val

Pushes val into the argument queue.

poparg var

Pops the argument queue and stores the value popped in var.

addret val

Sets the return value to val.

popret var

Sets var to return value.

The argument queue is not cleared automatically, so arguments not popped by current call will remain there until another function call pops them, which may cause weird behavior.

Standard libraries

Please refer to Meow/libs for more information about the standard libraries.

To do: Finish this.

Examples

Hello World

prtstr Hello, World!

Power

read arg1
read arg2
library math
run fpow
out ret

Truth Machine

read a
do
out a
while equal a 1

Interpreter

The original interpreter, in C++, is as follows:

#include<cstdio>
#include<map>
#include<string>
#include<iostream>
#include<fstream>
#include<cstdlib>
#include<stack>
#include<vector>
#include<ctime>
#include<csignal>
#include<queue>
using namespace std;
stack<int> cond;
map<string,long double> mp;
int argvn,numof1;
char cd[1000000],cc[1000000],z[1000000],x[1000000],y[1000000];
string dc,curf,mg;
map<string,vector<string> > mp2;
bool isf=0;
ifstream*jjn;
typedef struct ufrg{
	int curcode;
	string name;
}cstp;
stack<cstp> cs;
queue<long double> args;
long double retpp;
void inp2();
void inp3();
long double md(long double a,long double b){
	bool bb=0;
	if(a<0) bb=1;
	if(a<0) a=-a;
	if(b<0) b=-b;
	long double tmp=b,res=0;
	while(b<=a) b*=2;
	if(b-tmp>=-1e-15&&b-tmp<=1e-15) res=a;
	else{
		while(b>=tmp){
			if(b<=a){
			a-=b;	
		}b/=2;
		}
	}
	if(bb) a=tmp-a;
	return a; 
}
long double calc(long double a,long double b,string op){
	if(op=="add") return a+b;
	else if(op=="sub") return a-b;
	else if(op=="mul") return a*b;
	else if(op=="div") return a/b;
	else if(op=="mod") return md(a,b);
	else return 0;
}
char est(long double d){
	long double e=d-int(d);
	if(e<-(1e-10)) e=-e;
	if(e>=0.5) return char(d-e+1);
	else return char(d-e);
}
void ig(int num){
	signal(SIGINT,ig);
}
void inp(){
	sprintf(cd,"%s",dc.c_str());
	sscanf(cd,"%s",cc);
	string f(cc);
	if(f=="end"&&!cond.empty()){
		if(cond.top()) numof1--;
		cond.pop();
	}
	else if(f=="add"||f=="sub"||f=="mul"||f=="div"||f=="mod"){
		sscanf(cd,"%*s%s%s%s",x,y,z);
		long double a,b;
		if((x[0]>='0'&&x[0]<='9')||x[0]=='-'||x[0]=='.'||x[0]=='+') sscanf(x,"%Lf",&a);
		else a=mp[string(x)];
		if((y[0]>='0'&&y[0]<='9')||y[0]=='-'||y[0]=='.'||y[0]=='+') sscanf(y,"%Lf",&b);
		else b=mp[string(y)];
		long double res=calc(a,b,f);
		mp[string(z)]=res;
	}
	else if(f=="del"){
		sscanf(cd,"%*s%s",x);
		if(mp.find(string(x))!=mp.end()) mp.erase(mp.find(string(x)));
	}
	else if(f=="out"){
		sscanf(cd,"%*s%s",x);
		long double a; 
		if((x[0]>='0'&&x[0]<='9')||x[0]=='-'||x[0]=='.'||x[0]=='+') sscanf(x,"%Lf",&a);
		else a=mp[string(x)];
		printf("%.15Lg",a);
	}
	else if(f=="outc"){
		sscanf(cd,"%*s%s",x);
		long double a;
		if((x[0]>='0'&&x[0]<='9')||x[0]=='-'||x[0]=='.'||x[0]=='+') sscanf(x,"%Lf",&a);
		else a=mp[string(x)];
		printf("%c",est(a));
	}
	else if(f=="read"){
		sscanf(cd,"%*s%s",x);
		long double d;
		scanf("%Lf%*c",&d);
		mp[string(x)]=d;
	}
	else if(f=="readc"){
		sscanf(cd,"%*s%s",x);
		char d;
		scanf("%c%*c",&d);
		mp[string(x)]=d;
	}
	else if(f=="scanc"){
		sscanf(cd,"%*s%s",x);
		char d;
		scanf("%c",&d);
		mp[string(x)]=d;
	}
	else if(f=="equal"){
		sscanf(cd,"%*s%s%s",x,y);
		long double a,b;
		if((x[0]>='0'&&x[0]<='9')||x[0]=='-'||x[0]=='.'||x[0]=='+') sscanf(x,"%Lf",&a);
		else a=mp[string(x)];
		if((y[0]>='0'&&y[0]<='9')||y[0]=='-'||y[0]=='.'||y[0]=='+') sscanf(y,"%Lf",&b);
		else b=mp[string(y)];
		if(a-b<=1e-15&&a-b>=-(1e-15)){
			cond.push(1);numof1++;
		}else{
			cond.push(0);
		}
	}
	else if(f=="big"){
		sscanf(cd,"%*s%s%s",x,y);
		long double a,b;
		if((x[0]>='0'&&x[0]<='9')||x[0]=='-'||x[0]=='.'||x[0]=='+') sscanf(x,"%Lf",&a);
		else a=mp[string(x)];
		if((y[0]>='0'&&y[0]<='9')||y[0]=='-'||y[0]=='.'||y[0]=='+') sscanf(y,"%Lf",&b);
		else b=mp[string(y)];
		if(a-b>1e-15){
			cond.push(1);numof1++;
		}else{
			cond.push(0);
		}
	}
	else if(f=="small"){
		sscanf(cd,"%*s%s%s",x,y);
		long double a,b;
		if((x[0]>='0'&&x[0]<='9')||x[0]=='-'||x[0]=='.'||x[0]=='+') sscanf(x,"%Lf",&a);
		else a=mp[string(x)];
		if((y[0]>='0'&&y[0]<='9')||y[0]=='-'||y[0]=='.'||y[0]=='+') sscanf(y,"%Lf",&b);
		else b=mp[string(y)];
		if(a-b<-(1e-15)){
			cond.push(1);numof1++;
		}else{
			cond.push(0);
		}
	}else if(f=="meow") ;
	else if(f=="exit") exit(0);
	else if(f=="library"){
		sscanf(cd,"%*s%s",x);
		sprintf(x,"%s.meow",x);
		ifstream fg(x);
		if(!fg){
			sprintf(y,"C:\\meow\\%s",x);
			ifstream uv(y);
			if(!uv) return;
			while(!uv.eof()){
				if(!cs.empty()){
				cstp CSTP=cs.top();
				if(CSTP.curcode==mp2[CSTP.name].size()) cs.pop();
				else{
					dc=mp2[CSTP.name][CSTP.curcode];
					CSTP.curcode++;
					cs.pop();
					cs.push(CSTP);
					if(isf){
						vector<string> sv=mp2[curf];
						sv.push_back(dc);
						mp2[curf]=sv;
						inp3();
					}else{
						if(numof1==cond.size()-1) inp();
						else inp2();
					}
				}
				continue;
			}
				getline(uv,dc);
				if(isf){
				vector<string> sv=mp2[curf];
				sv.push_back(dc);
				mp2[curf]=sv;
				inp3();
			}else{
				if(numof1==cond.size()-1) inp();
				else inp2();
			}
			}
			uv.close();
		}
		else{
			while(!fg.eof()){
				if(!cs.empty()){
				cstp CSTP=cs.top();
				if(CSTP.curcode==mp2[CSTP.name].size()) cs.pop();
				else{
					dc=mp2[CSTP.name][CSTP.curcode];
					CSTP.curcode++;
					cs.pop();
					cs.push(CSTP);
					if(isf){
						vector<string> sv=mp2[curf];
						sv.push_back(dc);
						mp2[curf]=sv;
						inp3();
					}else{
						if(numof1==cond.size()-1) inp();
						else inp2();
					}
				}
				continue;
			}
				getline(fg,dc);
				if(isf){
				vector<string> sv=mp2[curf];
				sv.push_back(dc);
				mp2[curf]=sv;
				inp3();
			}else{
				if(numof1==cond.size()-1) inp();
				else inp2();
			}
			}	
		}
		fg.close();
	}
	else if(f=="func"){
		sscanf(cd,"%*s%s",x);
		curf=string(x);
		mp2[string(x)]=vector<string>();
		isf=1;
	}else if(f=="run"){
		sscanf(cd,"%*s%s",x);
		if(string(x)=="clock"){
			retpp=clock();
		}
		else{
			cstp CSTP;
			CSTP.curcode=0;
			CSTP.name=string(x);
			cs.push(CSTP);
		}
	}else if(f=="refa"){
		sscanf(cd,"%*s%s%s%s",x,y,z);
		long double yfu;
		if((y[0]>='0'&&y[0]<='9')||y[0]=='-'||y[0]=='.'||y[0]=='+') sscanf(y,"%Lf",&yfu);
		else yfu=mp[string(y)];
		sprintf(x,"%s %.0Lg",x,yfu);
		mp[string(z)]=mp[string(x)];
	}else if(f=="edita"){
		sscanf(cd,"%*s%s%s%s",x,y,z);
		long double yfu;
		if((y[0]>='0'&&y[0]<='9')||y[0]=='-'||y[0]=='.'||y[0]=='+') sscanf(y,"%Lf",&yfu);
		else yfu=mp[string(y)];
		sprintf(x,"%s %.0Lg",x,yfu);
		long double rrr;
		if((z[0]>='0'&&z[0]<='9')||z[0]=='-'||z[0]=='.'||z[0]=='+') sscanf(z,"%Lf",&rrr);
		else rrr=mp[string(z)];
		mp[string(x)]=rrr;
	}else if(f=="dela"){
		sscanf(cd,"%*s%s%s",x,y);
		long double yfu;
		if((y[0]>='0'&&y[0]<='9')||y[0]=='-'||y[0]=='.'||y[0]=='+') sscanf(y,"%Lf",&yfu);
		else yfu=mp[string(y)];
		sprintf(x,"%s %.0Lg",x,yfu);
		if(mp.find(string(x))!=mp.end()) mp.erase(mp.find(string(x)));
	}else if(f=="nocc"){
		signal(SIGINT,ig);
	}else if(f=="addarg"){
		sscanf(cd,"%*s%s",x);
		long double a;
		if((x[0]>='0'&&x[0]<='9')||x[0]=='-'||x[0]=='.'||x[0]=='+') sscanf(x,"%Lf",&a);
		else a=mp[string(x)];
		args.push(a);
	}
	else if(f=="poparg"){
		if(!args.empty()){
			sscanf(cd,"%*s%s",x);
			mp[string(x)]=args.front();
			args.pop();
		}
	}else if(f=="addret"){
		sscanf(cd,"%*s%s",x);
		long double a;
		if((x[0]>='0'&&x[0]<='9')||x[0]=='-'||x[0]=='.'||x[0]=='+') sscanf(x,"%Lf",&a);
		else a=mp[string(x)];
		retpp=a;
	}else if(f=="popret"){
		sscanf(cd,"%*s%s",x);
		mp[string(x)]=retpp;
	}else if(f=="ctrl"){
		sscanf(cd,"%*s%s",x);
		printf("\e[%s",x);
	}else if(f=="clr"){
		system("cls");
	}else if(f=="prtstr"){
		printf("%s",cd+7);
	}else if(f=="do"){
		mp2[mg+="_"]=vector<string>();
		string j;
		do{
			if(argvn>1){
				getline(*jjn,j);
			}else{
				putchar('>');
				getline(cin,j);
			}
			mp2[mg].push_back(j);
		}while(j.substr(0,5)!="while");
		mp2[mg].push_back(string(j.c_str()+5));
		mp2[mg].push_back("run "+mg);
		mp2[mg].push_back("end");
		cstp CSTP;
		CSTP.curcode=0;
		CSTP.name=mg;
		cs.push(CSTP);
	}
}
void inp2(){
	sprintf(cd,"%s",dc.c_str());
	sscanf(cd,"%s",cc);
	string f(cc);
	if(f=="end"&&!cond.empty()){
		if(cond.top()) numof1--;
		cond.pop();
	}
	
	
	else if(f=="big"){
		sscanf(cd,"%*s%s%s",x,y);
		long double a,b;
		if((x[0]>='0'&&x[0]<='9')||x[0]=='-'||x[0]=='.'||x[0]=='+') sscanf(x,"%Lf",&a);
		else a=mp[string(x)];
		if((y[0]>='0'&&y[0]<='9')||y[0]=='-'||y[0]=='.'||y[0]=='+') sscanf(y,"%Lf",&b);
		else b=mp[string(y)];
		if(a-b>1e-10){
			cond.push(1);
			numof1++;
		}else{
			cond.push(0);
		}
	}
	else if(f=="small"){
		sscanf(cd,"%*s%s%s",x,y);
		long double a,b;
		if((x[0]>='0'&&x[0]<='9')||x[0]=='-'||x[0]=='.'||x[0]=='+') sscanf(x,"%Lf",&a);
		else a=mp[string(x)];
		if((y[0]>='0'&&y[0]<='9')||y[0]=='-'||y[0]=='.'||y[0]=='+') sscanf(y,"%Lf",&b);
		else b=mp[string(y)];
		if(a-b<-(1e-10)){
			cond.push(1);
			numof1++;
		}else{
			cond.push(0);
		}
	}else if(f=="meow") ;
	else if(f=="exit") exit(0);
}
void inp3(){
	sprintf(cd,"%s",dc.c_str());
	sscanf(cd,"%s",cc);
	string f(cc);
	if(f=="endf"){
		mp2[curf].pop_back();
		isf=0;
	}
}
int main(int argc,char *argv[]){
	mp["SYST"]=time(0)%86400;
	mp["SYSD"]=time(0)/86400;
	cond.push(1);
	argvn=argc;
	if(argc<=1){
		while(1){
			if(!cs.empty()){
				cstp CSTP=cs.top();
				if(CSTP.curcode==mp2[CSTP.name].size()) cs.pop();
				else{
					dc=mp2[CSTP.name][CSTP.curcode];
					CSTP.curcode++;
					cs.pop();
					cs.push(CSTP);
					if(isf){
						vector<string> sv=mp2[curf];
						sv.push_back(dc);
						mp2[curf]=sv;
						inp3();
					}else{
						if(numof1==cond.size()-1) inp();
						else inp2();
					}
				}
				continue;
			}
			printf(">");
			getline(cin,dc);
			if(isf){
				vector<string> sv=mp2[curf];
				sv.push_back(dc);
				mp2[curf]=sv;
				inp3();
			}else{
				if(numof1==cond.size()-1) inp();
				else inp2();
			}
		}
	}else{
		ifstream fi(argv[1]);
		jjn=&fi;
		if(!fi){
			printf("Error:file not found");
			return 0;
		}
		while(!fi.eof()||!cs.empty()){
			if(!cs.empty()){
				cstp CSTP=cs.top();
				if(CSTP.curcode==mp2[CSTP.name].size()) cs.pop();
				else{
					dc=mp2[CSTP.name][CSTP.curcode];
					CSTP.curcode++;
					cs.pop();
					cs.push(CSTP);
					if(isf){
						vector<string> sv=mp2[curf];
						sv.push_back(dc);
						mp2[curf]=sv;
						inp3();
					}else{
						if(numof1==cond.size()-1) inp();
						else inp2();
					}
				}
				continue;
			}
			getline(fi,dc);
			if(isf){
				vector<string>&sv=mp2[curf];
				sv.push_back(dc);
				inp3();
			}else{
				if(numof1==cond.size()-1) inp();
				else inp2();
			}
		}
	}
	return 0;
}