Skip to content

Commit

Permalink
Turned some switch blocks into switch expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
Lehonti Ramos authored and ForNeVeR committed Oct 30, 2023
1 parent 20b4fbe commit 667b230
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 81 deletions.
87 changes: 31 additions & 56 deletions Cesium.CodeGen/ConstantEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,15 @@ public static IConstant GetConstantValue(IExpression expression)
if (constant is not IntegerConstant constInt)
throw new CompilationException("Evaluated constant is not an integer");

switch (unOp.Operator)
{
case UnaryOperator.Negation:
return new IntegerConstant(-constInt.Value);
case UnaryOperator.BitwiseNot:
return new IntegerConstant(~constInt.Value);
case UnaryOperator.LogicalNot:
return new IntegerConstant(constInt.Value != 0 ? 0 : 1);
case UnaryOperator.AddressOf:
case UnaryOperator.Indirection:
throw new CompilationException($"Operator {unOp.Operator} is not compile-time evaluable");
default:
throw new ArgumentOutOfRangeException($"Invalid unary operator {unOp.Operator}");
return unOp.Operator switch
{
UnaryOperator.Negation => new IntegerConstant(-constInt.Value),
UnaryOperator.BitwiseNot => new IntegerConstant(~constInt.Value),
UnaryOperator.LogicalNot => new IntegerConstant(constInt.Value != 0 ? 0 : 1),
UnaryOperator.AddressOf or UnaryOperator.Indirection => throw new CompilationException($"Operator {unOp.Operator} is not compile-time evaluable"),
_ => throw new ArgumentOutOfRangeException($"Invalid unary operator {unOp.Operator}"),
};
}
}

case BinaryOperatorExpression binOp:
{
Expand All @@ -46,49 +40,30 @@ public static IConstant GetConstantValue(IExpression expression)
rightConstant is not IntegerConstant rightInt)
throw new CompilationException("Evaluated constants are not integer");

switch (binOp.Operator)
{
case BinaryOperator.Add:
return new IntegerConstant(leftInt.Value + rightInt.Value);
case BinaryOperator.Subtract:
return new IntegerConstant(leftInt.Value - rightInt.Value);
case BinaryOperator.Multiply:
return new IntegerConstant(leftInt.Value * rightInt.Value);
case BinaryOperator.Divide:
return new IntegerConstant(leftInt.Value / rightInt.Value);
case BinaryOperator.Remainder:
return new IntegerConstant(leftInt.Value % rightInt.Value);
case BinaryOperator.BitwiseLeftShift:
return new IntegerConstant(leftInt.Value << rightInt.Value);
case BinaryOperator.BitwiseRightShift:
return new IntegerConstant(leftInt.Value >> rightInt.Value);
case BinaryOperator.BitwiseOr:
return new IntegerConstant(leftInt.Value | rightInt.Value);
case BinaryOperator.BitwiseAnd:
return new IntegerConstant(leftInt.Value & rightInt.Value);
case BinaryOperator.BitwiseXor:
return new IntegerConstant(leftInt.Value ^ rightInt.Value);
// boolean constants are needed here
case BinaryOperator.GreaterThan:
return new IntegerConstant(leftInt.Value > rightInt.Value ? 1 : 0);
case BinaryOperator.LessThan:
return new IntegerConstant(leftInt.Value < rightInt.Value ? 1 : 0);
case BinaryOperator.GreaterThanOrEqualTo:
return new IntegerConstant(leftInt.Value >= rightInt.Value ? 1 : 0);
case BinaryOperator.LessThanOrEqualTo:
return new IntegerConstant(leftInt.Value <= rightInt.Value ? 1 : 0);
case BinaryOperator.EqualTo:
return new IntegerConstant(leftInt.Value == rightInt.Value ? 1 : 0);
case BinaryOperator.NotEqualTo:
return new IntegerConstant(leftInt.Value != rightInt.Value ? 1 : 0);
case BinaryOperator.LogicalAnd:
return new IntegerConstant((leftInt.Value != 0) && (rightInt.Value != 0) ? 1 : 0);
case BinaryOperator.LogicalOr:
return new IntegerConstant((leftInt.Value != 0) || (rightInt.Value != 0) ? 1 : 0);
default:
throw new ArgumentOutOfRangeException($"Invalid binary operator {binOp.Operator}");
return binOp.Operator switch
{
BinaryOperator.Add => new IntegerConstant(leftInt.Value + rightInt.Value),
BinaryOperator.Subtract => new IntegerConstant(leftInt.Value - rightInt.Value),
BinaryOperator.Multiply => new IntegerConstant(leftInt.Value * rightInt.Value),
BinaryOperator.Divide => new IntegerConstant(leftInt.Value / rightInt.Value),
BinaryOperator.Remainder => new IntegerConstant(leftInt.Value % rightInt.Value),
BinaryOperator.BitwiseLeftShift => new IntegerConstant(leftInt.Value << rightInt.Value),
BinaryOperator.BitwiseRightShift => new IntegerConstant(leftInt.Value >> rightInt.Value),
BinaryOperator.BitwiseOr => new IntegerConstant(leftInt.Value | rightInt.Value),
BinaryOperator.BitwiseAnd => new IntegerConstant(leftInt.Value & rightInt.Value),
BinaryOperator.BitwiseXor => new IntegerConstant(leftInt.Value ^ rightInt.Value),
// boolean constants are needed here
BinaryOperator.GreaterThan => new IntegerConstant(leftInt.Value > rightInt.Value ? 1 : 0),
BinaryOperator.LessThan => new IntegerConstant(leftInt.Value < rightInt.Value ? 1 : 0),
BinaryOperator.GreaterThanOrEqualTo => new IntegerConstant(leftInt.Value >= rightInt.Value ? 1 : 0),
BinaryOperator.LessThanOrEqualTo => new IntegerConstant(leftInt.Value <= rightInt.Value ? 1 : 0),
BinaryOperator.EqualTo => new IntegerConstant(leftInt.Value == rightInt.Value ? 1 : 0),
BinaryOperator.NotEqualTo => new IntegerConstant(leftInt.Value != rightInt.Value ? 1 : 0),
BinaryOperator.LogicalAnd => new IntegerConstant((leftInt.Value != 0) && (rightInt.Value != 0) ? 1 : 0),
BinaryOperator.LogicalOr => new IntegerConstant((leftInt.Value != 0) || (rightInt.Value != 0) ? 1 : 0),
_ => throw new ArgumentOutOfRangeException($"Invalid binary operator {binOp.Operator}"),
};
}
}

default:
throw new CompilationException($"Expression {expression} cannot be evaluated as constant expression.");
Expand Down
13 changes: 5 additions & 8 deletions Cesium.CodeGen/Extensions/BlockItemEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,11 @@ internal static class BlockItemEx

private static IBlockItem ToIntermediate(Ast.Declaration d)
{
switch (IScopedDeclarationInfo.Of(d))
return IScopedDeclarationInfo.Of(d) switch
{
case ScopedIdentifierDeclaration declaration:
return new DeclarationBlockItem(declaration);
case TypeDefDeclaration typeDefDeclaration:
return new TypeDefBlockItem(typeDefDeclaration);
default:
throw new WipException(212, $"Unknown kind of declaration: {d}.");
}
ScopedIdentifierDeclaration declaration => new DeclarationBlockItem(declaration),
TypeDefDeclaration typeDefDeclaration => new TypeDefBlockItem(typeDefDeclaration),
_ => throw new WipException(212, $"Unknown kind of declaration: {d}."),
};
}
}
14 changes: 6 additions & 8 deletions Cesium.CodeGen/Ir/Declarations/LocalDeclarationInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Cesium.CodeGen.Ir.Declarations;
/// initializer, and is always a part of a more complex syntax construct: say, a parameter declaration or a function
/// definition.
/// </summary>
internal record LocalDeclarationInfo(
internal sealed record LocalDeclarationInfo(
IType Type,
string? Identifier,
string? CliImportMemberName)
Expand Down Expand Up @@ -291,14 +291,12 @@ private static IType ProcessDirectAbstractDeclarator(
var current = directAbstractDeclarator;
while (current != null)
{
switch (current)
throw current switch
{
default:
throw new WipException(
332,
$"Direct abstract declarator is not supported, yet: {current}.");
}

_ => new WipException(
332,
$"Direct abstract declarator is not supported, yet: {current}."),
};
current = current.Base;

Check warning on line 300 in Cesium.CodeGen/Ir/Declarations/LocalDeclarationInfo.cs

View workflow job for this annotation

GitHub Actions / main (macos-latest)

Unreachable code detected

Check warning on line 300 in Cesium.CodeGen/Ir/Declarations/LocalDeclarationInfo.cs

View workflow job for this annotation

GitHub Actions / main (macos-latest)

Unreachable code detected

Check warning on line 300 in Cesium.CodeGen/Ir/Declarations/LocalDeclarationInfo.cs

View workflow job for this annotation

GitHub Actions / main (ubuntu-latest)

Unreachable code detected

Check warning on line 300 in Cesium.CodeGen/Ir/Declarations/LocalDeclarationInfo.cs

View workflow job for this annotation

GitHub Actions / main (ubuntu-latest)

Unreachable code detected

Check warning on line 300 in Cesium.CodeGen/Ir/Declarations/LocalDeclarationInfo.cs

View workflow job for this annotation

GitHub Actions / main (windows-latest)

Unreachable code detected

Check warning on line 300 in Cesium.CodeGen/Ir/Declarations/LocalDeclarationInfo.cs

View workflow job for this annotation

GitHub Actions / main (windows-latest)

Unreachable code detected
}

Expand Down
15 changes: 6 additions & 9 deletions Cesium.Compiler/Compilation.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using System.Text;
using Cesium.CodeGen;
using Cesium.CodeGen.Contexts;
using Cesium.Core;
using Cesium.Parser;
using Cesium.Preprocessor;
using Mono.Cecil;
using System.Text;
using Yoakke.Streams;
using Yoakke.SynKit.C.Syntax;
using Yoakke.SynKit.Lexer;
Expand Down Expand Up @@ -99,15 +99,12 @@ private static async Task GenerateCode(AssemblyContext context, string inputFile
var translationUnitParseError = parser.ParseTranslationUnit();
if (translationUnitParseError.IsError)
{
switch (translationUnitParseError.Error.Got)
throw translationUnitParseError.Error.Got switch
{
case CToken token:
throw new ParseException($"Error during parsing {inputFilePath}. Error at position {translationUnitParseError.Error.Position}. Got {token.LogicalText}.");
case char ch:
throw new ParseException($"Error during parsing {inputFilePath}. Error at position {translationUnitParseError.Error.Position}. Got {ch}.");
default:
throw new ParseException($"Error during parsing {inputFilePath}. Error at position {translationUnitParseError.Error.Position}.");
}
CToken token => new ParseException($"Error during parsing {inputFilePath}. Error at position {translationUnitParseError.Error.Position}. Got {token.LogicalText}."),
char ch => new ParseException($"Error during parsing {inputFilePath}. Error at position {translationUnitParseError.Error.Position}. Got {ch}."),
_ => new ParseException($"Error during parsing {inputFilePath}. Error at position {translationUnitParseError.Error.Position}."),
};
}

var translationUnit = translationUnitParseError.Ok.Value;
Expand Down

0 comments on commit 667b230

Please sign in to comment.