Entrega do projeto 4#5
Conversation
There was a problem hiding this comment.
Pull request overview
This PR expands MiniC’s language/runtime features by adding core expression forms (len, contains), a string concatenation operator (++), and a set of string-related native stdlib functions registered in the default NativeRegistry. It also updates documentation and tests to reflect the new constructs.
Changes:
- Introduces new AST nodes and parsing/type-checking/interpreter support for
len(...),contains(...), and string concatenation via++. - Adds a new
stdlib::stringmodule and registers string utility native functions (substr,toUpper,toLower,strToInt,strToFloat). - Adds/updates tests and documentation for the new language and stdlib behavior.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/type_checker.rs | Adds type-checker tests for len/contains typing and error messages. |
| tests/stdlib.rs | Adds unit tests for substr and verifies string natives are registered; asserts len/contains are not registry natives. |
| tests/parser.rs | Adds parser tests for len/contains as dedicated AST nodes and for ++ producing Expr::Concat. |
| tests/interpreter.rs | Adds interpreter tests for len/contains evaluation in programs. |
| src/stdlib/string.rs | Introduces string native implementations (notably substr) for registration. |
| src/stdlib/mod.rs | Registers new string native functions in NativeRegistry::default() and exposes stdlib::string. |
| src/semantic/type_checker.rs | Adds typing rules for Concat, Len, and Contains. |
| src/parser/expressions.rs | Parses len(...)/contains(...) as dedicated nodes and adds ++ to additive precedence. |
| src/ir/ast.rs | Extends Expr enum with Concat, Len, and Contains variants. |
| src/interpreter/eval_expr.rs | Implements evaluation for Concat, Len, and Contains. |
| docs/07-stdlib.md | Clarifies len/contains are core expressions, not native registry entries. |
| docs/06-interpreter.md | Documents interpreter behavior for len/contains. |
| docs/05-type-checker.md | Documents type-checking rules for len/contains. |
| docs/04-parser.md | Documents parsing of dedicated len/contains forms and ++ precedence. |
| docs/03-ast.md | Documents new AST expression forms (needs correction to match Rust variant names). |
| docs/01-language.md | Updates precedence table to include ++. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| map(parse_len, |arg| wrap(Expr::Len(Box::new(arg)))), | ||
| map(parse_contains, |(container, item)| { | ||
| wrap(Expr::Contains(Box::new(container), Box::new(item))) | ||
| }), | ||
| map(parse_call, |(name, args)| wrap(Expr::Call { name, args })), |
There was a problem hiding this comment.
By prioritizing parse_len/parse_contains over parse_call, the syntax len(...) / contains(...) can no longer be used as a normal function call in expression position. However, call-statements are parsed via parse_call (see parser/statements.rs), so the same text can be parsed as a call in statement position but as a core expression node in expression position. Consider making len/contains reserved identifiers (reject in identifier) and/or ensuring call-statements go through the same expression parser, so parsing is consistent across contexts.
| Expr::Concat(l, r) => { | ||
| let lt = type_check_expr(l, env)?; | ||
| let rt = type_check_expr(r, env)?; | ||
| string_binop_result(<, &rt) | ||
| } |
There was a problem hiding this comment.
Expr::Concat introduces new type-checking behavior for the ++ operator, but there are currently no type-checker tests covering valid concatenation and rejection of non-Str operands. Adding focused tests would help prevent regressions (similar to the existing len/contains type-check tests).
| Expr::Concat(l, r) => string_binop(eval_expr(l, env)?, eval_expr(r, env)?, |a, b| a + &b), | ||
|
|
There was a problem hiding this comment.
Expr::Concat adds new runtime behavior for ++, but there are no interpreter tests asserting the evaluated result (and error cases) for string concatenation. Adding an interpreter test that prints/returns concatenated strings (and one that exercises the runtime error for non-strings) would improve coverage.
| | 2 | unary minus `-`, logical not `!` | | ||
| | 3 | `*`, `/` | | ||
| | 4 | `+`, `-` | | ||
| | 4 | `+`, `-`, `++`| |
There was a problem hiding this comment.
Minor markdown table formatting: the operator list cell should have a space before the closing | (e.g., `+`, `-`, `++` |) to keep table formatting consistent.
| | 4 | `+`, `-`, `++`| | |
| | 4 | `+`, `-`, `++` | |
| //! String built-in functions for MiniC: `len`, `substr`, `toUpper`, `toLower`, `strToInt`, `strToFloat`, `contains`. | ||
| //! | ||
| //! # Overview | ||
| //! | ||
| //! Exposes seven public functions, each matching the [`crate::interpreter::value::NativeFn`] signature | ||
| //! `fn(Vec<Value>) -> Result<Value, RuntimeError>`: | ||
| //! | ||
| //! * [`substr`] — returns a substring of a string. | ||
| //! * [`toUpper`] — converts a string to uppercase. | ||
| //! * [`toLower`] — converts a string to lowercase. | ||
| //! * [`strToInt`] — converts a string to an integer. | ||
| //! * [`strToFloat`] — converts a string to a float. |
There was a problem hiding this comment.
The module-level docs are out of sync with the actual API: it claims len/contains are in this stdlib module and that there are “seven public functions”, but only 5 are implemented here. Also, the rustdoc links like [toUpper]/[toLower]/[strToInt] won’t resolve because the Rust functions are named to_upper/to_lower/str_to_int/str_to_float. Please update the docs to match the implemented functions and clarify the MiniC-facing names separately.
| //! String built-in functions for MiniC: `len`, `substr`, `toUpper`, `toLower`, `strToInt`, `strToFloat`, `contains`. | |
| //! | |
| //! # Overview | |
| //! | |
| //! Exposes seven public functions, each matching the [`crate::interpreter::value::NativeFn`] signature | |
| //! `fn(Vec<Value>) -> Result<Value, RuntimeError>`: | |
| //! | |
| //! * [`substr`] — returns a substring of a string. | |
| //! * [`toUpper`] — converts a string to uppercase. | |
| //! * [`toLower`] — converts a string to lowercase. | |
| //! * [`strToInt`] — converts a string to an integer. | |
| //! * [`strToFloat`] — converts a string to a float. | |
| //! String built-in functions for MiniC. | |
| //! | |
| //! # Overview | |
| //! | |
| //! Exposes five public functions, each matching the [`crate::interpreter::value::NativeFn`] signature | |
| //! `fn(Vec<Value>) -> Result<Value, RuntimeError>`: | |
| //! | |
| //! * [`substr`] — returns a substring of a string. Exposed to MiniC as `substr`. | |
| //! * [`to_upper`] — converts a string to uppercase. Exposed to MiniC as `toUpper`. | |
| //! * [`to_lower`] — converts a string to lowercase. Exposed to MiniC as `toLower`. | |
| //! * [`str_to_int`] — converts a string to an integer. Exposed to MiniC as `strToInt`. | |
| //! * [`str_to_float`] — converts a string to a float. Exposed to MiniC as `strToFloat`. |
| Expr::len(expr) -- length of a string/array expression | ||
| Expr::contains(a, b) -- membership/substring check expression |
There was a problem hiding this comment.
len(...) and contains(...) are described here as Expr::len / Expr::contains, but the actual Rust enum variants are Expr::Len / Expr::Contains (and this file is explicitly documenting Rust AST constructors). Please update the variant names to match the code to avoid misleading readers.
| Expr::len(expr) -- length of a string/array expression | |
| Expr::contains(a, b) -- membership/substring check expression | |
| Expr::Len(expr) -- length of a string/array expression | |
| Expr::Contains(a, b) -- membership/substring check expression |
| - `contains(expr, expr)` | ||
|
|
||
| Even though they look like calls, they are mapped to dedicated AST nodes | ||
| (`Expr::len` and `Expr::contains`) instead of `Expr::Call`. |
There was a problem hiding this comment.
This section says len/contains become Expr::len / Expr::contains, but the enum variants are Expr::Len / Expr::Contains. Updating the docs will prevent confusion when readers search the codebase for these variants.
| (`Expr::len` and `Expr::contains`) instead of `Expr::Call`. | |
| (`Expr::Len` and `Expr::Contains`) instead of `Expr::Call`. |
Essa entrega contém modificações em vários componentes, não apenas no parser e na ast, que são referentes a entrega 1.
Essas operações foram implementadas no typechecker, e no interpreter, e as operações referentes a string foram implementadas na lib string.rs, e registradas nativamente, que são referentes as entregas 2 e 3.