Skip to content

Commit

Permalink
Merge remote-tracking branch 'DanTGL/list_declarations_issue_2856' in…
Browse files Browse the repository at this point in the history
…to merging_2975_comma_declares
  • Loading branch information
Dunbaratu committed Aug 1, 2021
2 parents adc69ec + 2ba9021 commit 874e05f
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 5 deletions.
17 changes: 17 additions & 0 deletions doc/source/language/variables.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ Any variable declared with ``DECLARE``, ``DECLARE LOCAL``, or ``LOCAL``
will only exist inside the code block section it was created in.
After that code block is finished, the variable will no longer exist.

It is also possible to declare multiple variables in a single ``DECLARE`` statement,
separated by commas, as shown below::

// These all do the exact same thing - make local variables:
DECLARE A IS 5, B TO 1, C TO "O".
LOCAL A IS 5, B TO 1, C TO "O".
DECLARE LOCAL A IS 5, B TO 1, C TO "O".

// These do the exact same thing - make global variables:
GLOBAL A IS 5, B TO 1, C TO "O".
DECLARE GLOBAL A IS 5, B TO 1, C TO "O".

See Scoping:
::::::::::::

Expand Down Expand Up @@ -268,6 +280,11 @@ This follows the :ref:`scoping rules explained below <scope>`. If the
variable can be found in the current local scope, or any scope higher
up, then it won't be created and instead the existing one will be used.

It is also possible to set the values of multiple variables in a single ``SET`` statement
by separating the assignments with commas, as shown below::

SET X TO 1, Y TO 5, S TO "abc".

.. _unset:

``UNSET``
Expand Down
30 changes: 30 additions & 0 deletions kerboscript_tests/declaration/multi_declaration_test.ks
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Tests comma-separated declarations of variables

print "Testing with 'SET'".
set a to 1, b to 2, c to "a".

print " 1. The first variable has the correct value: " + (a = 1).
print " 2. The second variable has the correct value: " + (b = 2).
print " 3. The third variable has the correct value: " + (c = "a").

print "Testing with 'GLOBAL'".
global d is 5, e to 2.

print " 1. The first variable has the correct value: " + (d = 5).
print " 2. The second variable has the correct value: " + (e = 2).

print "Testing with 'DECLARE'".

declare f is 12, g to 1.

print " 1. The first variable has the correct value: " + (f = 12).
print " 2. The second variable has the correct value: " + (g = 1).


print "Testing with 'DECLARE GLOBAL'".

declare h is 7, i to 15, j to 3.

print " 1. The first variable has the correct value: " + (h = 7).
print " 2. The second variable has the correct value: " + (i = 15).
print " 3. The thrid variable has the correct value: " + (j = 3).
12 changes: 9 additions & 3 deletions src/kOS.Safe/Compilation/KS/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2175,7 +2175,11 @@ private ParseNode DepthFirstLeftSearch(ParseNode node, TokenType tokType)
private void VisitSetStatement(ParseNode node)
{
NodeStartHousekeeping(node);
ProcessSetOperation(node.Nodes[1], node.Nodes[3]);

for (int i = 1; i < node.Nodes.Count; i += 4)
{
ProcessSetOperation(node.Nodes[i], node.Nodes[i + 2]);
}
}

/// <summary>
Expand Down Expand Up @@ -2687,8 +2691,10 @@ private void VisitDeclareStatement(ParseNode node)
// DECLARE [GLOBAL|LOCAL] identifier TO expr.
if (lastSubNode.Token.Type == TokenType.declare_identifier_clause)
{
VisitNode(lastSubNode.Nodes[2]);
AddOpcode(CreateAppropriateStoreCode(whereToStore, true, "$" + GetIdentifierText(lastSubNode.Nodes[0])));
for (int i = 0; i < lastSubNode.Nodes.Count; i += 4) {
VisitNode(lastSubNode.Nodes[i + 2]);
AddOpcode(CreateAppropriateStoreCode(whereToStore, true, "$" + GetIdentifierText(lastSubNode.Nodes[i])));
}
}

// If the declare statement is of the form:
Expand Down
92 changes: 92 additions & 0 deletions src/kOS.Safe/Compilation/KS/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,39 @@ private void Parseset_stmt(ParseNode parent) // NonTerminalSymbol: set_stmt
// Concat Rule
Parseexpr(node); // NonTerminal Rule: expr

// Concat Rule
tok = scanner.LookAhead(TokenType.COMMA); // ZeroOrMore Rule
while (tok.Type == TokenType.COMMA)
{

// Concat Rule
tok = scanner.Scan(TokenType.COMMA); // Terminal Rule: COMMA
n = node.CreateNode(tok, tok.ToString() );
node.Token.UpdateRange(tok);
node.Nodes.Add(n);
if (tok.Type != TokenType.COMMA) {
tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.COMMA.ToString(), 0x1001, tok));
return;
}

// Concat Rule
Parsevaridentifier(node); // NonTerminal Rule: varidentifier

// Concat Rule
tok = scanner.Scan(TokenType.TO); // Terminal Rule: TO
n = node.CreateNode(tok, tok.ToString() );
node.Token.UpdateRange(tok);
node.Nodes.Add(n);
if (tok.Type != TokenType.TO) {
tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.TO.ToString(), 0x1001, tok));
return;
}

// Concat Rule
Parseexpr(node); // NonTerminal Rule: expr
tok = scanner.LookAhead(TokenType.COMMA); // ZeroOrMore Rule
}

// Concat Rule
tok = scanner.Scan(TokenType.EOI); // Terminal Rule: EOI
n = node.CreateNode(tok, tok.ToString() );
Expand Down Expand Up @@ -1332,6 +1365,65 @@ private void Parsedeclare_identifier_clause(ParseNode parent) // NonTerminalSymb
// Concat Rule
Parseexpr(node); // NonTerminal Rule: expr

// Concat Rule
tok = scanner.LookAhead(TokenType.COMMA); // ZeroOrMore Rule
while (tok.Type == TokenType.COMMA)
{

// Concat Rule
tok = scanner.Scan(TokenType.COMMA); // Terminal Rule: COMMA
n = node.CreateNode(tok, tok.ToString() );
node.Token.UpdateRange(tok);
node.Nodes.Add(n);
if (tok.Type != TokenType.COMMA) {
tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.COMMA.ToString(), 0x1001, tok));
return;
}

// Concat Rule
tok = scanner.Scan(TokenType.IDENTIFIER); // Terminal Rule: IDENTIFIER
n = node.CreateNode(tok, tok.ToString() );
node.Token.UpdateRange(tok);
node.Nodes.Add(n);
if (tok.Type != TokenType.IDENTIFIER) {
tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IDENTIFIER.ToString(), 0x1001, tok));
return;
}

// Concat Rule
tok = scanner.LookAhead(TokenType.TO, TokenType.IS); // Choice Rule
switch (tok.Type)
{ // Choice Rule
case TokenType.TO:
tok = scanner.Scan(TokenType.TO); // Terminal Rule: TO
n = node.CreateNode(tok, tok.ToString() );
node.Token.UpdateRange(tok);
node.Nodes.Add(n);
if (tok.Type != TokenType.TO) {
tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.TO.ToString(), 0x1001, tok));
return;
}
break;
case TokenType.IS:
tok = scanner.Scan(TokenType.IS); // Terminal Rule: IS
n = node.CreateNode(tok, tok.ToString() );
node.Token.UpdateRange(tok);
node.Nodes.Add(n);
if (tok.Type != TokenType.IS) {
tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected " + TokenType.IS.ToString(), 0x1001, tok));
return;
}
break;
default:
tree.Errors.Add(new ParseError("Unexpected token '" + tok.Text.Replace("\n", "") + "' found. Expected TO or IS.", 0x0002, tok));
break;
} // Choice Rule

// Concat Rule
Parseexpr(node); // NonTerminal Rule: expr
tok = scanner.LookAhead(TokenType.COMMA); // ZeroOrMore Rule
}

// Concat Rule
tok = scanner.Scan(TokenType.EOI); // Terminal Rule: EOI
n = node.CreateNode(tok, tok.ToString() );
Expand Down
4 changes: 2 additions & 2 deletions src/kOS.Safe/Compilation/KS/kRISC.tpg
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ directive -> lazyglobal_directive; // Add to this list later if we ma
// ------------ statements --------------------

empty_stmt -> EOI;
set_stmt -> SET varidentifier TO expr EOI;
set_stmt -> SET varidentifier TO expr (COMMA varidentifier TO expr)* EOI;
if_stmt -> IF expr instruction EOI? (ELSE instruction EOI?)?;
until_stmt -> UNTIL expr instruction EOI?;
fromloop_stmt -> FROM instruction_block UNTIL expr STEP instruction_block DO instruction EOI?;
Expand All @@ -172,7 +172,7 @@ remove_stmt -> REMOVE expr EOI;
log_stmt -> LOG expr TO expr EOI;
break_stmt -> BREAK EOI;
preserve_stmt -> PRESERVE EOI;
declare_identifier_clause -> IDENTIFIER (TO|IS) expr EOI;
declare_identifier_clause -> IDENTIFIER (TO|IS) expr (COMMA IDENTIFIER (TO|IS) expr)* EOI;
declare_parameter_clause -> PARAMETER IDENTIFIER ((TO|IS) expr)? (COMMA IDENTIFIER ((TO|IS) expr)?)* EOI;
declare_function_clause -> FUNCTION IDENTIFIER instruction_block EOI?;
declare_lock_clause -> LOCK IDENTIFIER TO expr EOI;
Expand Down

0 comments on commit 874e05f

Please sign in to comment.