rsplt issueshttps://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues2018-09-09T03:37:30+02:00https://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/14Binding time analysis2018-09-09T03:37:30+02:00Gerdriaan MulderBinding time analysisSo we want to have a couple of scopes:
* global scope
* function scope
* local scope
Next to that (regarding variable names):
* local variables hide (shadow) function arguments and global variables
* function arguments hide (shad...So we want to have a couple of scopes:
* global scope
* function scope
* local scope
Next to that (regarding variable names):
* local variables hide (shadow) function arguments and global variables
* function arguments hide (shadow) global variables
* variable names can have the same name as function names
Global scope
------------
At the top of the program, we can define variables that can be used everywhere in the program.
Function scope
--------------
Function arguments can be used everywhere in the body of that function.
Local scope
-----------
Variables defined at the top of the function body can be used everywhere in the rest of the function.
Environments
------------
It seems necessary to introduce a concept of an *environment* (or 'namespace', but I find 'environment' a better term):
* functions environment
* variables environment
We keep track of all the defined functions in the functions environment. Since the grammar forbids recursive function definitions, this environment (`FunEnv`) can be reached from all points in a program.
The variables environment (`VarEnv`) can take different forms depending on the current position in a program. In the *global* part of a program (`Decl+`) it should contain all `VarDecl`s. In some *function* (`FunDecl`) the variables environment is backed up, and the environment is duplicated. In the duplicate (`VarEnvFun` for clarity), the environment is changed according to the following rule:
* Function arguments with the same name as an existing global variable overwrite that existing global variable (effectively *masking* the variable in `VarEnv`).
In the function body, the same happens. We keep the `VarEnvFun` and copy it to a new instance: `VarEnvBody`, for example. Then the following rules are followed:
* Local variables with the same name as function arguments overwrite those function arguments (effectively *masking* the variable in `VarEnvFun`)
* Local variables with the same name as global variables overwrite those global variables (effectively *masking* the variable in `VarEnvFun`).
In the function body, the variables environment used is `VarEnvBody`. This contains all variables with the correct scope.
After the function ends, we discard `VarEnvBody` and `VarEnvFun`, continue to the next function with the original `VarEnv` and repeat the above process.
Binding time analysis
---------------------
Now we have two environments that contain all the information needed about a program at any time. The only thing left to do is to *check in which scope we are* and use the corresponding environments:
* global scope
* `FunEnv`
* `VarEnv`
* function scope
* `FunEnv`
* `VarEnvFun`
* local scope
* `FunEnv`
* `VarEnvBody`
We can then simply check at each declaration whether the environment accepts that declaration (i.e. use of defined variables, defined functions).https://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/13trait Add for ErrorAndSpan2017-05-20T20:23:40+02:00Amber Sprenkelsd.sprenkels@cs.ru.nltrait Add for ErrorAndSpanAt the moment, we propagate parsing errors pretty random up through the call stack when they occur. I propose that we implement the `std::ops::BitOr` trait, so we can use constructs like this:
```rust
let eas = yield_parse!(Exp::Fiel...At the moment, we propagate parsing errors pretty random up through the call stack when they occur. I propose that we implement the `std::ops::BitOr` trait, so we can use constructs like this:
```rust
let eas = yield_parse!(Exp::Field, Box::new, self.parse_field_exp(offset));
eas |= yield_parse!(Exp::FunCall, Box::new, self.parse_fun_call(offset));
eas |= yield_parse!(Exp::Ident, self.parse_ident(offset));
eas |= yield_parse!(Exp::Int, self.parse_literal_int(offset));
eas |= yield_parse!(Exp::Char, self.parse_literal_char(offset));
eas |= yield_parse!(Exp::Bool, self.parse_literal_bool(offset));
```
The implementation of BitOr should then return the _first_ occurring error (a.k.a. the error with the smallest `span.start`). This way, we will be able to describe the correct error to the user, instead of just picking one at random, or needing to generate a custom one.Amber Sprenkelsd.sprenkels@cs.ru.nlAmber Sprenkelsd.sprenkels@cs.ru.nlhttps://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/12Fix `allow(unused_assignments)` error suppressing2017-05-20T20:23:40+02:00Amber Sprenkelsd.sprenkels@cs.ru.nlFix `allow(unused_assignments)` error suppressingand just use the new `peek_token!` macro.and just use the new `peek_token!` macro.Amber Sprenkelsd.sprenkels@cs.ru.nlAmber Sprenkelsd.sprenkels@cs.ru.nlhttps://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/11Build remaining test cases2018-09-09T03:37:30+02:00Amber Sprenkelsd.sprenkels@cs.ru.nlBuild remaining test casesFor the parser, some test cases remain unimplemented. We should look into which test cases are currently missing (like the ones for testing the parsing of statements).For the parser, some test cases remain unimplemented. We should look into which test cases are currently missing (like the ones for testing the parsing of statements).Assignment 1Gerdriaan MulderGerdriaan Mulderhttps://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/10Provide a reasonal span on an unexpected EOF2017-05-20T20:23:40+02:00Amber Sprenkelsd.sprenkels@cs.ru.nlProvide a reasonal span on an unexpected EOFI propose that we let the scanner add one EOF at the end of the string of scanned tokens. This way, we know what the span is, when we encounter an unexpected end-of-file.I propose that we let the scanner add one EOF at the end of the string of scanned tokens. This way, we know what the span is, when we encounter an unexpected end-of-file.https://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/9SPL functions to implement2018-09-09T03:37:31+02:00Gerdriaan MulderSPL functions to implement* [ ] `isEmpty :: [a] -> Bool` (returns `True` iff `[a]` empty)
* [ ] `print a` (magical print function)* [ ] `isEmpty :: [a] -> Bool` (returns `True` iff `[a]` empty)
* [ ] `print a` (magical print function)https://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/8Operator precedence2017-05-20T20:23:40+02:00Gerdriaan MulderOperator precedenceFor the arithmetic operators we should follow the `HMVDWOA` (braces, exponentiation, multiplication, division, root, addition, subtraction).
What to do with the other operators? I.e. the unary `!`, `-`, and the binary `==`, `<`, `>`, ...For the arithmetic operators we should follow the `HMVDWOA` (braces, exponentiation, multiplication, division, root, addition, subtraction).
What to do with the other operators? I.e. the unary `!`, `-`, and the binary `==`, `<`, `>`, `<=`, `>=`, `!=`, `&&`, `||`, `:`.Assignment 1https://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/7Assignment 1: deliverables2017-05-20T20:23:40+02:00Gerdriaan MulderAssignment 1: deliverables* [x] Presentation
* [x] Construction of the parser
* [x] Demonstration of the parser
* [x] Implementation (language, changes to the grammar, interesting points)
* [x] Document
* [x] Transformed grammar
* [ ] Semantic ana...* [x] Presentation
* [x] Construction of the parser
* [x] Demonstration of the parser
* [x] Implementation (language, changes to the grammar, interesting points)
* [x] Document
* [x] Transformed grammar
* [ ] Semantic analysisAssignment 1https://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/6Pretty printer2017-05-20T20:23:40+02:00Gerdriaan MulderPretty printerThe pretty printer should output the result of the lexer in such a way that the output can be used again in the lexer.The pretty printer should output the result of the lexer in such a way that the output can be used again in the lexer.Assignment 1https://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/5build reasonable error reporting2017-05-20T20:23:40+02:00Amber Sprenkelsd.sprenkels@cs.ru.nlbuild reasonable error reportingProposal example error:
```
src/filename.spl:20,{18-27} error: unexpected identifier 'remainder'
src/filename.spl:20: mooncycle = 3 remainder;
^~~~~~~~~
```Proposal example error:
```
src/filename.spl:20,{18-27} error: unexpected identifier 'remainder'
src/filename.spl:20: mooncycle = 3 remainder;
^~~~~~~~~
```https://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/4scanner: rename to lexer?2017-05-20T20:23:40+02:00Amber Sprenkelsd.sprenkels@cs.ru.nlscanner: rename to lexer?`scanner` is a widely used name for the input-buffer reading device. However, `lexer` is a more used and less ambiguous name.
I propose to change te code to use the word `lexer`, instead of `scanner`.`scanner` is a widely used name for the input-buffer reading device. However, `lexer` is a more used and less ambiguous name.
I propose to change te code to use the word `lexer`, instead of `scanner`.https://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/3Clippy2018-09-09T03:37:31+02:00Gerdriaan MulderClippyWe want to amuse the user and Clippy (the renowned paperclip) is perfectly suitable for it.We want to amuse the user and Clippy (the renowned paperclip) is perfectly suitable for it.https://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/2scanner: implement missing features2017-05-20T20:23:40+02:00Amber Sprenkelsd.sprenkels@cs.ru.nlscanner: implement missing features- [x] Literal characters
- [x] Comments (`/* ... */`, and `// ...`)- [x] Literal characters
- [x] Comments (`/* ... */`, and `// ...`)Gerdriaan MulderGerdriaan Mulderhttps://gitlab.science.ru.nl/dsprenkels/rsplt/-/issues/1What to do with whitespace2017-05-20T20:23:40+02:00Gerdriaan MulderWhat to do with whitespaceFrom the grammar:
* `VarDecl = ( 'var' | Type ) id '=' Exp ';'`
* `Exp = ...`
* `id = alpha ( '_' | alphaNum )*`
What do we do with input `varavaravarava=123;` as a variable declaration:
1. Variable name `avaravarava` and variable...From the grammar:
* `VarDecl = ( 'var' | Type ) id '=' Exp ';'`
* `Exp = ...`
* `id = alpha ( '_' | alphaNum )*`
What do we do with input `varavaravarava=123;` as a variable declaration:
1. Variable name `avaravarava` and variable value `123`?
2. "Parse" error, because we want an explicit `' '` between `var` and the variable name?
3. ...?
Arguably, both options have their merit. Depending on the type of 'peeking' (lookahead / lookbehind), the scanner can be either very simple or already look like a parser.
Also, what to do with other types of whitespace: `\t`, `\n`, `\r`...