Commit 06c75f4e authored by twanvl's avatar twanvl

added include support to script parser

parent 80f2d9e2
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <script/script.hpp> #include <script/script.hpp>
#include <script/parser.hpp> #include <script/parser.hpp>
#include <util/error.hpp> #include <util/error.hpp>
#include <util/io/package_manager.hpp> // for "include file" semi hack
#include <stack> #include <stack>
DECLARE_TYPEOF_COLLECTION(int); DECLARE_TYPEOF_COLLECTION(int);
...@@ -64,9 +65,16 @@ class TokenIterator { ...@@ -64,9 +65,16 @@ class TokenIterator {
private: private:
String input; String input;
size_t pos; size_t pos;
vector<Token> buffer; // buffer of unread tokens, front() = current 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 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? 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 /// Add a token to the buffer, with the current newline value, resets newline
void addToken(TokenType type, const String& value); void addToken(TokenType type, const String& value);
/// Read the next token, and add it to the buffer /// Read the next token, and add it to the buffer
...@@ -91,6 +99,7 @@ bool isLongOper(const String& s) { return s==_(":=") || s==_("==") || s==_("!=") ...@@ -91,6 +99,7 @@ bool isLongOper(const String& s) { return s==_(":=") || s==_("==") || s==_("!=")
TokenIterator::TokenIterator(const String& str) TokenIterator::TokenIterator(const String& str)
: input(str) : input(str)
, pos(0) , pos(0)
, newline(false)
{} {}
const Token& TokenIterator::peek(size_t offset) { const Token& TokenIterator::peek(size_t offset) {
...@@ -121,6 +130,12 @@ void TokenIterator::addToken(TokenType type, const String& value) { ...@@ -121,6 +130,12 @@ void TokenIterator::addToken(TokenType type, const String& value) {
void TokenIterator::readToken() { void TokenIterator::readToken() {
if (pos >= input.size()) { if (pos >= input.size()) {
// done with input, is there more?
if (!more.empty()) {
input = more.top().input;
pos = more.top().pos;
more.pop();
}
// EOF // EOF
addToken(TOK_EOF, _("end of input")); addToken(TOK_EOF, _("end of input"));
return; return;
...@@ -131,6 +146,24 @@ void TokenIterator::readToken() { ...@@ -131,6 +146,24 @@ void TokenIterator::readToken() {
newline = true; newline = true;
} else if (isSpace(c)) { } else if (isSpace(c)) {
// ignore // 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)) { } else if (isAlpha(c)) {
// name // name
size_t start = pos - 1; size_t start = pos - 1;
...@@ -209,6 +242,7 @@ void TokenIterator::readStringToken() { ...@@ -209,6 +242,7 @@ void TokenIterator::readStringToken() {
} }
} }
// ----------------------------------------------------------------------------- : Parsing // ----------------------------------------------------------------------------- : Parsing
/// Precedence levels for parsing, higher = tighter /// Precedence levels for parsing, higher = tighter
......
...@@ -108,8 +108,6 @@ String variableToString(unsigned int v); ...@@ -108,8 +108,6 @@ String variableToString(unsigned int v);
*/ */
class Script : public ScriptValue { class Script : public ScriptValue {
public: public:
/// Set the script to be executed
//void setScript(const String& script);
virtual ScriptType type() const; virtual ScriptType type() const;
virtual String typeName() const; virtual String typeName() const;
......
...@@ -87,14 +87,14 @@ String strip_last_word(const String& s) { ...@@ -87,14 +87,14 @@ String strip_last_word(const String& s) {
// ----------------------------------------------------------------------------- : Caseing // ----------------------------------------------------------------------------- : Caseing
/// Quick check to see if the substring starting at the given iterator is equal /// Quick check to see if the substring starting at the given iterator is equal to some given string
/// to some given string
bool is_substr(const String& s, String::iterator it, const Char* cmp) { bool is_substr(const String& s, String::iterator it, const Char* cmp) {
while (it != s.end() && *cmp != 0) { while (it != s.end() && *cmp != 0) {
if (*it++ != *cmp++) return false; if (*it++ != *cmp++) return false;
} }
return *cmp == 0; return *cmp == 0;
} }
String capitalize(const String& s) { String capitalize(const String& s) {
String result = s; String result = s;
bool afterSpace = true; bool afterSpace = true;
...@@ -142,14 +142,6 @@ String singular_form(const String& str) { ...@@ -142,14 +142,6 @@ String singular_form(const String& str) {
// ----------------------------------------------------------------------------- : Comparing / finding // ----------------------------------------------------------------------------- : 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 smart_less(const String& as, const String& bs) {
bool in_num = false; // are we inside a number? bool in_num = false; // are we inside a number?
bool lt = false; // is as less than bs? bool lt = false; // is as less than bs?
...@@ -187,4 +179,19 @@ bool smart_less(const String& as, const String& bs) { ...@@ -187,4 +179,19 @@ bool smart_less(const String& as, const String& bs) {
} else { } else {
return lt; 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&); ...@@ -121,7 +121,11 @@ String singular_form(const String&);
bool smart_less(const String&, const String&); bool smart_less(const String&, const String&);
/// Return whether str starts with start /// Return whether str starts with start
/** starts_with(a,b) == is_substr(a,0,b) */
bool starts_with(const String& str, const String& start); 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 // ----------------------------------------------------------------------------- : EOF
#endif #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