Add support for exporting environment variables (#4)

* Add support for exporting environment variables

* Support multiple exports in one command

Also improves the structure of the AST so the variable name and the
assigned expression aren't free-floating

* Allow for multiple declarations in local declarations as well

Simplify the generated nodes.

* Commit generated code

* Consolidate declarations into a single declaration_command

This also adds support for declare, typeset, and readonly

* Rename environment_variable_assignment to variable_assignment
This commit is contained in:
Mads Hartmann 2018-02-27 22:22:28 +01:00 committed by Max Brunsfeld
parent 1efe2e6f7a
commit 8ca2ecd52d
6 changed files with 32407 additions and 28625 deletions

View File

@ -72,11 +72,11 @@ VAR1=a VAR2="ok" git diff --word-diff=color
(program (program
(command (command
(environment_variable_assignment (variable_name) (word)) (variable_assignment (variable_name) (word))
(command_name (word))) (command_name (word)))
(command (command
(environment_variable_assignment (variable_name) (word)) (variable_assignment (variable_name) (word))
(environment_variable_assignment (variable_name) (string)) (variable_assignment (variable_name) (string))
(command_name (word)) (command_name (word))
(word) (word)
(word))) (word)))
@ -91,8 +91,8 @@ VAR2= echo
--- ---
(program (program
(environment_variable_assignment (variable_name)) (variable_assignment (variable_name))
(command (environment_variable_assignment (variable_name)) (command_name (word)))) (command (variable_assignment (variable_name)) (command_name (word))))
=================================== ===================================
Pipelines Pipelines

View File

@ -144,22 +144,62 @@ find "`dirname $file`" -name "$base"'*'
(raw_string)))) (raw_string))))
========================================= =========================================
Local Variable Declaration Variable declaration: declare & typeset
========================================= =========================================
function a { declare var1
local a=42 typeset -i -r var2=42 var3=10
local b
}
--- ---
(program (program
(function_definition (declaration_command (simple_variable_name))
(word) (declaration_command (argument) (argument)
(compound_statement (variable_assignment (variable_name) (word))
(local_variable_declaration (simple_variable_name) (word)) (variable_assignment (variable_name) (word))))
(local_variable_declaration (simple_variable_name)))))
=========================================
Variable declaration: readonly
=========================================
readonly var1
readonly var2=42
---
(program
(declaration_command (simple_variable_name))
(declaration_command (variable_assignment (variable_name) (word))))
=========================================
Variable declaration: local
=========================================
local a=42 b
local -r c
---
(program
(declaration_command
(variable_assignment (variable_name) (word))
(simple_variable_name))
(declaration_command (argument) (simple_variable_name)))
=========================================
Variable declaration: export
=========================================
export PATH
export FOOBAR PATH="$PATH:/usr/foobar/bin"
---
(program
(declaration_command (simple_variable_name))
(declaration_command
(simple_variable_name)
(variable_assignment (variable_name) (string (simple_expansion (variable_name))))))
========================================= =========================================
Arrays and array expansions Arrays and array expansions
@ -177,14 +217,14 @@ a+=(foo "bar" $(baz))
--- ---
(program (program
(environment_variable_assignment (variable_name) (array)) (variable_assignment (variable_name) (array))
(environment_variable_assignment (variable_name) (array (word) (word) (word))) (variable_assignment (variable_name) (array (word) (word) (word)))
(command (command_name (word)) (expansion (variable_name))) (command (command_name (word)) (expansion (variable_name)))
(command (command_name (word)) (expansion (variable_name))) (command (command_name (word)) (expansion (variable_name)))
(environment_variable_assignment (variable_assignment
(subscript (variable_name) (simple_expansion (variable_name))) (subscript (variable_name) (simple_expansion (variable_name)))
(word)) (word))
(environment_variable_assignment (variable_assignment
(variable_name) (variable_name)
(array (array
(word) (word)

View File

@ -32,10 +32,10 @@ f=g \
(word) (word)
(word)) (word))
(command (command
(environment_variable_assignment (variable_assignment
(variable_name) (variable_name)
(word)) (word))
(environment_variable_assignment (variable_assignment
(variable_name) (variable_name)
(word)) (word))
(command_name (word)) (command_name (word))

View File

@ -47,11 +47,9 @@ module.exports = grammar({
// Statements // Statements
_statement: $ => choice( _statement: $ => choice(
$.environment_variable_assignment, $.variable_assignment,
// Local variable are only allowed inside the body of a function, but to
// keep the grammar simple we'll ignore that requirements.
$.local_variable_declaration,
$.command, $.command,
$.declaration_command,
$.bracket_command, $.bracket_command,
$.for_statement, $.for_statement,
$.while_statement, $.while_statement,
@ -167,7 +165,7 @@ module.exports = grammar({
command: $ => prec.left(seq( command: $ => prec.left(seq(
repeat(choice( repeat(choice(
$.environment_variable_assignment, $.variable_assignment,
$.file_redirect $.file_redirect
)), )),
$.command_name, $.command_name,
@ -180,7 +178,7 @@ module.exports = grammar({
command_name: $ => $._expression, command_name: $ => $._expression,
environment_variable_assignment: $ => seq( variable_assignment: $ => seq(
choice( choice(
$.variable_name, $.variable_name,
$.subscript $.subscript
@ -188,10 +186,13 @@ module.exports = grammar({
$._assignment $._assignment
), ),
local_variable_declaration: $ => seq( declaration_command: $ => seq(
'local', choice('declare', 'typeset', 'export', 'readonly', 'local'),
repeat(alias(seq('-', $.word), 'argument')),
repeat(choice(
$.simple_variable_name, $.simple_variable_name,
optional($._assignment) $.variable_assignment
))
), ),
_assignment: $ => seq( _assignment: $ => seq(

74
src/grammar.json vendored
View File

@ -26,16 +26,16 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "environment_variable_assignment" "name": "variable_assignment"
},
{
"type": "SYMBOL",
"name": "local_variable_declaration"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "command" "name": "command"
}, },
{
"type": "SYMBOL",
"name": "declaration_command"
},
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "bracket_command" "name": "bracket_command"
@ -546,7 +546,7 @@
"members": [ "members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "environment_variable_assignment" "name": "variable_assignment"
}, },
{ {
"type": "SYMBOL", "type": "SYMBOL",
@ -589,7 +589,7 @@
"type": "SYMBOL", "type": "SYMBOL",
"name": "_expression" "name": "_expression"
}, },
"environment_variable_assignment": { "variable_assignment": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
@ -611,29 +611,71 @@
} }
] ]
}, },
"local_variable_declaration": { "declaration_command": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "STRING",
"value": "declare"
},
{
"type": "STRING",
"value": "typeset"
},
{
"type": "STRING",
"value": "export"
},
{
"type": "STRING",
"value": "readonly"
},
{
"type": "STRING",
"value": "local"
}
]
},
{
"type": "REPEAT",
"content": {
"type": "ALIAS",
"content": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
{ {
"type": "STRING", "type": "STRING",
"value": "local" "value": "-"
}, },
{
"type": "SYMBOL",
"name": "word"
}
]
},
"named": false,
"value": "argument"
}
},
{
"type": "REPEAT",
"content": {
"type": "CHOICE",
"members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "simple_variable_name" "name": "simple_variable_name"
}, },
{
"type": "CHOICE",
"members": [
{ {
"type": "SYMBOL", "type": "SYMBOL",
"name": "_assignment" "name": "variable_assignment"
},
{
"type": "BLANK"
} }
] ]
} }
}
] ]
}, },
"_assignment": { "_assignment": {

60849
src/parser.c vendored

File diff suppressed because it is too large Load Diff