Exemple #1
0
        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)));
            }
        }
Exemple #2
0
        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");
                }
            }
        }