diff --git a/build/msbuild/lol.rules.props b/build/msbuild/lol.rules.props
index 787a2870..29da5ad2 100644
--- a/build/msbuild/lol.rules.props
+++ b/build/msbuild/lol.rules.props
@@ -15,7 +15,7 @@
$(IntDir)/%(Directory)/
- $(SolutionDir)\..\src;$(SolutionDir)\..\src\bullet;$(SolutionDir)\..\tools\lolunit;$(FlexIncludes);$(BtPhysIncludes);%(AdditionalIncludeDirectories)
+ $(SolutionDir)\..\src;$(SolutionDir)\..\src\bullet;$(SolutionDir)\..\tools\lolunit;$(PegtlIncludes);$(FlexIncludes);$(BtPhysIncludes);%(AdditionalIncludeDirectories)
$(GlIncludes);$(SdlIncludes);$(FfmpegIncludes);$(D3d9Includes);$(XinputIncludes);%(AdditionalIncludeDirectories)
$(GlIncludes);$(SdlIncludes);$(FfmpegIncludes);$(D3d9Includes);$(XinputIncludes);%(AdditionalIncludeDirectories)
NOMINMAX;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
diff --git a/build/msbuild/lol.vars.props b/build/msbuild/lol.vars.props
index a9ddd7b6..d3edf8d9 100644
--- a/build/msbuild/lol.vars.props
+++ b/build/msbuild/lol.vars.props
@@ -8,6 +8,10 @@
$(ExternalDir)\flex-2.5.35
$(FlexDir)\include
+
+ $(ExternalDir)\pegtl-0.32
+ $(PegtlDir)\include
+
$(ExternalDir)\libgcc-4.9
$(LibGccDir)\lib\i686-w64-mingw32
@@ -109,6 +113,8 @@
$(ExternalDir)
$(FlexDir)
$(FlexIncludes)
+ $(PegtlDir)
+ $(PegtlIncludes)
$(LibGccDir)
$(LibGccLibs)
$(LibGccDeps)
diff --git a/configure.ac b/configure.ac
index f50b3980..3b8fd422 100644
--- a/configure.ac
+++ b/configure.ac
@@ -143,9 +143,8 @@ else
AC_DEFINE(LOL_BUILD_RELEASE, 1, Define to 1 to activate final release)
LOL_TRY_CXXFLAGS(-Os, [AM_CXXFLAGS="${AM_CXXFLAGS} -Os"])
LOL_TRY_CXXFLAGS(-ffast-math, [AM_CXXFLAGS="${AM_CXXFLAGS} -ffast-math"])
-dnl Removed this so .nexe build ok.
-dnl LOL_TRY_CXXFLAGS(-fomit-frame-pointer, [AM_CXXFLAGS="${AM_CXXFLAGS} -fomit-frame-pointer"])
-dnl LOL_TRY_CXXFLAGS(-fno-strength-reduce, [AM_CXXFLAGS="${AM_CXXFLAGS} -fno-strength-reduce"])
+ LOL_TRY_CXXFLAGS(-fomit-frame-pointer, [AM_CXXFLAGS="${AM_CXXFLAGS} -fomit-frame-pointer"])
+ LOL_TRY_CXXFLAGS(-fno-strength-reduce, [AM_CXXFLAGS="${AM_CXXFLAGS} -fno-strength-reduce"])
fi
@@ -191,10 +190,6 @@ AM_CONDITIONAL(USE_LATEX, test "${LATEX}" != "no")
AM_CONDITIONAL(USE_DOT, test "${DOT}" != "no")
-dnl No exceptions…
-LOL_TRY_CXXFLAGS(-fno-exceptions, [AM_CXXFLAGS="${AM_CXXFLAGS} -fno-exceptions"])
-LOL_TRY_CXXFLAGS(-fno-rtti, [AM_CXXFLAGS="${AM_CXXFLAGS} -fno-rtti"])
-
dnl Debug symbols
LOL_TRY_LDFLAGS(-rdynamic, [AM_LDFLAGS="${AM_LDFLAGS} -rdynamic"])
@@ -353,6 +348,13 @@ if test "x${ac_cv_my_have_flexlexer_h}" = "xno"; then
fi
+dnl Use pegtl? Yes, always
+if true; then
+ LOL_CFLAGS="$LOL_CFLAGS -I\$(top_srcdir)/external/pegtl-0.32/include"
+ LOL_CFLAGS="$LOL_CFLAGS -I\$(top_srcdir)/external/axe-1.5.4.164/include"
+fi
+
+
dnl Use NativeClient?
ac_cv_my_have_nacl="no"
AC_LANG_PUSH(C++)
diff --git a/demos/test/sandbox/sample.cpp b/demos/test/sandbox/sample.cpp
index 9e221124..914ef8ee 100644
--- a/demos/test/sandbox/sample.cpp
+++ b/demos/test/sandbox/sample.cpp
@@ -1,11 +1,13 @@
//
-// Lol Engine - Sandbox program
+// Lol Engine - Sandbox program
//
-// Copyright: (c) 2005-2011 Sam Hocevar
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the Do What The Fuck You Want To
-// Public License, Version 2, as published by Sam Hocevar. See
-// http://www.wtfpl.net/ for more details.
+// Copyright © 2005-2015 Sam Hocevar
+//
+// This program is free software. It comes without any warranty, to
+// the extent permitted by applicable law. You can redistribute it
+// and/or modify it under the terms of the Do What the Fuck You Want
+// to Public License, Version 2, as published by the WTFPL Task Force.
+// See http://www.wtfpl.net/ for more details.
//
#if HAVE_CONFIG_H
@@ -14,22 +16,151 @@
#include
+#include "pegtl.hh"
+namespace lol { namespace parser = pegtl; }
+
+#include "axe.h"
+namespace lol { using namespace axe; }
+
using namespace lol;
-int main(int argc, char **argv)
+//
+// Parser tools for a simple calculator grammar with + - * /
+//
+
+struct calculator
{
- ivec2 size(128, 128);
+ void push(double d) { stack.Push(d); }
+ void pop() { printf("%f\n", stack.Pop()); }
- if (argc > 1)
- size.x = size.y = atoi(argv[1]);
- if (argc > 2)
- size.y = atoi(argv[2]);
+ void mul() { auto x = stack.Pop(); stack.Push(stack.Pop() * x); }
+ void div() { auto x = stack.Pop(); stack.Push(stack.Pop() / x); }
+ void add() { auto x = stack.Pop(); stack.Push(stack.Pop() + x); }
+ void sub() { auto x = stack.Pop(); stack.Push(stack.Pop() - x); }
- array2d vac = Image::BlueNoiseKernel(size);
- for (int y = 0; y < size.y; ++y)
- for (int x = 0; x < size.x; ++x)
- printf("%d %d %f\n", x, y, vac[x][y]);
+ array stack;
+};
+
+static void parse_pegtl(std::string const &str);
+static void parse_axe(std::string const &str);
+
+int main()
+{
+ std::string const str("42+2*(1-1+2+3-4*5)");
+
+ parse_axe(str);
+ parse_pegtl(str);
return EXIT_SUCCESS;
}
+//
+// PegTL -- a PEG parser
+//
+
+namespace pegtl_parser
+{
+ using namespace lol::parser;
+
+ #define ACTION(name, code) \
+ struct name : action_base { \
+ static void apply(std::string const &ctx, calculator &c) { \
+ code \
+ } \
+ };
+
+ ACTION( do_number, c.push(atof(ctx.c_str())); )
+ ACTION( do_op,
+ switch (ctx[0])
+ {
+ case '*': c.mul(); break;
+ case '/': c.div(); break;
+ case '+': c.add(); break;
+ case '-': c.sub(); break;
+ } )
+ ACTION( do_success, c.pop(); )
+
+ #undef ACTION
+
+ // number <- +
+ struct number : ifapply, do_number> {};
+
+ // term <- number | "(" expr ")"
+ struct term : sor, struct expr, one<')'>>> {};
+
+ // factor <- term ( "*" term | "/" term ) *
+ struct factor : seq, term>,
+ seq, term>>, do_op>>> {};
+
+ // expr <- factor ( "+" factor | "-" factor ) *
+ struct expr : seq, factor>,
+ seq, factor>>, do_op>>> {};
+
+ // stmt <- expr
+ struct stmt : ifapply, do_success> {};
+};
+
+static void parse_pegtl(std::string const & str)
+{
+ calculator c;
+ pegtl::basic_parse_string(str, c);
+}
+
+//
+// AXE -- a recursive descent parser (needs right-recursion)
+//
+
+template
+static void parse_axe_helper(IT i1, IT i2)
+{
+ calculator c;
+ double d;
+
+ #define ACTION(code) e_ref([&](...) { code })
+
+ r_rule number, term, factor, factor_tail, expr, expr_tail, stmt;
+
+ // number ::=
+ number = r_double(d) >> ACTION( c.push(d); );
+
+ // term ::= number | ( expr )
+ term = number
+ | '(' & expr & ')';
+
+ // factor ::= term factor_tail
+ // factor_tail ::= * term factor_tail
+ // | / term factor_tail
+ // | ɛ
+ factor_tail = '*' & term >> ACTION( c.mul(); ) & factor_tail
+ | '/' & term >> ACTION( c.div(); ) & factor_tail
+ | r_empty();
+ factor = term & factor_tail;
+
+ // expr ::= factor expr_tail
+ // expr_tail ::= + factor expr_tail
+ // | - factor expr_tail
+ // | ɛ
+ expr_tail = '+' & factor >> ACTION( c.add(); ) & expr_tail
+ | '-' & factor >> ACTION( c.sub(); ) & expr_tail
+ | r_empty();
+ expr = factor & expr_tail;
+
+ // stmt ::= expr
+ // |
+ stmt = expr & r_end() >> ACTION( c.pop(); )
+ | r_fail([](...) { printf("malformed expression\n"); });
+
+ #undef ACTION
+
+ // Evaluate expression
+ stmt(i1, i2);
+}
+
+static void parse_axe(std::string const &str)
+{
+ return parse_axe_helper(str.begin(), str.end());
+}
+