munificent / craftinginterpreters

Repository for the book "Crafting Interpreters"
http://www.craftinginterpreters.com/
Other
8.84k stars 1.04k forks source link

Question about pre/post increment/decrement expressions #205

Closed xDGameStudios closed 6 years ago

xDGameStudios commented 6 years ago

I have a question about pre/post increment/decrement (a++, ++a, a--, --a) expressions and how they fit within the rules. Could you please give me some guidance on how to implement those? as I can see there is currently no information for it in the chapters already written. Thank you very much.

The same applies to compound assignments (+=, -=, &= ....) where in terms of priority should those be defined? and also are there some exceptions where normal assignments should be allowed while compound expressions not.

for example should while statement condition expression allow assignments?! is it a parsing rule or should it be taken care after parsing by code evaluation?!

alexito4 commented 6 years ago

Not sure if it will help for your specific questions but this repo contains some notes around the challenges.

https://github.com/munificent/craftinginterpreters/tree/e7783f611de6b5e6f068dd93d00f5be646803f67/note/answers

munificent commented 6 years ago

When it comes to figuring out where to slot expressions into the precedence and associativity levels, it usually works to find the grammar for the language whose syntax you are following and do what they do.

I believe C places prefix -- and ++ at the same level as the other prefix unary operators like -. I puts the postfix ones at the highest precedence level, along with () (function call) and [] (subscript). In practical terms, it means we would parse the postfix -- and ++ operators inside the Parser.call() in jlox, and the prefix ones in Parser.unary().

Interpreting those operators is basically a combination of the logic you do to access a variable, increment or decrement the value, and then store it back into the variable.

The same applies to compound assignments (+=, -=, &= ....) where in terms of priority should those be defined?

Those usually have the same precedence as =. So you define additional token types for +=, -=, etc. and then accept any of those tokens when parsing assignment expressions.

for example should while statement condition expression allow assignments?!

That is a good question. :) It's really up to you. Most C-based languages do. Some newer ones make it an error to have an assignment in the condition of an if statement since that's a common source of errors.

is it a parsing rule or should it be taken care after parsing by code evaluation?!

You can do either, but I would do it in the parser. It's pretty easy to, when going to parse the condition, just start at a higher level of the precedence hierarchy. For example, the jlox code for parsing while looks like:

  private Stmt whileStatement() {
    consume(LEFT_PAREN, "Expect '(' after 'while'.");
    Expr condition = expression();
    consume(RIGHT_PAREN, "Expect ')' after condition.");
    Stmt body = statement();

    return new Stmt.While(condition, body);
  }

If we didn't want to allow assignments in the condition, we would use the next level of precedence above that, which is logical or (||). So we just change that one line of code above to:

    Expr condition = or();

With that, you'll get a syntax error if you try to parse while (a = b).

I hope that helps! :)

xDGameStudios commented 6 years ago

Thank you so much for your help! Of course it helped... a lot!! Some of those things I figured out myself and the others I will play with them as soon as I can.

Are the “tutorials”/parts of the book still coming up? I’m working with your book and tryng to adapt the concepts to C#. I’m a recently starting game developer and I’m writing a tool to add object oriented capabilities to a language that doesn’t have that... so I’m not really making a interpreter, it’s more like a transpiler.

Still thinking my way through that: maybe using arrays to implement objects... linked lists for functions inheritance. Calling super would go up the linked list into the parent object and find the function. Having the functions seperated from the properties.

(ohhh by the way!! I’m not quite sure.. lox doesn’t have class properties?! For example, a class “person” having an “age” and “name” property (like c# and Java)?

Well I still have a lot to read in your book. Thank you once again, for your time and attention.

Bob Nystrom notifications@github.com escreveu em qui, 5/04/2018 às 05:54 :

When it comes to figuring out where to slot expressions into the precedence and associativity levels, it usually works to find the grammar for the language whose syntax you are following and do what they do.

I believe C places prefix -- and ++ at the same level as the other prefix unary operators like -. I puts the postfix ones at the highest precedence level, along with () (function call) and [] (subscript). In practical terms, it means we would parse the postfix -- and ++ operators inside the Parser.call() in jlox, and the prefix ones in Parser.unary().

Interpreting those operators is basically a combination of the logic you do to access a variable, increment or decrement the value, and then store it back into the variable.

The same applies to compound assignments (+=, -=, &= ....) where in terms of priority should those be defined?

Those usually have the same precedence as =. So you define additional token types for +=, -=, etc. and then accept any of those tokens when parsing assignment expressions.

for example should while statement condition expression allow assignments?!

That is a good question. :) It's really up to you. Most C-based languages do. Some newer ones make it an error to have an assignment in the condition of an if statement since that's a common source of errors.

is it a parsing rule or should it be taken care after parsing by code evaluation?!

You can do either, but I would do it in the parser. It's pretty easy to, when going to parse the condition, just start at a higher level of the precedence hierarchy. For example, the jlox code for parsing while looks like:

private Stmt whileStatement() { consume(LEFT_PAREN, "Expect '(' after 'while'."); Expr condition = expression(); consume(RIGHT_PAREN, "Expect ')' after condition."); Stmt body = statement();

return new Stmt.While(condition, body);

}

If we didn't want to allow assignments in the condition, we would use the next level of precedence above that, which is logical or (||). So we just change that one line of code above to:

Expr condition = or();

With that, you'll get a syntax error if you try to parse while (a = b).

I hope that helps! :)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/munificent/craftinginterpreters/issues/205#issuecomment-378819944, or mute the thread https://github.com/notifications/unsubscribe-auth/AJ4Oqyy13aZuz8ZD-P3BHXSlzbX5FhUnks5tlaODgaJpZM4S94cu .

munificent commented 6 years ago

Are the “tutorials”/parts of the book still coming up?

Yup, I'm about halfway through writing the book. It's slow going, but it's getting there. :)

(ohhh by the way!! I’m not quite sure.. lox doesn’t have class properties?! For example, a class “person” having an “age” and “name” property (like c# and Java)?

That's correct. There's a challenge to add them yourself. You can see my answer to it here.

xDGameStudios commented 6 years ago

If I need to add array access support...

My_array[id]

What would be the best the way to handle it? Should it be handle as a get/set?!

my_array[id] = 45 => get

a = my_array[id] => get

Is it a call?! Should I make a new type of expression?

Bob Nystrom notifications@github.com escreveu em qui, 5/04/2018 às 22:08 :

Are the “tutorials”/parts of the book still coming up?

Yup, I'm about halfway through writing the book. It's slow going, but it's getting there. :)

(ohhh by the way!! I’m not quite sure.. lox doesn’t have class properties?! For example, a class “person” having an “age” and “name” property (like c# and Java)?

That's correct. There's a challenge to add them yourself http://www.craftinginterpreters.com/classes.html#challenges. You can see my answer to it here https://github.com/munificent/craftinginterpreters/blob/master/note/answers/chapter12_classes.md .

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/munificent/craftinginterpreters/issues/205#issuecomment-379060903, or mute the thread https://github.com/notifications/unsubscribe-auth/AJ4Oq1SE9sm-4ES1Pn8mCAU4jCtHgH49ks5tlnnMgaJpZM4S94cu .