Commit 06c75f4e authored by twanvl's avatar twanvl

added include support to script parser

parent 80f2d9e2
......@@ -9,6 +9,7 @@
#include <script/script.hpp>
#include <script/parser.hpp>
#include <util/error.hpp>
#include <util/io/package_manager.hpp> // for "include file" semi hack
#include <stack>
DECLARE_TYPEOF_COLLECTION(int);
......@@ -64,9 +65,16 @@ class TokenIterator {
private:
String input;
size_t pos;
vector<Token> buffer; // buffer of unread tokens, front() = current
stack<bool> open_braces; // braces we entered, true if the brace was from a smart string escape
bool newline; ///< Did we just pass a newline?
vector<Token> buffer; ///< buffer of unread tokens, front() = current
stack<bool> open_braces; ///< braces we entered, true if the brace was from a smart string escape
bool newline; ///< Did we just pass a newline?
// more input?
struct MoreInput {
String input;
size_t pos;
};
stack<MoreInput> more; ///< Read tokens from here when we are done with the current input
/// Add a token to the buffer, with the current newline value, resets newline
void addToken(TokenType type, const String& value);
/// Read the next token, and add it to the buffer
......@@ -91,6 +99,7 @@ bool isLongOper(const String& s) { return s==_(":=") || s==_("==") || s==_("!=")
TokenIterator::TokenIterator(const String& str)
: input(str)
, pos(0)
, newline(false)
{}
const Token& TokenIterator::peek(size_t offset) {
......@@ -121,6 +130,12 @@ void TokenIterator::addToken(TokenType type, const String& value) {
void TokenIterator::readToken() {
if (pos >= input.size()) {
// done with input, is there more?
if (!more.empty()) {
input = more.top().input;
pos = more.top().pos;
more.pop();
}
// EOF
addToken(TOK_EOF, _("end of input"));
return;
......@@ -131,6 +146,24 @@ void TokenIterator::readToken() {
newline = true;
} else if (isSpace(c)) {
// ignore
} else if (is_substr(input, pos-1, _("include file:"))) {
// include a file
// HACK: This is not really the right place for it, but it's the best I've got
// filename
pos += 12; // "nclude file:"
size_t eol = input.find_first_of(_("\r\n"), pos);
if (eol == String::npos) eol = input.size();
String filename = trim(input.substr(pos, eol - pos));
// store the current input for later retrieval
MoreInput m = {input, eol};
more.push(m);
// open file
InputStreamP is = packages.openFileFromPackage(filename);
wxTextInputStream tis(*is);
// read the entire file, and start at the beginning of it
pos = 0;
input.clear();
while (!is->Eof()) input += tis.ReadLine() + _('\n');
} else if (isAlpha(c)) {
// name
size_t start = pos - 1;
......@@ -209,6 +242,7 @@ void TokenIterator::readStringToken() {
}
}
// ----------------------------------------------------------------------------- : Parsing
/// Precedence levels for parsing, higher = tighter
......
......@@ -108,8 +108,6 @@ String variableToString(unsigned int v);
*/
class Script : public ScriptValue {
public:
/// Set the script to be executed
//void setScript(const String& script);
virtual ScriptType type() const;
virtual String typeName() const;
......
......@@ -87,14 +87,14 @@ String strip_last_word(const String& s) {
// ----------------------------------------------------------------------------- : Caseing
/// Quick check to see if the substring starting at the given iterator is equal
/// to some given string
/// Quick check to see if the substring starting at the given iterator is equal to some given string
bool is_substr(const String& s, String::iterator it, const Char* cmp) {
while (it != s.end() && *cmp != 0) {
if (*it++ != *cmp++) return false;
}
return *cmp == 0;
}
String capitalize(const String& s) {
String result = s;
bool afterSpace = true;
......@@ -142,14 +142,6 @@ String singular_form(const String& str) {
// ----------------------------------------------------------------------------- : Comparing / finding
bool starts_with(const String& str, const String& start) {
if (str.size() < start.size()) return false;
FOR_EACH_2_CONST(a, str, b, start) {
if (a != b) return false;
}
return true;
}
bool smart_less(const String& as, const String& bs) {
bool in_num = false; // are we inside a number?
bool lt = false; // is as less than bs?
......@@ -187,4 +179,19 @@ bool smart_less(const String& as, const String& bs) {
} else {
return lt;
}
}
\ No newline at end of file
}
bool starts_with(const String& str, const String& start) {
if (str.size() < start.size()) return false;
FOR_EACH_2_CONST(a, str, b, start) {
if (a != b) return false;
}
return true;
}
bool is_substr(const String& str, size_t pos, const Char* cmp) {
for (String::const_iterator it = str.begin() + pos ; *cmp && it < str.end() ; ++cmp, ++it) {
if (*cmp != *it) return false;
}
return *cmp == _('\0');
}
......@@ -121,7 +121,11 @@ String singular_form(const String&);
bool smart_less(const String&, const String&);
/// Return whether str starts with start
/** starts_with(a,b) == is_substr(a,0,b) */
bool starts_with(const String& str, const String& start);
/// Return whether str contains the string cmp at position pos
bool is_substr(const String& str, size_t pos, const Char* cmp);
// ----------------------------------------------------------------------------- : EOF
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment