Found my old LEL code and got the shell working, so tomorrow I'll try to make it layout some gui element.

master
Zed A. Shaw 10 months ago
parent 8a6b38c1a4
commit bfd2718cc9
  1. 2
      Makefile
  2. 2
      ansi_parser.cpp
  3. 2
      ansi_parser.rl
  4. 294
      lel.cpp
  5. 87
      lel.rl
  6. 3
      meson.build
  7. 77
      tests/ansi_parser.cpp
  8. 21
      tests/lel.cpp

@ -6,7 +6,7 @@ reset:
%.cpp : %.rl
ragel -o $@ $<
build: ansi_parser.cpp
build: ansi_parser.cpp lel.cpp
meson compile -j 10 -C builddir
release_build:

@ -114,7 +114,7 @@ ANSIParser::ANSIParser(sf::Color default_fg, sf::Color default_bg) :
}
bool ANSIParser::parse(std::wstring_view codes, ColorCB color_cb, WriteCB write_cb) {
const wchar_t *start = NULL;
const wchar_t *start = nullptr;
int cs = 0;
unsigned int value = 0;
const wchar_t *p = codes.data();

@ -132,7 +132,7 @@ ANSIParser::ANSIParser(sf::Color default_fg, sf::Color default_bg) :
}
bool ANSIParser::parse(std::wstring_view codes, ColorCB color_cb, WriteCB write_cb) {
const wchar_t *start = NULL;
const wchar_t *start = nullptr;
int cs = 0;
unsigned int value = 0;
const wchar_t *p = codes.data();

@ -0,0 +1,294 @@
#line 1 "lel.rl"
#include "lel.hpp"
#include <fmt/core.h>
#line 33 "lel.rl"
#line 7 "lel.cpp"
static const char _LELParser_actions[] = {
0, 1, 1, 1, 2, 1, 3, 1,
4, 1, 5, 1, 6, 1, 9, 1,
10, 1, 11, 2, 0, 7, 2, 0,
8, 2, 4, 1, 2, 4, 5
};
static const char _LELParser_key_offsets[] = {
0, 0, 4, 18, 20, 24, 35, 47,
52, 66, 68, 72, 83, 95, 99, 101,
104, 106, 109
};
static const char _LELParser_trans_keys[] = {
32, 91, 9, 13, 32, 40, 42, 46,
60, 62, 94, 95, 9, 13, 65, 90,
97, 122, 48, 57, 41, 44, 48, 57,
40, 42, 46, 60, 62, 94, 95, 65,
90, 97, 122, 32, 93, 95, 124, 9,
13, 48, 57, 65, 90, 97, 122, 32,
93, 124, 9, 13, 32, 40, 42, 46,
60, 62, 94, 95, 9, 13, 65, 90,
97, 122, 48, 57, 41, 44, 48, 57,
40, 42, 46, 60, 62, 94, 95, 65,
90, 97, 122, 32, 93, 95, 124, 9,
13, 48, 57, 65, 90, 97, 122, 32,
93, 9, 13, 48, 57, 41, 48, 57,
48, 57, 41, 48, 57, 32, 91, 9,
13, 0
};
static const char _LELParser_single_lengths[] = {
0, 2, 8, 0, 2, 7, 4, 3,
8, 0, 2, 7, 4, 2, 0, 1,
0, 1, 2
};
static const char _LELParser_range_lengths[] = {
0, 1, 3, 1, 1, 2, 4, 1,
3, 1, 1, 2, 4, 1, 1, 1,
1, 1, 1
};
static const char _LELParser_index_offsets[] = {
0, 0, 4, 16, 18, 22, 32, 41,
46, 58, 60, 64, 74, 83, 87, 89,
92, 94, 97
};
static const char _LELParser_indicies[] = {
0, 2, 0, 1, 3, 4, 5, 6,
7, 7, 6, 8, 3, 8, 8, 1,
9, 1, 10, 11, 12, 1, 4, 5,
6, 7, 7, 6, 8, 8, 8, 1,
13, 15, 14, 16, 13, 14, 14, 14,
1, 17, 18, 19, 17, 1, 20, 21,
22, 23, 24, 24, 23, 25, 20, 25,
25, 1, 26, 1, 27, 28, 29, 1,
21, 22, 23, 24, 24, 23, 25, 25,
25, 1, 30, 15, 31, 16, 30, 31,
31, 31, 1, 32, 18, 32, 1, 33,
1, 34, 35, 1, 36, 1, 37, 38,
1, 39, 2, 39, 1, 0
};
static const char _LELParser_trans_targs[] = {
1, 0, 2, 2, 3, 5, 5, 5,
6, 4, 5, 16, 4, 7, 6, 18,
8, 7, 18, 8, 8, 9, 11, 11,
11, 12, 10, 11, 14, 10, 13, 12,
13, 15, 11, 15, 17, 5, 17, 18
};
static const char _LELParser_trans_actions[] = {
0, 0, 3, 0, 0, 13, 5, 11,
17, 15, 19, 19, 0, 7, 0, 28,
25, 0, 9, 1, 0, 0, 13, 5,
11, 17, 15, 19, 19, 0, 7, 0,
0, 15, 22, 0, 15, 22, 0, 0
};
static const int LELParser_start = 1;
static const int LELParser_first_final = 18;
static const int LELParser_error = 0;
static const int LELParser_en_main = 1;
#line 36 "lel.rl"
bool LELParser::parse(std::string input) {
int cs = 0;
const char *start = nullptr;
const char *begin = input.data();
const char *p = input.data();
const char *pe = p + input.size();
std::string tk;
#line 103 "lel.cpp"
{
cs = LELParser_start;
}
#line 46 "lel.rl"
#line 106 "lel.cpp"
{
int _klen;
unsigned int _trans;
const char *_acts;
unsigned int _nacts;
const char *_keys;
if ( p == pe )
goto _test_eof;
if ( cs == 0 )
goto _out;
_resume:
_keys = _LELParser_trans_keys + _LELParser_key_offsets[cs];
_trans = _LELParser_index_offsets[cs];
_klen = _LELParser_single_lengths[cs];
if ( _klen > 0 ) {
const char *_lower = _keys;
const char *_mid;
const char *_upper = _keys + _klen - 1;
while (1) {
if ( _upper < _lower )
break;
_mid = _lower + ((_upper-_lower) >> 1);
if ( (*p) < *_mid )
_upper = _mid - 1;
else if ( (*p) > *_mid )
_lower = _mid + 1;
else {
_trans += (unsigned int)(_mid - _keys);
goto _match;
}
}
_keys += _klen;
_trans += _klen;
}
_klen = _LELParser_range_lengths[cs];
if ( _klen > 0 ) {
const char *_lower = _keys;
const char *_mid;
const char *_upper = _keys + (_klen<<1) - 2;
while (1) {
if ( _upper < _lower )
break;
_mid = _lower + (((_upper-_lower) >> 1) & ~1);
if ( (*p) < _mid[0] )
_upper = _mid - 2;
else if ( (*p) > _mid[1] )
_lower = _mid + 2;
else {
_trans += (unsigned int)((_mid - _keys)>>1);
goto _match;
}
}
_trans += _klen;
}
_match:
_trans = _LELParser_indicies[_trans];
cs = _LELParser_trans_targs[_trans];
if ( _LELParser_trans_actions[_trans] == 0 )
goto _again;
_acts = _LELParser_actions + _LELParser_trans_actions[_trans];
_nacts = (unsigned int) *_acts++;
while ( _nacts-- > 0 )
{
switch ( *_acts++ )
{
case 0:
#line 8 "lel.rl"
{tk = input.substr(start - begin, p - start); }
break;
case 1:
#line 10 "lel.rl"
{ col(); }
break;
case 2:
#line 11 "lel.rl"
{ ltab(); }
break;
case 3:
#line 12 "lel.rl"
{ valign((*p)); }
break;
case 4:
#line 13 "lel.rl"
{ id(input.substr(start - begin, p - start)); }
break;
case 5:
#line 14 "lel.rl"
{ row(); }
break;
case 6:
#line 15 "lel.rl"
{ align((*p)); }
break;
case 7:
#line 16 "lel.rl"
{ setwidth(std::stoi(tk)); }
break;
case 8:
#line 17 "lel.rl"
{ setheight(std::stoi(tk)); }
break;
case 9:
#line 18 "lel.rl"
{ expand(); }
break;
case 10:
#line 26 "lel.rl"
{ start = p; }
break;
case 11:
#line 29 "lel.rl"
{start = p;}
break;
#line 215 "lel.cpp"
}
}
_again:
if ( cs == 0 )
goto _out;
if ( ++p != pe )
goto _resume;
_test_eof: {}
_out: {}
}
#line 47 "lel.rl"
bool good = pe - p == 0;
return good;
}
void LELParser::col() {
fmt::println("col");
}
void LELParser::ltab() {
fmt::println("ltab");
}
void LELParser::valign(char dir) {
fmt::println("valign: {}", dir);
}
void LELParser::align(char dir) {
fmt::println("align {}", dir);
}
void LELParser::id(std::string name) {
fmt::println("id: {}", name);
}
void LELParser::row() {
fmt::println("row");
}
void LELParser::setwidth(int width) {
fmt::println("setwidth: {}", width);
}
void LELParser::setheight(int height) {
fmt::println("setheight: {}", height);
}
void LELParser::expand() {
fmt::println("expand");
}

@ -0,0 +1,87 @@
#include "lel.hpp"
#include <fmt/core.h>
%%{
machine LELParser;
alphtype char;
action token {tk = input.substr(start - begin, fpc - start); }
action col { col(); }
action ltab { ltab(); }
action valign { valign(fc); }
action id { id(input.substr(start - begin, fpc - start)); }
action row { row(); }
action align { align(fc); }
action setwidth { setwidth(std::stoi(tk)); }
action setheight { setheight(std::stoi(tk)); }
action expand { expand(); }
col = "|" $col;
ltab = "[" $ltab;
rtab = "]" $row;
valign = ("^" | ".") $valign;
expand = "*" $expand;
halign = ("<" | ">") $align;
number = digit+ >{ start = fpc; } %token;
setw = ("(" number %setwidth ("," number %setheight)? ")") ;
modifiers = (expand | valign | halign | setw);
id = modifiers* ((alpha | '_')+ :>> (alnum | '_')*) >{start = fpc;} %id;
row = space* ltab space* id space* (col space* id)* space* rtab space*;
main := row+;
}%%
%% write data;
bool LELParser::parse(std::string input) {
int cs = 0;
const char *start = nullptr;
const char *begin = input.data();
const char *p = input.data();
const char *pe = p + input.size();
std::string tk;
%% write init;
%% write exec;
bool good = pe - p == 0;
return good;
}
void LELParser::col() {
fmt::println("col");
}
void LELParser::ltab() {
fmt::println("ltab");
}
void LELParser::valign(char dir) {
fmt::println("valign: {}", dir);
}
void LELParser::align(char dir) {
fmt::println("align {}", dir);
}
void LELParser::id(std::string name) {
fmt::println("id: {}", name);
}
void LELParser::row() {
fmt::println("row");
}
void LELParser::setwidth(int width) {
fmt::println("setwidth: {}", width);
}
void LELParser::setheight(int height) {
fmt::println("setheight: {}", height);
}
void LELParser::expand() {
fmt::println("expand");
}

@ -54,6 +54,7 @@ sources = [
'devices.cpp',
'gui.cpp',
'inventory.cpp',
'lel.cpp',
'levelmanager.cpp',
'lights.cpp',
'map.cpp',
@ -77,11 +78,13 @@ sources = [
]
executable('runtests', sources + [
'tests/ansi_parser.cpp',
'tests/base.cpp',
'tests/dbc.cpp',
'tests/dinkyecs.cpp',
'tests/fsm.cpp',
'tests/inventory.cpp',
'tests/lel.cpp',
'tests/levelmanager.cpp',
'tests/lighting.cpp',
'tests/map.cpp',

@ -0,0 +1,77 @@
#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <string>
#include "ansi_parser.hpp"
#include <codecvt>
#include <iostream>
#include "ftxui/dom/elements.hpp" // for text, bgcolor, color, vbox, hbox, separator, operator|, Elements, Element, Fit, border
#include "ftxui/dom/node.hpp" // for Render
#include "ftxui/screen/color.hpp" // for Color, Color::Black, Color::Blue, Color::BlueLight, Color::Cyan, Color::CyanLight, Color::Default, Color::GrayDark, Color::GrayLight, Color::Green, Color::GreenLight, Color::Magenta, Color::MagentaLight, Color::Red, Color::RedLight, Color::White, Color::Yellow, Color::YellowLight, Color::Palette256, ftxui
#include <ftxui/screen/color_info.hpp> // for ColorInfo
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <ftxui/screen/screen.hpp> // for Full, Screen
#include <ftxui/screen/terminal.hpp> // for ColorSupport, Color, Palette16, Palette256, TrueColor
#include "render.hpp"
using namespace fmt;
using namespace ftxui;
std::string generate_colors() {
SFMLRender::init_terminal();
REQUIRE(ftxui::Terminal::ColorSupport() == ftxui::Terminal::Color::TrueColor);
const int max_value = 255;
const int value_increment = 8;
const int hue_increment = 6;
int saturation = max_value;
Elements array;
int count = 0;
for (int value = 0; value < max_value; value += 2 * value_increment) {
Elements line;
for (int hue = 0; hue < max_value; hue += hue_increment) {
line.push_back(
text("#") //
| ftxui::color(Color::HSV(hue, saturation, value)) //
| ftxui::bgcolor(Color::HSV(hue, saturation, value + value_increment)));
count++;
}
array.push_back(hbox(std::move(line)));
}
auto true_color_display = vbox({
vbox(std::move(array)),
});
auto document = vbox({hbox({
true_color_display,
})});
auto screen = Screen::Create(Dimension::Full(), Dimension::Fit(document));
Render(screen, document);
return screen.ToString();
}
TEST_CASE("test out ragel parser", "[gui]") {
SFMLRender::init_terminal();
sf::Color default_fg(0,0,0);
sf::Color default_bg(100,100,100);
// this sets the Truecolor so need to do it first
ANSIParser ansi(default_fg, default_bg);
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> $converter;
std::string colors = generate_colors();
std::wstring colors_utf = $converter.from_bytes(colors);
bool good = ansi.parse(colors_utf,
[&](sf::Color color[[maybe_unused]], sf::Color bgcolor[[maybe_unused]]){
},
[&](wchar_t ch) {
bool correct_char = ch == '#' || ch == ' ' || ch == '\n' || ch == '\r';
REQUIRE(correct_char);
});
REQUIRE(good);
}

@ -0,0 +1,21 @@
#include "lel.hpp"
#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <string>
#include "ansi_parser.hpp"
#include <codecvt>
#include <iostream>
TEST_CASE("test basic ops", "[lel]") {
LELParser parser;
bool good = parser.parse(
"[ label_1 | label3 ]"
"[ (300,300)*text1 | (150)people ]"
"[ <label2 | _ ]"
"[ message | buttons ]");
REQUIRE(good);
}