public override ErlangValue Evaluate(ErlangProcess process) { var result = Expression.Evaluate(process); if (result.Kind == ErlangValueKind.Error) { return(result); } switch (Operator) { case ErlangOperatorKind.Plus: return(ErlangValue.Multiply(result, ErlangNumber.One)); case ErlangOperatorKind.Minus: return(ErlangValue.Multiply(result, ErlangNumber.NegativeOne)); case ErlangOperatorKind.Not: return(ErlangValue.Not(result)); case ErlangOperatorKind.BNot: if (result.Kind == ErlangValueKind.Number) { return(ErlangNumber.BNot((ErlangNumber)result)); } else { return(new ErlangError("not integral")); } default: return(new ErlangError(string.Format("Invalid unary operator: {0}", Operator))); } }
public override ErlangValue Evaluate(ErlangProcess process) { // variable assignment or pattern match if (Operator == ErlangOperatorKind.Equals) { // first evaluate the right side var right = Right.Evaluate(process); if (right.Kind == ErlangValueKind.Error) { return(right); } // now match to the left if (ErlangBinder.TryBindParameter(Left, right, process.CallStack.CurrentFrame)) { return(right); } else { return(new ErlangError("bad match")); } } var left = Left.Evaluate(process); if (left.Kind == ErlangValueKind.Error) { return(left); } if (IsShortCircuitOperator(Operator)) { switch (Operator) { case ErlangOperatorKind.AndAlso: if (ErlangAtom.IsTrue(left)) { return(Right.Evaluate(process)); } else { return(ErlangAtom.False); } case ErlangOperatorKind.OrElse: if (ErlangAtom.IsTrue(left)) { return(left); } else { return(Right.Evaluate(process)); } default: throw new ArgumentException("invalid operator"); } } else { var right = Right.Evaluate(process); if (right.Kind == ErlangValueKind.Error) { return(right); } switch (Operator) { case ErlangOperatorKind.Plus: return(ErlangValue.Add(left, right)); case ErlangOperatorKind.Minus: return(ErlangValue.Subtract(left, right)); case ErlangOperatorKind.Asterisk: return(ErlangValue.Multiply(left, right)); case ErlangOperatorKind.Slash: return(ErlangValue.Divide(left, right)); case ErlangOperatorKind.And: return(ErlangValue.And(left, right)); case ErlangOperatorKind.Or: return(ErlangValue.Or(left, right)); case ErlangOperatorKind.Less: return(ErlangValue.Less(left, right)); case ErlangOperatorKind.EqualsLess: return(ErlangValue.LessEquals(left, right)); case ErlangOperatorKind.Greater: return(ErlangValue.Greater(left, right)); case ErlangOperatorKind.GreaterEquals: return(ErlangValue.GreaterEquals(left, right)); case ErlangOperatorKind.EqualsEquals: return(ErlangValue.EqualsEquals(left, right)); case ErlangOperatorKind.SlashEquals: return(ErlangValue.SlashEquals(left, right)); case ErlangOperatorKind.EqualsColonEquals: return(ErlangValue.EqualsColonEquals(left, right)); case ErlangOperatorKind.EqualsSlashEquals: return(ErlangValue.EqualsSlashEquals(left, right)); case ErlangOperatorKind.PlusPlus: return(ErlangValue.PlusPlus(left, right)); default: throw new ArgumentException("invalid operator"); } } }