-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' of github.com:vddCore/EVIL
- Loading branch information
Showing
22 changed files
with
328 additions
and
122 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using EVIL.Grammar.AST.Base; | ||
|
||
namespace EVIL.Grammar.AST.Expressions | ||
{ | ||
public class WithExpression : Expression | ||
{ | ||
public Expression BaseExpression { get; } | ||
public TableExpression TableExpansionExpression { get; } | ||
|
||
public WithExpression(Expression baseExpression, TableExpression tableExpansionExpression) | ||
{ | ||
BaseExpression = baseExpression; | ||
TableExpansionExpression = tableExpansionExpression; | ||
|
||
Reparent(BaseExpression, TableExpansionExpression); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
218 changes: 106 additions & 112 deletions
218
Core/EVIL.Grammar/Parsing/Expressions/Parser.ByExpression.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,131 +1,125 @@ | ||
namespace EVIL.Grammar.Parsing; | ||
|
||
using System.Collections.Generic; | ||
using EVIL.Grammar.AST.Base; | ||
using EVIL.Grammar.AST.Expressions; | ||
using EVIL.Grammar.AST.Miscellaneous; | ||
using EVIL.Lexical; | ||
|
||
namespace EVIL.Grammar.Parsing | ||
public partial class Parser | ||
{ | ||
public partial class Parser | ||
private ByExpression ByExpression() | ||
{ | ||
private Expression ByExpression() | ||
var (line, col) = Match(Token.By); | ||
|
||
var qualifier = AssignmentExpression(); | ||
Match(Token.LBrace); | ||
|
||
var arms = new List<ByArmNode>(); | ||
AstNode? elseArm = null; | ||
|
||
while (true) | ||
{ | ||
if (CurrentToken.Type == TokenType.By) | ||
if (CurrentToken.Type == TokenType.EOF) | ||
{ | ||
throw new ParserException( | ||
"Unexpected EOF in a by-expression.", | ||
(CurrentToken.Line, CurrentToken.Column) | ||
); | ||
} | ||
|
||
var (armLine, armCol) = (CurrentToken.Line, CurrentToken.Column); | ||
|
||
if (CurrentToken.Type == TokenType.RBrace) | ||
{ | ||
if (arms.Count == 0) | ||
{ | ||
throw new ParserException( | ||
"Empty by-expressions are not allowed.", | ||
(line, col) | ||
); | ||
} | ||
} | ||
|
||
if (CurrentToken.Type == TokenType.Else) | ||
{ | ||
if (arms.Count == 0) | ||
{ | ||
throw new ParserException( | ||
"'else' is illegal with no selector arms specified.", | ||
(armLine, armCol) | ||
); | ||
} | ||
|
||
Match(Token.Else); | ||
Match(Token.Colon); | ||
|
||
if (CurrentToken.Type == TokenType.Throw) | ||
{ | ||
elseArm = ThrowStatement(); | ||
} | ||
else | ||
{ | ||
elseArm = AssignmentExpression(); | ||
} | ||
|
||
|
||
if (CurrentToken.Type != TokenType.RBrace) | ||
{ | ||
throw new ParserException( | ||
"'else' arm must be specified at the end of selector list.", | ||
(armLine, armCol) | ||
); | ||
} | ||
|
||
break; | ||
} | ||
else | ||
{ | ||
var (line, col) = Match(Token.By); | ||
var selector = AssignmentExpression(); | ||
var deepEquality = false; | ||
|
||
var qualifier = AssignmentExpression(); | ||
Match(Token.LBrace); | ||
if (CurrentToken.Type == TokenType.RightArrow) | ||
{ | ||
Match(Token.RightArrow); | ||
deepEquality = false; | ||
} | ||
else if (CurrentToken.Type == TokenType.Associate) | ||
{ | ||
Match(Token.Associate); | ||
deepEquality = true; | ||
} | ||
else | ||
{ | ||
throw new ParserException( | ||
$"Expected '->' or '=>', found '{CurrentToken.Value}'.", | ||
(CurrentToken.Line, CurrentToken.Column) | ||
); | ||
} | ||
|
||
var arms = new List<ByArmNode>(); | ||
AstNode? elseArm = null; | ||
|
||
while (true) | ||
AstNode valueArm; | ||
if (CurrentToken.Type == TokenType.Throw) | ||
{ | ||
if (CurrentToken.Type == TokenType.EOF) | ||
{ | ||
throw new ParserException( | ||
"Unexpected EOF in a by-expression.", | ||
(CurrentToken.Line, CurrentToken.Column) | ||
); | ||
} | ||
|
||
var (armLine, armCol) = (CurrentToken.Line, CurrentToken.Column); | ||
|
||
if (CurrentToken.Type == TokenType.RBrace) | ||
{ | ||
if (arms.Count == 0) | ||
{ | ||
throw new ParserException( | ||
"Empty by-expressions are not allowed.", | ||
(line, col) | ||
); | ||
} | ||
} | ||
|
||
if (CurrentToken.Type == TokenType.Else) | ||
{ | ||
if (arms.Count == 0) | ||
{ | ||
throw new ParserException( | ||
"'else' is illegal with no selector arms specified.", | ||
(armLine, armCol) | ||
); | ||
} | ||
|
||
Match(Token.Else); | ||
Match(Token.Colon); | ||
|
||
if (CurrentToken.Type == TokenType.Throw) | ||
{ | ||
elseArm = ThrowStatement(); | ||
} | ||
else | ||
{ | ||
elseArm = AssignmentExpression(); | ||
} | ||
|
||
|
||
if (CurrentToken.Type != TokenType.RBrace) | ||
{ | ||
throw new ParserException( | ||
"'else' arm must be specified at the end of selector list.", | ||
(armLine, armCol) | ||
); | ||
} | ||
|
||
break; | ||
} | ||
else | ||
{ | ||
var selector = AssignmentExpression(); | ||
var deepEquality = false; | ||
|
||
if (CurrentToken.Type == TokenType.RightArrow) | ||
{ | ||
Match(Token.RightArrow); | ||
deepEquality = false; | ||
} | ||
else if (CurrentToken.Type == TokenType.Associate) | ||
{ | ||
Match(Token.Associate); | ||
deepEquality = true; | ||
} | ||
else | ||
{ | ||
throw new ParserException( | ||
$"Expected '->' or '=>', found '{CurrentToken.Value}'.", | ||
(CurrentToken.Line, CurrentToken.Column) | ||
); | ||
} | ||
|
||
AstNode valueArm; | ||
if (CurrentToken.Type == TokenType.Throw) | ||
{ | ||
valueArm = ThrowStatement(); | ||
} | ||
else | ||
{ | ||
valueArm = AssignmentExpression(); | ||
} | ||
|
||
arms.Add(new ByArmNode(selector, valueArm, deepEquality) { Line = armLine, Column = armCol }); | ||
} | ||
|
||
if (CurrentToken.Type == TokenType.RBrace) | ||
{ | ||
break; | ||
} | ||
|
||
Match(Token.Comma); | ||
valueArm = ThrowStatement(); | ||
} | ||
else | ||
{ | ||
valueArm = AssignmentExpression(); | ||
} | ||
|
||
arms.Add(new ByArmNode(selector, valueArm, deepEquality) { Line = armLine, Column = armCol }); | ||
} | ||
|
||
Match(Token.RBrace); | ||
return new ByExpression(qualifier, arms, elseArm) { Line = line, Column = col }; | ||
if (CurrentToken.Type == TokenType.RBrace) | ||
{ | ||
break; | ||
} | ||
return PrefixExpression(); | ||
|
||
Match(Token.Comma); | ||
} | ||
|
||
Match(Token.RBrace); | ||
|
||
return new ByExpression(qualifier, arms, elseArm) { Line = line, Column = col }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
Core/EVIL.Grammar/Parsing/Expressions/Parser.PatternExpression.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using EVIL.Grammar.AST.Base; | ||
using EVIL.Lexical; | ||
|
||
namespace EVIL.Grammar.Parsing | ||
{ | ||
public partial class Parser | ||
{ | ||
private Expression PatternExpression() | ||
{ | ||
if (CurrentToken.Type == TokenType.By) | ||
{ | ||
return ByExpression(); | ||
} | ||
else | ||
{ | ||
var node = PrefixExpression(); | ||
var token = CurrentToken; | ||
|
||
while (token.Type == TokenType.With) | ||
{ | ||
node = WithExpression(node); | ||
token = CurrentToken; | ||
} | ||
|
||
return node; | ||
} | ||
} | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
Core/EVIL.Grammar/Parsing/Expressions/Parser.WithExpression.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
namespace EVIL.Grammar.Parsing; | ||
|
||
using EVIL.Grammar.AST.Base; | ||
using EVIL.Grammar.AST.Expressions; | ||
using EVIL.Lexical; | ||
|
||
public partial class Parser | ||
{ | ||
private WithExpression WithExpression(Expression left) | ||
{ | ||
var (line, col) = Match(Token.With); | ||
|
||
var tableExpansion = TableExpression(); | ||
|
||
if (!tableExpansion.Keyed) | ||
{ | ||
throw new ParserException( | ||
"Table expansion expression must be a keyed table.", | ||
(tableExpansion.Line, tableExpansion.Column) | ||
); | ||
} | ||
|
||
return new WithExpression(left, tableExpansion) | ||
{ Line = line, Column = col }; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.