Marist-CMPT331-TOPL / adder

Adder is a small but usable subset of the Python language. It is named for the Blackadder comedy series, much as the Python language is named for Monty Python.
MIT License
0 stars 2 forks source link

if elif and else statements #60

Closed MaxEnglish closed 1 year ago

MaxEnglish commented 1 year ago

I tried the first approach you sent me in your email. I'm certain I didn't do it correctly though. Where online or in the textbook can I learn how to implement expressions in the interpreter? Let me know what I can change

MaxEnglish commented 1 year ago

Thanks

On Sat, Dec 10, 2022 at 12:18 AM Matthew Adam Johnson < @.***> wrote:

@.**** commented on this pull request.

A quick glance suggests that this is close to working, but not quite. Rather than trying to do all of these at once, start with just one (e.g., IfElseStmt and just compute the resultOf that. Once you get one of these correct, such as if-else, then the others should become a little easier.

I'll take a deeper look early tomorrow and post some more specific suggestions for how to improve it.

— Reply to this email directly, view it on GitHub https://github.com/Marist-CMPT331-TOPL/adder/pull/60#pullrequestreview-1212441918, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFR4ASCY4VHHUCEO2BPCRXTWMQHCVANCNFSM6AAAAAASZ2JZVI . You are receiving this because you authored the thread.Message ID: @.***>

MaxEnglish commented 1 year ago

[image: image.png] This is how I've changed IfElseStmt based on your criticism. However, I'm not sure how to "take the list-of-statements and wrap it in StmtList before passing it to resultOf." I imagine it has to due with brackets which is why I wrapped the exps in them but again I don't know if that's correct.

When I try to run the program, it fails in the parser. Below is a screenshot of a portion of the error message. This somehow seems related to the issue you outlined with the param needing to be a list of stmts. [image: image.png]

On Sat, Dec 10, 2022 at 9:58 PM Matthew Adam Johnson < @.***> wrote:

@.**** requested changes on this pull request.

I've described the necessary changes for IfElseStmt below, so let's start with that.

Please make sure the code compiles before you continue on. Although you won't be able to test it interactively yet (because it may depend on a couple of other pieces that classmates are working on), it will most likely be correct if it compiles.

In src/Adder/Interp.hs https://github.com/Marist-CMPT331-TOPL/adder/pull/60#discussion_r1045123607 :

+{- +resultOf (IfElseStmt test conseq) p st = if q then st2 else st3

The symbols {- and -} are just start and end delimiters for multi-line comments in Haskell (like / and / in Java/JavaScript/etc.) Only use them if you actually want something commented out, and then you should make sure they match (don't have a {- without a matching -}, and vice versa).

I recommend un-commenting this part, since this is for the if-else statement, which I think is a good place to start.

First, let's review the steps needed to execute an if-else statement.

  1. First, evaluate the test expression with valueOf.
    • This will yield an Answer (see line 95 below), which is just a pair containing both a value and the new state of the free store.
  2. Next, assume that value of the test expression is a BoolVal and check if the Bool inside it is True using a Haskell -f-then-else.
  3. If it is True, then compute the resultOf the first branch (i.e., the second sub-expression, sometimes called the consequent).
  4. Otherwise, compute the resultOf the second branch (i.e., the third sub-expression, the else part, sometimes called the alternate).

The code that's commented-out here is close to what's needed, except for a few details.

  • On line 70, the IfElseStmt should have three parts, or sub-expressions, but right now it only has two. Add a third and name it something that is easy to understand. (In fact, you could even decide to rename all of these to just exp1, exp2, and exp3).
  • Since Answer is defined as just a pair of ExpVal and Store, the syntax on line 72 is wrong. It should be just be (BoolVal q, st1), in parentheses without the word Answer.
  • Then, on line 74, there's no need to compute the resultOf the expression conseq again, since we've already done that on the previous line. This line should instead compute the resultOf the third sub-expression (whatever you decided to call it). Also, the state in which that third sub-expression is evaluated is just going to be st1 also, because if we go down the else branch, we do so without ever going down the true-branch (which is what causes us to get to state st2).

Finally, one last detail... in the HOPL languages like SIMPLE_STATEMENT, an if-else statement could only have a single statement in each branch. But in the Adder language, the IfStmt and your IfElseStmt are set up to contain a list-of-statements. So, you actually can't just do resultOf conseq p st since conseq is not just a single Statement. However, someone else is implementing resultOf (StmtList ..), so what you could here is take the list-of-statements and wrap it in StmtList before passing it to resultOf, so that you're passing in the correct data type.

In src/Adder/Interp.hs https://github.com/Marist-CMPT331-TOPL/adder/pull/60#discussion_r1045123649 :

where Answer (BoolVal q) st1 = valueOf test p st st2 = resultOf conseq p st1 st3 = resultOf conseq p st2 -}

+resultOf (IfElifStmt test conseq) p st = if q then st2 then if r then st4

  • where
  • Answer (BoolVal q) st1 = valueOf test p st
  • st2 = resultOf conseq p st1
  • Answer (BoolVal r) st3 = valueOf test r st
  • st4 = resultOf conseq p st3 +-}

Note: End of comment without a matching start of comment.

In src/Adder/Interp.hs https://github.com/Marist-CMPT331-TOPL/adder/pull/60#discussion_r1045123679 :

+resultOf (IfElifStmt test conseq) p st = if q then st2 then if r then st4

  • where
  • Answer (BoolVal q) st1 = valueOf test p st
  • st2 = resultOf conseq p st1
  • Answer (BoolVal r) st3 = valueOf test r st
  • st4 = resultOf conseq p st3 +-}
  • +resultOf (IfElifElseStmt test conseq) p st = if q then st2 then if r then st4 else st5

  • where
  • Answer (BoolVal q) st1 = valueOf test p st
  • st2 = resultOf conseq p st1
  • Answer (BoolVal r) st3 = valueOf test r st
  • st4 = resultOf conseq p st3
  • st5 = resultOf conseq p st4 +-}

Note: End of comment without a matching start of comment.

In src/Adder/Interp.hs https://github.com/Marist-CMPT331-TOPL/adder/pull/60#discussion_r1045123741 :

+resultOf (IfElifStmt test conseq) p st = if q then st2 then if r then st4

  • where
  • Answer (BoolVal q) st1 = valueOf test p st
  • st2 = resultOf conseq p st1
  • Answer (BoolVal r) st3 = valueOf test r st
  • st4 = resultOf conseq p st3

Add a start of comment before this to temporarily comment-out the IfElifStmt until you get the IfElseStmt working.

In src/Adder/Interp.hs https://github.com/Marist-CMPT331-TOPL/adder/pull/60#discussion_r1045123801 :

+resultOf (IfElifElseStmt test conseq) p st = if q then st2 then if r then st4 else st5

  • where
  • Answer (BoolVal q) st1 = valueOf test p st
  • st2 = resultOf conseq p st1
  • Answer (BoolVal r) st3 = valueOf test r st
  • st4 = resultOf conseq p st3
  • st5 = resultOf conseq p st4

Add a start of comment before this to temporarily comment-out the IfElifElseStmt until you get both IfElseStmt and IfElifElseStmtworking.

— Reply to this email directly, view it on GitHub https://github.com/Marist-CMPT331-TOPL/adder/pull/60#pullrequestreview-1212606673, or unsubscribe https://github.com/notifications/unsubscribe-auth/AFR4ASETDA6RDBZPDWRT6KDWMU7OFANCNFSM6AAAAAASZ2JZVI . You are receiving this because you authored the thread.Message ID: @.***>