incomplete match

This commit is contained in:
lachrymaL 2021-12-13 14:04:12 -05:00
parent 13b14f4002
commit 87b9471735
No known key found for this signature in database
GPG key ID: F3640ACFA174B1C1
7 changed files with 94 additions and 23 deletions

View file

@ -52,4 +52,4 @@ namespace NVL {
return env.find(name) != env.end();
}
}
}

View file

@ -31,4 +31,4 @@ namespace NVL {
bool exists(const std::string& name);
};
extern Environment ENVIRONMENT;
}
}

View file

@ -1,13 +1,10 @@
#include "Parser.h"
#include "Environment.h"
#include <functional>
#include <any>
#include <string>
#include <iostream>
int main() {
auto f = [](NVL::Variable) { return NVL::Variable(NVL::Type::Nil); };
NVL::Variable v(f, 1);
NVL::Variable v([](NVL::Variable) { return NVL::Variable(NVL::Type::Nil); }, 1);
NVL::ENVIRONMENT.enter("hello", v);

View file

@ -26,7 +26,7 @@ namespace {
struct Match {
std::string accept;
constexpr operator char() const {
operator char() const {
return accept[0];
}
bool operator== (const std::string& other) const {
@ -36,7 +36,7 @@ namespace {
const ParseGroup NUMERIC = { "1234567890" };
const Match DECIMAL_DOT = { "." };
const ParseGroup ALPHA = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst" };
const ParseGroup ALPHA = { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" };
const Match ARRAY_OPEN = { "[" };
const Match ARRAY_CLOSE = { "]" };
const Match ARRAY_DELIM = { "," };
@ -60,24 +60,46 @@ namespace {
char(COMMENT_BEGIN)
};
const Match NEWLINE = { "\n" };
const Match ESCAPE = { "\\" };
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 };
std::string read_file_to_string(const std::string& path) {
std::ifstream f(path);
{ // Some apps on Windows adds this signature in front of UTF-8 files when saving
char a, b, c;
a = f.get();
b = f.get();
c = f.get();
if (a != (char)0xEF || b != (char)0xBB || c != (char)0xBF) {
a = f.get(); b = f.get(); c = f.get();
if (a != (char)0xEF || b != (char)0xBB || c != (char)0xBF)
f.seekg(0);
}
else {
else
std::cerr << "Warning: Windows UTF-8 BOM skipped" << std::endl;
}
}
std::stringstream buffer;
buffer << f.rdbuf();
@ -125,7 +147,6 @@ namespace {
};
using Command = std::vector<Object>;
class Scene {
std::string name;
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) {
while (WS.accept.find(f[pos]) != std::string::npos)
pos++;
@ -292,7 +322,46 @@ namespace {
}
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) {

View file

@ -3,4 +3,4 @@
namespace NVL {
void ParseFile(const std::string& path);
}
}

View file

@ -26,7 +26,7 @@ Every new line is a new "click". I discarded the "pause" idea.
[Bailey]
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テスト
@ -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.
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)
[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:
// JUMP Scene2
// 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

View file

@ -1,7 +1,12 @@
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.
Ç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テスト
夏はマシンガン。
->>