alevy / simple

A minimal Haskell web-framework based on the WAI web server interface.
http://simple.cx
39 stars 10 forks source link

Extend templating if statement to hold multiple conditionals? #9

Closed chrisdotcode closed 4 years ago

chrisdotcode commented 9 years ago

I was using the templating system, and I ended up having to write code like this:

$if(cond1)$
    $if(cond2)$
        $if(cond3)$
            <p>Hi</p>
        $endif$
    $endif$
$endif$

What if we extend the if statement to be able to parse stuff like:

$if(cond4 && cond5 || cond6)$
    <p>Hi</p>
$endif$

The current AST for Ifs is defined as:

| ASTIf AST AST (Maybe AST)
-- ^ If - condition, true branch and optional false branch

Adding &&s alone is easy, just make it an [AST], and Prelude.and over the conditionals in Language.evaluateAST.

Adding && and || might be a little more difficult, as it might need to look like:

| ASTIf [AST] [AST] AST (Maybe AST)
-- ^ If - and condition(s), or condition(s) true branch and optional false branch

In which Parser.pIf would have to account for this, Language.evaluateAST would need to Prelude.and over the and conditions, Prelude.or over the or conditions, and then Prelude.|| the two results together.

I'm willing to write the code myself (with a little assistance), but before I do that I want to make sure that:

  1. The PR will be accepted and
  2. My design is correct.
alevy commented 9 years ago

This would absolutely be accepted!

I'm not sure encoding it like that in the AST is the best way to do it (what about precedence and nested conditionals?), but it would get us closer. In general, I think we'd want some support for richer expressions anyway, so anything, even small, you do would put us on the right path.

chrisdotcode commented 9 years ago

What is the maximal amount of complexity that you'd like it to handle? And could you write examples of each? Might as well pre-plan for those cases from now.

alevy commented 9 years ago

For boolean operators, I'd say arbitrarily nested &&s and ||s with the normal precedence rules and semantics for parentheses.

So some examples:

I think it might be better to leave the ASTIf rule the same, and add rules for ASTOr and ASTAnd (order of operations is going to be the only tricky part here).

A very first step might just be trying to treat ands and ors and builtin functions, except then you're stuck with reverse polish notation (i.e. and(or(foo,bar),and(baz,boo))).

chrisdotcode commented 9 years ago

What about something like (very roughly):

data ASTConjunction = ASTOr [AST] | ASTAnd [AST]
...
| ASTIf ASTConjunction [AST] AST (Maybe AST)

This gives use re-usability for and and or to work with more than just Ifs.

alevy commented 9 years ago

That seems like the right approach. I think there is an extraneous [AST] in the ASTIf constructor, and we probably want to make ASTConjunction a constructor of AST (which again, then allows us to just leave ASTIf as it is, and we get the reusability you're talking about). But I could be wrong about all that. I think you're definitely on the right track.

alevy commented 9 years ago

Feel free to find me on IRC (alevy on FreeNode) if you have more concerns you'd want to discuss