diff options
author | tomsmeding <hallo@tomsmeding.nl> | 2015-09-08 20:40:20 +0200 |
---|---|---|
committer | tomsmeding <hallo@tomsmeding.nl> | 2015-09-08 20:40:20 +0200 |
commit | ed0409a2a7450905bdc70015ffe537171684dddf (patch) | |
tree | 6dd646a0df24cd42c09ca87384e9b0451facfa1c | |
parent | 1202b08cb45e79ee640b596304b003f046b292b1 (diff) |
@includeonce :tada:
-rw-r--r-- | runtime.cpp | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/runtime.cpp b/runtime.cpp index 3cf607d..03c87b4 100644 --- a/runtime.cpp +++ b/runtime.cpp @@ -2,6 +2,7 @@ #include <vector> #include <string> #include <unordered_map> +#include <unordered_set> #include <functional> #include <cstring> @@ -232,7 +233,9 @@ void run(vector<string> T){ unordered_map<string,Stackitem> variables; unordered_map<unsigned int,unsigned int> jumpmap; vector<Stackitem> S; + unordered_set<string> includeonces; unsigned int cursor=0; + bool skipincluding; //first pass, handle functions and includes while(cursor<T.size()){ const string &word=T[cursor]; @@ -256,21 +259,34 @@ void run(vector<string> T){ if(depth==0)break; } if(depth!=0)throw string("Non-terminated @defun statement at end of file"); + auto it=functions.find(name); + if(it!=functions.end()){ + throw string("Re-definition of function '"+name+"'!"); + } vector<string> &functoks=functions[name].first; functoks.resize(end-start); for(unsigned int i=start;i<end;i++)functoks[i-start]=move(T[i]); T.erase(T.begin()+cursor,T.begin()+end+1); - } else if(word=="@include"){ + } else if(word=="@include"||word=="@includeonce"){ if(cursor+1>=T.size())throw string("Unterminated @include statement at end of file"); string name=T[cursor+1]; if(name[0]!='\'')throw string("@include expected a string as file, but got '")+name+"'"; name.erase(0,1); - ifstream file(name); - if(!file)throw string("Could not open file '")+name+"' specified by @include statement"; - vector<string> included=tokenise(file); - file.close(); + skipincluding=false; + if(word=="@includeonce"){ + if(includeonces.find(name)==includeonces.end()) + includeonces.insert(name); + else + skipincluding=true; + } T.erase(T.begin()+cursor,T.begin()+cursor+2); - T.insert(T.begin()+cursor,included.begin(),included.end()); + if(!skipincluding){ + ifstream file(name); + if(!file)throw "Could not open file '"+name+"' specified by "+word+" statement"; + vector<string> included=tokenise(file); + file.close(); + T.insert(T.begin()+cursor,included.begin(),included.end()); + } } else { cursor++; } |