CLanguage by praeclarum

<PackageReference Include="CLanguage" Version="0.18.42" />

.NET API 204,288 bytes

 UnaryExpression

public class UnaryExpression : Expression
using CLanguage.Compiler; using CLanguage.Interpreter; using CLanguage.Types; using System; using System.Runtime.CompilerServices; namespace CLanguage.Syntax { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] public class UnaryExpression : Expression { public Unop Op { get; set; } public Expression Right { get; set; } public UnaryExpression(Unop op, Expression right) { Op = op; Right = right; } public override CType GetEvaluatedCType(EmitContext ec) { if (Op != Unop.Not) return Expression.GetPromotedType(Right, Op.ToString(), ec); return CBasicType.SignedInt; } protected override void DoEmit(EmitContext ec) { switch (Op) { case Unop.PreIncrement: new AssignExpression(Right, new BinaryExpression(Right, Binop.Add, ConstantExpression.One)).Emit(ec); break; case Unop.PreDecrement: new AssignExpression(Right, new BinaryExpression(Right, Binop.Add, ConstantExpression.NegativeOne)).Emit(ec); break; case Unop.PostIncrement: Right.Emit(ec); new AssignExpression(Right, new BinaryExpression(Right, Binop.Add, ConstantExpression.One)).Emit(ec); ec.Emit(OpCode.Pop); break; case Unop.PostDecrement: Right.Emit(ec); new AssignExpression(Right, new BinaryExpression(Right, Binop.Add, ConstantExpression.NegativeOne)).Emit(ec); ec.Emit(OpCode.Pop); break; default: { CBasicType cBasicType = (CBasicType)GetEvaluatedCType(ec); Right.Emit(ec); ec.EmitCast(Right.GetEvaluatedCType(ec), cBasicType); int instructionOffset = ec.GetInstructionOffset(cBasicType); switch (Op) { case Unop.None: break; case Unop.Negate: ec.Emit((OpCode)(168 + instructionOffset)); break; case Unop.Not: ec.Emit((OpCode)(148 + instructionOffset)); break; case Unop.BinaryComplement: ec.Emit((OpCode)(158 + instructionOffset)); break; default: throw new NotSupportedException("Unsupported unary operator '" + Op.ToString() + "'"); } break; } } } public override string ToString() { return string.Format("({0} {1})", new object[2] { Op, Right }); } public override Value EvalConstant(EmitContext ec) { if (Right.GetEvaluatedCType(ec).IsIntegral) { int num = (int)Right.EvalConstant(ec); switch (Op) { case Unop.None: return num; case Unop.Not: return (num == 0) ? 1 : 0; case Unop.Negate: return -num; case Unop.BinaryComplement: return ~num; case Unop.PreIncrement: return num + 1; case Unop.PreDecrement: return num - 1; case Unop.PostIncrement: return num; case Unop.PostDecrement: return num; default: throw new NotSupportedException("Unsupported unary operator '" + Op.ToString() + "'"); } } return base.EvalConstant(ec); } } }