summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <hallo@tomsmeding.nl>2015-09-08 20:40:20 +0200
committertomsmeding <hallo@tomsmeding.nl>2015-09-08 20:40:20 +0200
commited0409a2a7450905bdc70015ffe537171684dddf (patch)
tree6dd646a0df24cd42c09ca87384e9b0451facfa1c
parent1202b08cb45e79ee640b596304b003f046b292b1 (diff)
@includeonce :tada:
-rw-r--r--runtime.cpp28
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++;
}