diff options
| author | tomsmeding <hallo@tomsmeding.nl> | 2015-08-22 09:59:42 +0200 | 
|---|---|---|
| committer | tomsmeding <hallo@tomsmeding.nl> | 2015-08-22 10:00:38 +0200 | 
| commit | 28a403355894f378c87c01043365b85b69737546 (patch) | |
| tree | 7488d319624de749cceabb0bf7ec0212e610603d | |
| parent | 37173a7008807f133c92d64109b079ec209a34a2 (diff) | |
More IO and bug fixes
| -rw-r--r-- | postrun.cpp | 94 | 
1 files changed, 80 insertions, 14 deletions
diff --git a/postrun.cpp b/postrun.cpp index 916c65c..78998cf 100644 --- a/postrun.cpp +++ b/postrun.cpp @@ -7,6 +7,8 @@  #include <cstdlib>  #include <cstring>  #include <cmath> +#include <unistd.h> +#include <fcntl.h>  using namespace std; @@ -14,6 +16,9 @@ inline bool isword(char c){return isalpha(c)||c=='_'||c=='@'||c=='$';}  inline bool isextword(char c){return isword(c)||isdigit(c);}  inline bool isoperator(char c){return (bool)strchr("+-*/=><!%^{}",c);} +int g_argc; +char **g_argv; +  vector<string> tokenise(istream &stream){  	vector<string> tokens;  	string token; @@ -22,7 +27,7 @@ vector<string> tokenise(istream &stream){  	while(true){  		c=stream.get();  		if(!stream)break; -		if(c=='#'){ +		while(c=='#'){  			while((c=stream.get())!='\n'&&stream);  			c=stream.get();  			if(!stream)break; @@ -221,8 +226,79 @@ const unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string  		else cout<<v.intval<<flush;  	}},  	{"lf",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ +		BUILTIN_GUARD_STACKSIZE("lf",0)  		cout<<endl;  	}}, +	{"getline",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ +		BUILTIN_GUARD_STACKSIZE("getline",0) +		string line; +		getline(cin,line); +		if(!cin)S.emplace_back(-1); +		else S.emplace_back(line); +	}}, +	{"getc",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ +		BUILTIN_GUARD_STACKSIZE("getc",0) +		char c=cin.get(); +		if(!cin)S.emplace_back(-1); +		else S.emplace_back(string(1,c)); +	}}, +	{"fprint",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ +		BUILTIN_GUARD_STACKSIZE("fprint",2) +		Stackitem file=move(S.back()); S.pop_back(); +		Stackitem v=move(S.back()); S.pop_back(); +		if(file.isstr)throw string("Second argument to 'fprint' not a number"); +		if(v.isstr)write(file.intval,v.strval.data(),v.strval.size()); +		else { +			string s=to_string(v.intval); +			write(file.intval,s.data(),s.size()); +		} +	}}, +	{"flf",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ +		BUILTIN_GUARD_STACKSIZE("flf",1) +		Stackitem file=move(S.back()); S.pop_back(); +		if(file.isstr)throw string("Argument to 'flf' not a number"); +		write(file.intval,"\n",1); +	}}, +	{"fgetc",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ +		BUILTIN_GUARD_STACKSIZE("fgetc",1) +		Stackitem file=move(S.back()); S.pop_back(); +		if(file.isstr)throw string("Argument to 'fgetc' not a number"); +		char c; +		int ret=read(file.intval,&c,1); +		if(ret==-1)perror("read"); +		if(ret<=0)S.emplace_back(-1); +		else S.emplace_back(string(1,c)); +	}}, +	{"fopen",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ +		BUILTIN_GUARD_STACKSIZE("fopen",2) +		Stackitem mode=move(S.back()); S.pop_back(); +		Stackitem fname=move(S.back()); S.pop_back(); +		if(!fname.isstr)throw string("First argument to 'fopen' not a string"); +		if(!mode.isstr)throw string("Second argument to 'fopen' not a string"); +		int oflag=0; +		if(mode.strval.find('r')!=string::npos)oflag|=O_RDONLY; +		if(mode.strval.find('w')!=string::npos){ +			if(oflag&O_RDONLY)oflag=(oflag&~O_RDONLY)|O_RDWR; +			else oflag|=O_WRONLY; +		} +		if(mode.strval.find('a')!=string::npos)oflag|=O_APPEND; +		if(mode.strval.find('x')!=string::npos)oflag|=O_EXCL|O_CREAT; +		if(oflag==0)oflag=O_RDONLY; +		int ret=open(fname.strval.c_str(),oflag); +		if(ret<0)perror("open"); +		S.emplace_back(ret); +	}}, +	{"argc",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ +		BUILTIN_GUARD_STACKSIZE("argc",0) +		S.emplace_back(g_argc); +	}}, +	{"argvget",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ +		BUILTIN_GUARD_STACKSIZE("argvget",1) +		Stackitem idx=move(S.back()); S.pop_back(); +		if(idx.isstr)throw string("Argument to 'argvget' not a number"); +		if(idx.intval<0||idx.intval>=g_argc)throw string("Argument to 'argvget' out of bounds"); +		S.emplace_back(g_argv[idx.intval]); +	}},  	{"dup",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){  		BUILTIN_GUARD_STACKSIZE("dup",1)  		S.push_back(S.back()); @@ -328,18 +404,6 @@ const unordered_map<string,function<void(vector<Stackitem>&,unordered_map<string  		S.back().intval=(int)S.back().strval[0];  		S.back().strval="";  	}}, -	{"getline",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ -		BUILTIN_GUARD_STACKSIZE("getline",0) -		string line; -		getline(cin,line); -		if(!cin)S.emplace_back(-1); -		else S.emplace_back(line); -	}}, -	{"getc",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){ -		BUILTIN_GUARD_STACKSIZE("getc",0) -		if(!cin)S.emplace_back(-1); -		else S.emplace_back(string(1,cin.get())); -	}},  	{"stackdump",[](vector<Stackitem> &S,unordered_map<string,Stackitem> &variables){  		BUILTIN_GUARD_STACKSIZE("stackdump",0)  		cerr<<"STACKDUMP: "; @@ -532,10 +596,12 @@ void run(vector<string> T){  }  int main(int argc,char **argv){ -	if(argc!=2){ +	if(argc<2){  		cerr<<"Call this interpreter with the Postrun source file"<<endl;  		return 1;  	} +	g_argc=argc-2; +	g_argv=argv+2; //skip this executable and the postrun file  	ifstream srcf(argv[1]);  	if(!srcf){  		cerr<<"Could not open file '"<<argv[1]<<"'"<<endl;  | 
