Skip to content

Commit

Permalink
[ruby/prism] Support ItParametersNode
Browse files Browse the repository at this point in the history
So that compilers know they need to add to add an anonymous
variable to the local table.

ruby/prism@7f1aadd057
  • Loading branch information
kddnewton committed Feb 21, 2024
1 parent 0be0996 commit 90c5393
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 119 deletions.
6 changes: 6 additions & 0 deletions prism/config.yml
Expand Up @@ -1948,6 +1948,12 @@ nodes:
`foo #{bar} baz`
^^^^^^^^^^^^^^^^
- name: ItParametersNode
comment: |
Represents an implicit set of parameters through the use of the `it` keyword within a block or lambda.
-> { it + it }
^^^^^^^^^^^^^^
- name: KeywordHashNode
fields:
- name: flags
Expand Down
9 changes: 8 additions & 1 deletion prism/diagnostic.c
Expand Up @@ -202,8 +202,14 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
[PM_ERR_INVALID_MULTIBYTE_CHARACTER] = { "invalid multibyte character 0x%X", PM_ERROR_LEVEL_FATAL },
[PM_ERR_INVALID_PRINTABLE_CHARACTER] = { "invalid character `%c`", PM_ERROR_LEVEL_FATAL },
[PM_ERR_INVALID_PERCENT] = { "invalid `%` token", PM_ERROR_LEVEL_FATAL }, // TODO WHAT?
<<<<<<< HEAD:prism/diagnostic.c
[PM_ERR_INVALID_VARIABLE_GLOBAL] = { "'%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_FATAL },
[PM_ERR_IT_NOT_ALLOWED] = { "`it` is not allowed when an ordinary parameter is defined", PM_ERROR_LEVEL_FATAL },
=======
[PM_ERR_INVALID_VARIABLE_GLOBAL] = { "`%.*s' is not allowed as a global variable name", PM_ERROR_LEVEL_FATAL },
[PM_ERR_IT_NOT_ALLOWED_NUMBERED] = { "`it` is not allowed when an numbered parameter is defined", PM_ERROR_LEVEL_FATAL },
[PM_ERR_IT_NOT_ALLOWED_ORDINARY] = { "`it` is not allowed when an ordinary parameter is defined", PM_ERROR_LEVEL_FATAL },
>>>>>>> 7f1aadd057 (Support ItParametersNode):src/diagnostic.c
[PM_ERR_LAMBDA_OPEN] = { "expected a `do` keyword or a `{` to open the lambda block", PM_ERROR_LEVEL_FATAL },
[PM_ERR_LAMBDA_TERM_BRACE] = { "expected a lambda block beginning with `{` to end with `}`", PM_ERROR_LEVEL_FATAL },
[PM_ERR_LAMBDA_TERM_END] = { "expected a lambda block beginning with `do` to end with `end`", PM_ERROR_LEVEL_FATAL },
Expand All @@ -225,7 +231,8 @@ static const pm_diagnostic_data_t diagnostic_messages[PM_DIAGNOSTIC_ID_LEN] = {
[PM_ERR_NOT_EXPRESSION] = { "expected an expression after `not`", PM_ERROR_LEVEL_FATAL },
[PM_ERR_NO_LOCAL_VARIABLE] = { "%.*s: no such local variable", PM_ERROR_LEVEL_FATAL },
[PM_ERR_NUMBER_LITERAL_UNDERSCORE] = { "number literal ending with a `_`", PM_ERROR_LEVEL_FATAL },
[PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED] = { "numbered parameters are not allowed when an ordinary parameter is defined", PM_ERROR_LEVEL_FATAL },
[PM_ERR_NUMBERED_PARAMETER_IT] = { "numbered parameters are not allowed when an 'it' parameter is defined", PM_ERROR_LEVEL_FATAL },
[PM_ERR_NUMBERED_PARAMETER_ORDINARY] = { "numbered parameters are not allowed when an ordinary parameter is defined", PM_ERROR_LEVEL_FATAL },
[PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE] = { "numbered parameter is already used in outer scope", PM_ERROR_LEVEL_FATAL },
[PM_ERR_OPERATOR_MULTI_ASSIGN] = { "unexpected operator for a multiple assignment", PM_ERROR_LEVEL_FATAL },
[PM_ERR_OPERATOR_WRITE_ARGUMENTS] = { "unexpected operator after a call with arguments", PM_ERROR_LEVEL_FATAL },
Expand Down
6 changes: 4 additions & 2 deletions prism/diagnostic.h
Expand Up @@ -201,7 +201,8 @@ typedef enum {
PM_ERR_INVALID_PRINTABLE_CHARACTER,
PM_ERR_INVALID_PERCENT,
PM_ERR_INVALID_VARIABLE_GLOBAL,
PM_ERR_IT_NOT_ALLOWED,
PM_ERR_IT_NOT_ALLOWED_NUMBERED,
PM_ERR_IT_NOT_ALLOWED_ORDINARY,
PM_ERR_LAMBDA_OPEN,
PM_ERR_LAMBDA_TERM_BRACE,
PM_ERR_LAMBDA_TERM_END,
Expand All @@ -223,7 +224,8 @@ typedef enum {
PM_ERR_NOT_EXPRESSION,
PM_ERR_NO_LOCAL_VARIABLE,
PM_ERR_NUMBER_LITERAL_UNDERSCORE,
PM_ERR_NUMBERED_PARAMETER_NOT_ALLOWED,
PM_ERR_NUMBERED_PARAMETER_IT,
PM_ERR_NUMBERED_PARAMETER_ORDINARY,
PM_ERR_NUMBERED_PARAMETER_OUTER_SCOPE,
PM_ERR_OPERATOR_MULTI_ASSIGN,
PM_ERR_OPERATOR_WRITE_ARGUMENTS,
Expand Down
66 changes: 37 additions & 29 deletions prism/parser.h
Expand Up @@ -450,37 +450,31 @@ typedef struct {
* into their parent scopes, while others cannot.
*/
typedef struct pm_scope {
/** The IDs of the locals in the given scope. */
pm_constant_id_list_t locals;

/** A pointer to the previous scope in the linked list. */
struct pm_scope *previous;

/**
* A boolean indicating whether or not this scope can see into its parent.
* If closed is true, then the scope cannot see into its parent.
*/
bool closed;

/**
* A boolean indicating whether or not this scope has explicit parameters.
* This is necessary to determine whether or not numbered parameters are
* allowed.
*/
bool explicit_params;
/** The IDs of the locals in the given scope. */
pm_constant_id_list_t locals;

/**
* Booleans indicating whether the parameters for this scope have declared
* forwarding parameters.
* This is a bitfield that indicates the parameters that are being used in
* this scope. It is a combination of the PM_SCOPE_PARAMS_* constants. There
* are three different kinds of parameters that can be used in a scope:
*
* - Ordinary parameters (e.g., def foo(bar); end)
* - Numbered parameters (e.g., def foo; _1; end)
* - The it parameter (e.g., def foo; it; end)
*
* If ordinary parameters are being used, then certain parameters can be
* forwarded to another method/structure. Those are indicated by four
* additional bits in the params field. For example, some combinations of:
*
* For example, some combinations of:
* def foo(*); end
* def foo(**); end
* def foo(&); end
* def foo(...); end
* - def foo(*); end
* - def foo(**); end
* - def foo(&); end
* - def foo(...); end
*/

uint8_t forwarding_params;
uint8_t parameters;

/**
* An integer indicating the number of numbered parameters on this scope.
Expand All @@ -489,13 +483,27 @@ typedef struct pm_scope {
* about how many numbered parameters exist.
*/
int8_t numbered_parameters;

/**
* A boolean indicating whether or not this scope can see into its parent.
* If closed is true, then the scope cannot see into its parent.
*/
bool closed;
} pm_scope_t;

static const uint8_t PM_FORWARDING_POSITIONALS = 0x1;
static const uint8_t PM_FORWARDING_KEYWORDS = 0x2;
static const uint8_t PM_FORWARDING_BLOCK = 0x4;
static const uint8_t PM_FORWARDING_ALL = 0x8;
static const int8_t PM_NUMBERED_PARAMETERS_DISALLOWED = -1;
static const uint8_t PM_SCOPE_PARAMETERS_NONE = 0x0;
static const uint8_t PM_SCOPE_PARAMETERS_ORDINARY = 0x1;
static const uint8_t PM_SCOPE_PARAMETERS_NUMBERED = 0x2;
static const uint8_t PM_SCOPE_PARAMETERS_IT = 0x4;
static const uint8_t PM_SCOPE_PARAMETERS_TYPE_MASK = 0x7;

static const uint8_t PM_SCOPE_PARAMETERS_FORWARDING_POSITIONALS = 0x8;
static const uint8_t PM_SCOPE_PARAMETERS_FORWARDING_KEYWORDS = 0x10;
static const uint8_t PM_SCOPE_PARAMETERS_FORWARDING_BLOCK = 0x20;
static const uint8_t PM_SCOPE_PARAMETERS_FORWARDING_ALL = 0x40;

static const int8_t PM_SCOPE_NUMBERED_PARAMETERS_DISALLOWED = -1;
static const int8_t PM_SCOPE_NUMBERED_PARAMETERS_NONE = 0;

/**
* This struct represents the overall parser. It contains a reference to the
Expand Down

0 comments on commit 90c5393

Please sign in to comment.