incomplete match
This commit is contained in:
parent
13b14f4002
commit
87b9471735
7 changed files with 94 additions and 23 deletions
|
@ -52,4 +52,4 @@ namespace NVL {
|
||||||
return env.find(name) != env.end();
|
return env.find(name) != env.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,4 +31,4 @@ namespace NVL {
|
||||||
bool exists(const std::string& name);
|
bool exists(const std::string& name);
|
||||||
};
|
};
|
||||||
extern Environment ENVIRONMENT;
|
extern Environment ENVIRONMENT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
#include "Parser.h"
|
#include "Parser.h"
|
||||||
#include "Environment.h"
|
#include "Environment.h"
|
||||||
#include <functional>
|
|
||||||
#include <any>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
auto f = [](NVL::Variable) { return NVL::Variable(NVL::Type::Nil); };
|
NVL::Variable v([](NVL::Variable) { return NVL::Variable(NVL::Type::Nil); }, 1);
|
||||||
NVL::Variable v(f, 1);
|
|
||||||
|
|
||||||
NVL::ENVIRONMENT.enter("hello", v);
|
NVL::ENVIRONMENT.enter("hello", v);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace {
|
||||||
struct Match {
|
struct Match {
|
||||||
std::string accept;
|
std::string accept;
|
||||||
|
|
||||||
constexpr operator char() const {
|
operator char() const {
|
||||||
return accept[0];
|
return accept[0];
|
||||||
}
|
}
|
||||||
bool operator== (const std::string& other) const {
|
bool operator== (const std::string& other) const {
|
||||||
|
@ -36,7 +36,7 @@ namespace {
|
||||||
|
|
||||||
const ParseGroup NUMERIC = { "1234567890" };
|
const ParseGroup NUMERIC = { "1234567890" };
|
||||||
const Match DECIMAL_DOT = { "." };
|
const Match DECIMAL_DOT = { "." };
|
||||||
const ParseGroup ALPHA = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst" };
|
const ParseGroup ALPHA = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" };
|
||||||
const Match ARRAY_OPEN = { "[" };
|
const Match ARRAY_OPEN = { "[" };
|
||||||
const Match ARRAY_CLOSE = { "]" };
|
const Match ARRAY_CLOSE = { "]" };
|
||||||
const Match ARRAY_DELIM = { "," };
|
const Match ARRAY_DELIM = { "," };
|
||||||
|
@ -60,24 +60,46 @@ namespace {
|
||||||
char(COMMENT_BEGIN)
|
char(COMMENT_BEGIN)
|
||||||
};
|
};
|
||||||
const Match NEWLINE = { "\n" };
|
const Match NEWLINE = { "\n" };
|
||||||
const Match ESCAPE = { "\\" };
|
|
||||||
const ParseGroup ESCAPED = { "\\\"" };
|
const ParseGroup ESCAPED = { "\\\"" };
|
||||||
|
|
||||||
|
const Match ESCAPE = { "\\" };
|
||||||
|
|
||||||
|
// Dialogue mode matches
|
||||||
|
const Match MARKUP_OPEN = { "[" };
|
||||||
|
const Match MARKUP_CLOSE = { "]" };
|
||||||
|
const Match SPEAKER_OPEN = { "[" };
|
||||||
|
const Match SPEAKER_CLOSE = { "]" };
|
||||||
|
const Match MARKUP_TEXT_OPEN = { "{" };
|
||||||
|
const Match MARKUP_TEXT_CLOSE = { "}" };
|
||||||
|
const Match TEMPLATE_IND = { "$" };
|
||||||
|
const Match TEMPLATE_OPEN = { "{" };
|
||||||
|
const Match TEMPLATE_CLOSE = { "}" };
|
||||||
|
|
||||||
|
const Match COMMAND_ESCAPE = { "*!" };
|
||||||
|
const ParseGroup DIALOGUE_ESCAPED_SINGLE = {
|
||||||
|
ESCAPE.accept +
|
||||||
|
char(MARKUP_OPEN) +
|
||||||
|
char(MARKUP_CLOSE) +
|
||||||
|
char(MARKUP_TEXT_OPEN) +
|
||||||
|
char(MARKUP_TEXT_CLOSE) +
|
||||||
|
// char(SPEAKER_OPEN) +
|
||||||
|
// char(SPEAKER_CLOSE) +
|
||||||
|
char(TEMPLATE_IND)
|
||||||
|
// char(TEMPLATE_OPEN) +
|
||||||
|
// char(TEMPLATE_CLOSE)
|
||||||
|
};
|
||||||
|
|
||||||
enum class ParseType { Symbol, Number, String, Array, Subexpression };
|
enum class ParseType { Symbol, Number, String, Array, Subexpression };
|
||||||
|
|
||||||
std::string read_file_to_string(const std::string& path) {
|
std::string read_file_to_string(const std::string& path) {
|
||||||
std::ifstream f(path);
|
std::ifstream f(path);
|
||||||
{ // Some apps on Windows adds this signature in front of UTF-8 files when saving
|
{ // Some apps on Windows adds this signature in front of UTF-8 files when saving
|
||||||
char a, b, c;
|
char a, b, c;
|
||||||
a = f.get();
|
a = f.get(); b = f.get(); c = f.get();
|
||||||
b = f.get();
|
if (a != (char)0xEF || b != (char)0xBB || c != (char)0xBF)
|
||||||
c = f.get();
|
|
||||||
if (a != (char)0xEF || b != (char)0xBB || c != (char)0xBF) {
|
|
||||||
f.seekg(0);
|
f.seekg(0);
|
||||||
}
|
else
|
||||||
else {
|
|
||||||
std::cerr << "Warning: Windows UTF-8 BOM skipped" << std::endl;
|
std::cerr << "Warning: Windows UTF-8 BOM skipped" << std::endl;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
std::stringstream buffer;
|
std::stringstream buffer;
|
||||||
buffer << f.rdbuf();
|
buffer << f.rdbuf();
|
||||||
|
@ -125,7 +147,6 @@ namespace {
|
||||||
};
|
};
|
||||||
using Command = std::vector<Object>;
|
using Command = std::vector<Object>;
|
||||||
|
|
||||||
|
|
||||||
class Scene {
|
class Scene {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<Command> commands{};
|
std::vector<Command> commands{};
|
||||||
|
@ -136,6 +157,15 @@ namespace {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Markup {
|
||||||
|
//... TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MarkupInstance {
|
||||||
|
std::pair<unsigned, unsigned> range;
|
||||||
|
std::string effect; //TEMP
|
||||||
|
};
|
||||||
|
|
||||||
void SkipWS(const std::string& f, size_t& pos) {
|
void SkipWS(const std::string& f, size_t& pos) {
|
||||||
while (WS.accept.find(f[pos]) != std::string::npos)
|
while (WS.accept.find(f[pos]) != std::string::npos)
|
||||||
pos++;
|
pos++;
|
||||||
|
@ -292,7 +322,46 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
Command ParseDialogue(const std::string& s) {
|
Command ParseDialogue(const std::string& s) {
|
||||||
return { { ParseType::Symbol, "Say" }, { ParseType::String, s } };
|
if (s.substr(0, 2) == COMMAND_ESCAPE.accept) {
|
||||||
|
size_t dummy = 0;
|
||||||
|
return ParseCommand(s.substr(2), dummy); // TODO string[] will throw on this 100%, maybe do ParseDialogueCommand
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.back() == SPEAKER_CLOSE) {
|
||||||
|
if (s.front() == SPEAKER_OPEN) {
|
||||||
|
auto name = s.substr(1, s.length() - 2);
|
||||||
|
if (IsLegalSymbolName(name))
|
||||||
|
return { { ParseType::Symbol, "SwitchSpeaker" }, { ParseType::String, name } };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::runtime_error("Malformed speaker command");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> discards;
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
if (s[i] == ESCAPE) {
|
||||||
|
if (DIALOGUE_ESCAPED_SINGLE.accept.find(s[i]) != std::string::npos) {
|
||||||
|
discards.push_back(i++);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw std::runtime_error("Unrecognized escape sequence");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string new_s{s};
|
||||||
|
for (int i = 0; i < discards.size(); i++) {
|
||||||
|
new_s.erase(discards[i] - i, 1);
|
||||||
|
discards[i] -= i; // New indices become the positions of the escaped characters
|
||||||
|
}
|
||||||
|
// TODO
|
||||||
|
for (int i = 0; i < s.length(); i++) {
|
||||||
|
if (!discards.empty() && discards[0] < i) {
|
||||||
|
discards.erase(discards.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << new_s << std::endl;
|
||||||
|
return { { ParseType::Symbol, "Say" }, { ParseType::String, new_s } };
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene ParseScene(const std::string& f, size_t& pos) {
|
Scene ParseScene(const std::string& f, size_t& pos) {
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
|
|
||||||
namespace NVL {
|
namespace NVL {
|
||||||
void ParseFile(const std::string& path);
|
void ParseFile(const std::string& path);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ Every new line is a new "click". I discarded the "pause" idea.
|
||||||
|
|
||||||
[Bailey]
|
[Bailey]
|
||||||
Je ne suis plus Alex.
|
Je ne suis plus Alex.
|
||||||
Ça ne me arrête pas de vous démontrer notre support multilingue noblement distingué.
|
Ça ne m'arrête pas de vous démontrer notre support multilingue noblement distingué.
|
||||||
|
|
||||||
[Catherine]
|
[Catherine]
|
||||||
CJKテスト!
|
CJKテスト!
|
||||||
|
@ -44,7 +44,7 @@ To grab a value from the environment, do it like this: ${var}.
|
||||||
This is also the syntax to evaluate a command from dialogue mode.
|
This is also the syntax to evaluate a command from dialogue mode.
|
||||||
If the return is void it will say "undefined" or something like that.
|
If the return is void it will say "undefined" or something like that.
|
||||||
|
|
||||||
*! This "is a command in dialogue mode."
|
*! This "is a command in dialogue mode." // Dialogue mode commands have to be one liners
|
||||||
*! Set var (+ var 1)
|
*! Set var (+ var 1)
|
||||||
|
|
||||||
[NARRATION]
|
[NARRATION]
|
||||||
|
@ -61,6 +61,6 @@ Choice var4 ["Apple", "Orange"]
|
||||||
// to have ways to terminate a scene other than END, for instance JUMP can be an alternative like this:
|
// to have ways to terminate a scene other than END, for instance JUMP can be an alternative like this:
|
||||||
// JUMP Scene2
|
// JUMP Scene2
|
||||||
// we can equally do something like this
|
// we can equally do something like this
|
||||||
// JUMP (switch var4 [["Apple", RouteA], ["Orange", RouteB], [default, RouteC]])
|
// JUMP (switch var4 [[0, RouteA], [1, RouteB], [default, RouteC]])
|
||||||
|
|
||||||
END
|
END
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
BEGIN Scene1
|
BEGIN Scene1
|
||||||
<<-
|
<<-
|
||||||
|
[Alex]
|
||||||
|
Hello. Welcome to dialogue mode.
|
||||||
|
Every new line is a new "click". I discarded the "pause" idea.
|
||||||
|
[Bailey]
|
||||||
Je ne suis plus Alex.
|
Je ne suis plus Alex.
|
||||||
Ça ne me arrête pas de vous démontrer notre support multilingue noblement distingué.
|
Ça ne m'arrête pas de vous démontrer notre support multilingue noblement distingué.
|
||||||
|
[Catherine]
|
||||||
CJKテスト!
|
CJKテスト!
|
||||||
夏はマシンガン。
|
夏はマシンガン。
|
||||||
->>
|
->>
|
||||||
|
|
Loading…
Add table
Reference in a new issue