Files
wb/wbt/wbt.cpp
T

94 lines
2.6 KiB
C++

module;
#include <fstream>
#include <iostream>
// This module is the transpiler from WBT to HTML for site build
export module wbt;
export enum WBT_States {
WBT_STATE_INIT,
WBT_STATE_OPEN,
WBT_STATE_EXPRESSION,
WBT_STATE_CLOSE,
};
export class WBT_Parser {
std::istream& input;
std::ostream& output;
public:
explicit WBT_Parser(
std::istream& i,
std::ostream& o
)
: input(i), output(o) {
}
void output_char(const char c) const {
output << c;
}
static void error(const std::string& msg, const int line, const int column) {
std::cerr << "Error (" << line << "," << column << "): " << msg << std::endl;
}
void eval(const std::string& expr) const {
output << "[EXPR: " << expr << "]";
}
void parse() const {
auto state = WBT_STATE_INIT;
std::string expr;
auto line = 1;
auto column = 1;
while (input.peek() != std::char_traits<char>::eof()) {
char c;
input.get(c);
// State machine
switch (state) {
case WBT_STATE_INIT:
if (c == '{') {
state = WBT_STATE_OPEN;
} else {
output_char(c);
}
break;
case WBT_STATE_OPEN:
if (c == '{') {
state = WBT_STATE_EXPRESSION;
} else {
output_char('{');
output_char(c);
state = WBT_STATE_INIT;
}
break;
case WBT_STATE_EXPRESSION:
if (c == '}') {
state = WBT_STATE_CLOSE;
} else if (c == '{') {
error("Invalid character inside of expression", line, column);
return;
} else {
expr += c;
}
break;
case WBT_STATE_CLOSE:
if (c == '}') {
eval(expr);
expr.clear();
state = WBT_STATE_INIT;
} else {
error("Unclosed expression", line, column);
return;
}
break;
}
if (c == '\n') {
line++;
column = 1;
} else {
column++;
}
}
}
};