ling

namespace ln {
  template<int N> struct Ling {
    char s[N]{}, *p{};
    constexpr Ling(const char (&a)[N]) { for (int i = 0; i < N; i++) s[i] = a[i]; p = s; }
    constexpr static int add(int a, int b) { return a + b; }
    constexpr static int sub(int a, int b) { return a - b; }
    constexpr static int mul(int a, int b) { return a * b; }
    constexpr char next() { while (' ' == *p) ++p; return *p; }
    constexpr bool some() { return ')' != next() && '\0' != *p; }
    constexpr int list() { int v = eval(); ++p; return v; }
    constexpr int num(int v = 0) { return '0' <= *p && '9' >= *p ? num(v * 10 + (*p++ - '0')) : v; }
    constexpr int op(int (*f)(int, int)) {
      int v = eval();
      if (!some()) return f(0, v);
      do v = f(v, eval()); while (some());
      return v;
    }
    constexpr int eval() {
      switch (next()) {
        case '(': return ++p, list();
        case '+': return ++p, op(add);
        case '-': return ++p, op(sub);
        case '*': return ++p, op(mul);
      }
      return num();
    }
  };
  template<int N> constexpr static auto ling(const char (&a)[N]) { return Ling<N>{a}.eval(); }
}

int main() {
  static_assert(  2 == ln::ling("2"), "" );
  static_assert( -2 == ln::ling("- 2"), "" );
  static_assert(  3 == ln::ling("+ 1 2"), "" );
  static_assert(  6 == ln::ling("+ 1 2 3"), "" );
  static_assert( -6 == ln::ling("- + 1 2 3"), "" );
  static_assert(  5 == ln::ling("+ 1 2 3 - 1"), "" );
  static_assert(  0 == ln::ling("* + 1 2 - 3 1"), "" );
  static_assert(  6 == ln::ling("* (+ 1 2) - 3 1"), "" );
}