Skip to content

Commit

Permalink
Merge branch 'master' of github.com:vddCore/EVIL
Browse files Browse the repository at this point in the history
  • Loading branch information
vddCore committed Aug 6, 2024
2 parents b6345ac + 4ed52e4 commit a13b76d
Show file tree
Hide file tree
Showing 22 changed files with 328 additions and 122 deletions.
18 changes: 18 additions & 0 deletions Core/EVIL.Grammar/AST/Expressions/WithExpression.cs
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);
}
}
}
2 changes: 1 addition & 1 deletion Core/EVIL.Grammar/EVIL.Grammar.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>

<Version>4.4.0</Version>
<Version>4.5.0</Version>

<IsPackable>false</IsPackable>
</PropertyGroup>
Expand Down
218 changes: 106 additions & 112 deletions Core/EVIL.Grammar/Parsing/Expressions/Parser.ByExpression.cs
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 };
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public partial class Parser

private Expression MultiplicativeExpression()
{
var node = ByExpression();
var node = PatternExpression();
var token = CurrentToken;

while (_multiplicativeOperators.Contains(token.Type))
Expand All @@ -25,21 +25,21 @@ private Expression MultiplicativeExpression()
{
var (line, col) = Match(Token.Multiply);

node = new BinaryExpression(node, PrefixExpression(), BinaryOperationType.Multiply)
node = new BinaryExpression(node, PatternExpression(), BinaryOperationType.Multiply)
{ Line = line, Column = col };
}
else if (token.Type == TokenType.Divide)
{
var (line, col) = Match(Token.Divide);

node = new BinaryExpression(node, PrefixExpression(), BinaryOperationType.Divide)
node = new BinaryExpression(node, PatternExpression(), BinaryOperationType.Divide)
{ Line = line, Column = col };
}
else if (token.Type == TokenType.Modulo)
{
var (line, col) = Match(Token.Modulo);

node = new BinaryExpression(node, PrefixExpression(), BinaryOperationType.Modulo)
node = new BinaryExpression(node, PatternExpression(), BinaryOperationType.Modulo)
{ Line = line, Column = col };
}

Expand Down
29 changes: 29 additions & 0 deletions Core/EVIL.Grammar/Parsing/Expressions/Parser.PatternExpression.cs
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 Core/EVIL.Grammar/Parsing/Expressions/Parser.WithExpression.cs
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 };
}
}
6 changes: 4 additions & 2 deletions Core/EVIL.Grammar/Traversal/AstVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@ protected AstVisitor()
{ typeof(ExpressionBodyStatement), (n) => Visit((ExpressionBodyStatement)n) },
{ typeof(ExtraArgumentsExpression), (n) => Visit((ExtraArgumentsExpression)n) },
{ typeof(FnExpression), (n) => Visit((FnExpression)n) },
{ typeof(IsExpression), (n) => Visit((IsExpression)n)},
{ typeof(ByExpression), (n) => Visit((ByExpression)n) }
{ typeof(IsExpression), (n) => Visit((IsExpression)n) },
{ typeof(ByExpression), (n) => Visit((ByExpression)n) },
{ typeof(WithExpression), (n) => Visit((WithExpression)n) }
};
#nullable enable
}
Expand Down Expand Up @@ -138,5 +139,6 @@ public virtual void Visit(AstNode node)
public abstract void Visit(FnExpression fnExpression);
public abstract void Visit(IsExpression isExpression);
public abstract void Visit(ByExpression byExpression);
public abstract void Visit(WithExpression withExpression);
}
}
2 changes: 1 addition & 1 deletion Core/EVIL.Lexical/EVIL.Lexical.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>

<Version>4.2.0</Version>
<Version>4.3.0</Version>

<IsPackable>false</IsPackable>
</PropertyGroup>
Expand Down
1 change: 1 addition & 0 deletions Core/EVIL.Lexical/Lexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ private Token GetIdentifierOrKeyword()
"self" => Token.Self,
"error" => Token.Error,
"retry" => Token.Retry,
"with" => Token.With,
"Infinity" => Token.Infinity,
"NaN" => Token.NaN,
"Nil" => Token.NilTypeCode,
Expand Down
Loading

0 comments on commit a13b76d

Please sign in to comment.