コード例 #1
0
        private MObject EvalProgram(Program program, Environment env)
        {
            MObject rs = null;

            foreach (var statement in program.Statements)
            {
                rs = Eval(statement, env);

                if (rs == null)
                {
                    return(rs);
                }

                var t = rs.GetType();

                if (t == typeof(ReturnValue))
                {
                    return(((ReturnValue)rs).value);
                }
                else if (t == typeof(Error))
                {
                    return(rs);
                }
            }

            return(rs);
        }
コード例 #2
0
        private bool IsError(MObject obj)
        {
            if (obj == null)
            {
                return(false);
            }

            return(obj.MType() == ObjectType.ERROR_OBJ);
        }
コード例 #3
0
        private MObject UnwrapReturnValue(MObject obj)
        {
            if (obj.GetType() == typeof(ReturnValue))
            {
                return(((ReturnValue)obj).value);
            }

            return(obj);
        }
コード例 #4
0
        private MObject ApplyFunction(MObject fn, MObject[] args)
        {
            var function = (Function)fn;

            var extendedEnv = ExtendFunctionEnv(function, args);

            var evaluated = Eval(function.body, extendedEnv);

            return(UnwrapReturnValue(evaluated));
        }
コード例 #5
0
        public MObject Set(string name, MObject obj)
        {
            if (store.ContainsKey(name))
            {
                store[name] = obj;
            }
            else
            {
                store.Add(name, obj);
            }

            return(obj);
        }
コード例 #6
0
        private MObject EvalMinusPrefixOperatorExpression(MObject right)
        {
            if (right.MType() != ObjectType.INTEGER_OBJ)
            {
                return(NewError(string.Format("unknown operator: -%s", right.MType())));
            }

            var val = ((MInt)right).value;

            return(new MInt()
            {
                value = -val
            });
        }
コード例 #7
0
        private MObject EvalPrefixExpression(string op, MObject right, Environment env)
        {
            switch (op)
            {
            case "!":
                return(EvalBangOperatorExpression(right));

            case "-":
                return(EvalMinusPrefixOperatorExpression(right));

            default:
                return(NewError(string.Format("unknown operator: %s%s", op, right.MType())));
            }
        }
コード例 #8
0
        private MObject EvalIntegerInfixExpression(string op, MObject left, MObject right)
        {
            var lv = ((MInt)left).value;
            var rv = ((MInt)right).value;

            switch (op)
            {
            case "+":
                return(new MInt()
                {
                    value = lv + rv
                });

            case "-":
                return(new MInt()
                {
                    value = lv - rv
                });

            case "*":
                return(new MInt()
                {
                    value = lv * rv
                });

            case "/":
                return(new MInt()
                {
                    value = lv / rv
                });

            case ">":
                return(NativeBoolToMBool(lv > rv));

            case "<":
                return(NativeBoolToMBool(lv < rv));

            case "==":
                return(NativeBoolToMBool(lv == rv));

            case "!=":
                return(NativeBoolToMBool(lv != rv));

            default:
                return(NewError(string.Format("unknown operator: %s %s %s", left.MType(), op, right.MType())));
            }
        }
コード例 #9
0
        private MObject EvalBlockStatement(BlockStatement block, Environment env)
        {
            MObject rs = null;

            foreach (var statement in block.Statements)
            {
                rs = Eval(statement, env);
                if (rs != null)
                {
                    var t = rs.MType();
                    if (t == ObjectType.RETURN_VALUE_OBJ || t == ObjectType.ERROR_OBJ)
                    {
                        return(rs);
                    }
                }
            }

            return(rs);
        }
コード例 #10
0
 private MObject EvalBangOperatorExpression(MObject right)
 {
     if (right == TRUE)
     {
         return(FALSE);
     }
     else if (right == FALSE)
     {
         return(TRUE);
     }
     else if (right == NIL)
     {
         return(TRUE);
     }
     else
     {
         return(FALSE);
     }
 }
コード例 #11
0
 private bool IsTruthy(MObject obj)
 {
     if (obj == TRUE)
     {
         return(true);
     }
     else if (obj == FALSE)
     {
         return(false);
     }
     else if (obj == NIL)
     {
         return(false);
     }
     else
     {
         return(true);
     }
 }
コード例 #12
0
 private MObject EvalInfixExpression(string op, MObject left, MObject right, Environment env)
 {
     if (left.MType() == ObjectType.INTEGER_OBJ && right.MType() == ObjectType.INTEGER_OBJ)
     {
         return(EvalIntegerInfixExpression(op, left, right));
     }
     else if (op == "==")
     {
         return(NativeBoolToMBool(left == right));
     }
     else if (op == "!=")
     {
         return(NativeBoolToMBool(left != right));
     }
     else if (left.MType() != right.MType())
     {
         return(NewError(string.Format("type mismatch: %s %s %s", left.MType(), op, right.MType())));
     }
     else
     {
         return(NewError(string.Format("unknown operator: %s %s %s", left.MType(), op, right.MType())));
     }
 }