Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

19 REALs #51

Merged
merged 12 commits into from
May 5, 2022
Merged

19 REALs #51

merged 12 commits into from
May 5, 2022

Conversation

ngjunsiang
Copy link
Contributor

@ngjunsiang ngjunsiang commented May 5, 2022

Okay, time to get to REALs (Issue #4).

Scanning REALs

Let's start with adding the REAL type to builtin.py:
https://github.com/nyjc-computing/pseudo/blob/b76de00482a2799c7190f92596343b3dcce4d4c8/builtin.py#L103

And then scanning them:
https://github.com/nyjc-computing/pseudo/blob/948ffffd05253150224de0ccd62d0de5c55c16c6/scanner.py#L35-L45

When we reach the end of the digit sequence, we check for a .; if there isn't one, we return an INTEGER. If there's one, we continue scanning another digit sequence to get a REAL.

And we make sure to pass the correct token type:
https://github.com/nyjc-computing/pseudo/blob/948ffffd05253150224de0ccd62d0de5c55c16c6/scanner.py#L109-L114

@ngjunsiang
Copy link
Contributor Author

Parsing REALs

REAL tokens are going to be picked up by value():
https://github.com/nyjc-computing/pseudo/blob/948ffffd05253150224de0ccd62d0de5c55c16c6/parser.py#L126-L127

Which delegates the parsing to literal():
https://github.com/nyjc-computing/pseudo/blob/948ffffd05253150224de0ccd62d0de5c55c16c6/parser.py#L80-L86

So it doesn't look like any additional work is needed here to have REAL tokens parsed as Literal Exprs.

@ngjunsiang
Copy link
Contributor Author

Resolving REALs

Operations

REALs can be operated on by any operator that takes numeric types, so our type-checking for Binary and Unary Exprs will have to be updated.

First, unary negative:
https://github.com/nyjc-computing/pseudo/blob/ab15d9894680d2678498ca95937680329ee4d130/resolver.py#L50-L52

Then the equality operators, <> and =:
https://github.com/nyjc-computing/pseudo/blob/ab15d9894680d2678498ca95937680329ee4d130/resolver.py#L65-L75

The comparison operators:
https://github.com/nyjc-computing/pseudo/blob/ab15d9894680d2678498ca95937680329ee4d130/resolver.py#L76-L81

And lastly the arithmetic operators:
https://github.com/nyjc-computing/pseudo/blob/ab15d9894680d2678498ca95937680329ee4d130/resolver.py#L82-L91

It's a lot of if-matching, tedious but not particularly difficult. Most importantly it must match what the interpreter does.

This enables expectTypeElseError() to accept multiple
type arguments, without changing its behavior for
single type arguments.
@ngjunsiang
Copy link
Contributor Author

ngjunsiang commented May 5, 2022

To make the above changes, we had to undo a few uses of our expectTypeElseError() helper. And now our code is looking all the more complicated for it.

Let's overload our expectTypeElseError() helper so it can accept an arbitrary number of types to expect:
https://github.com/nyjc-computing/pseudo/blob/adb3826c2f4fc768ac644cc293f0f082b9dcdbf9/resolver.py#L18-L26

The * operator presents all positional arguments (after the first) to be presented as a tuple, expected.

And use it again where we want to match for multiple types: [529a658]

@ngjunsiang
Copy link
Contributor Author

Interpreting REALs

https://github.com/nyjc-computing/pseudo/blob/529a658f009403072eb279d7f8f2d0338066014a/interpreter.py#L29-L36

There's not much smarts in our interpreter; it evaluates the operands, and passes them to the operator. If our type-checking is correct, Python's operator implementation gets us the rest of the way.

And we have support for REALs!

@ngjunsiang
Copy link
Contributor Author

Type subcategories

Before wrapping up here, let's make things a bit easier to read (but more abstract).

We have some lines so long we have to stretch them to three lines, like:
https://github.com/nyjc-computing/pseudo/blob/4663382854b0ae571eace674c4dae7774fda9ea7/resolver.py#L78-L80

Let's introduce subcategories of TYPE to make this easier.

We have the NUMERIC types:
https://github.com/nyjc-computing/pseudo/blob/4663382854b0ae571eace674c4dae7774fda9ea7/builtin.py#L103

These can be used with arithmetic and comparison operators.

Then we have the EQUATABLEs:
https://github.com/nyjc-computing/pseudo/blob/4663382854b0ae571eace674c4dae7774fda9ea7/builtin.py#L105

These can be used with the equality operators.

And lastly we add these to the remaining types to get our trusty TYPES:
https://github.com/nyjc-computing/pseudo/blob/4663382854b0ae571eace674c4dae7774fda9ea7/builtin.py#L107

Yep, TYPES is now a tuple instead of a string, but this otherwise doesn't affect our code.

@ngjunsiang
Copy link
Contributor Author

Now we can use them in our typechecks: [2bb8aa7]

Python's * operator, when used in a function call, unpacks an iterable (such as our NUMERIC tuple) and passes its elements to the function as arguments.

@ngjunsiang
Copy link
Contributor Author

ngjunsiang commented May 5, 2022

And then cleaning up to keep each line of code within a 72-char limit:

@ngjunsiang ngjunsiang merged commit a064360 into main May 5, 2022
@ngjunsiang ngjunsiang deleted the real branch May 5, 2022 23:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant