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; |