Beispiel #1
0
        public LuryObject Dereference(LuryContext context)
        {
            var reference = (Reference)Value;

            if (reference.Subject == null)
            {
                if (reference.Key == null)
                {
                    return(context[reference.Object]);
                }
                else
                {
                    var obj = context[reference.Object];
                    return(LuryList.GetIndex(obj, reference.Key));
                }
            }
            else
            {
                if (reference.Key == null)
                {
                    return(reference.Subject.GetMember(reference.Object, context));
                }
                else
                {
                    return(LuryList.GetIndex(reference.Subject, reference.Key));
                }
            }
        }
Beispiel #2
0
        public override LuryObject Evaluate(LuryContext context)
        {
            var x = this.x.Evaluate(context);

            if (x == null)
            {
                throw new LuryException(LuryExceptionType.NilReference);
            }

            switch (this.operation)
            {
            case TernaryOperator.Condition:
                if (!(x is LuryBoolean))
                {
                    throw new LuryException(LuryExceptionType.ConditionValueIsNotBoolean);
                }

                if (((LuryBoolean)x).Value)
                {
                    return(this.y.Evaluate(context));
                }
                else
                {
                    return(this.z.Evaluate(context));
                }

            default:
                throw new InvalidOperationException();
            }
        }
Beispiel #3
0
        public LuryObject Assign(LuryContext context, LuryObject @object)
        {
            var reference = (Reference)Value;

            if (reference.Subject == null)
            {
                if (reference.Key == null)
                {
                    context[reference.Object] = @object;
                }
                else
                {
                    var obj = context[reference.Object];
                    LuryList.SetIndex(obj, reference.Key, @object);
                }
            }
            else
            {
                if (reference.Key == null)
                {
                    reference.Subject.SetMember(reference.Object, @object);
                }
                else
                {
                    LuryList.SetIndex(reference.Subject, reference.Key, @object);
                }
            }

            return(@object);
        }
Beispiel #4
0
        public override StatementExit Evaluate(LuryContext context)
        {
            if (this.condition == null)
            {
                // else block
                return(this.suite.Evaluate(new LuryContext(context)));
            }
            else
            {
                // if block
                var cond = this.condition.Evaluate(new LuryContext(context));

                if (cond == null)
                {
                    throw new LuryException(LuryExceptionType.NilReference);
                }

                if (!(cond is LuryBoolean))
                {
                    throw new LuryException(LuryExceptionType.ConditionValueIsNotBoolean);
                }

                if (cond == LuryBoolean.True)           // if suite
                {
                    return(this.suite.Evaluate(new LuryContext(context)));
                }
                else if (this.nextIf != null)           // elif block
                {
                    return(this.nextIf.Evaluate(new LuryContext(context)));
                }
            }

            return(StatementExit.NormalExit);
        }
Beispiel #5
0
        public override LuryObject Evaluate(LuryContext context)
        {
            if (!(this.target is LValueNode))
            {
                throw new LuryException(LuryExceptionType.WrongLValue);
            }

            var lvalue   = (LValueNode)this.target;
            var dr_value = lvalue.Evaluate(context);

            switch (this.operation)
            {
            case UnaryAssignOperator.IncrementPostfix:
                lvalue.Assign(dr_value.Inc(), context);
                return(dr_value);

            case UnaryAssignOperator.DecrementPostfix:
                lvalue.Assign(dr_value.Dec(), context);
                return(dr_value);

            case UnaryAssignOperator.IncrementPrefix:
                dr_value = dr_value.Inc();
                lvalue.Assign(dr_value, context);
                return(dr_value);

            case UnaryAssignOperator.DecrementPrefix:
                dr_value = dr_value.Dec();
                lvalue.Assign(dr_value, context);
                return(dr_value);

            default:
                throw new InvalidOperationException();
            }
        }
Beispiel #6
0
        public static LuryObject Call(LuryObject self, params object[] others)
        {
            var methodInfo = self.Value as MethodInfo;

            if (methodInfo != null)
            {
                return((LuryObject)methodInfo.Invoke(null, BindingFlags.Default, null, others, null));
            }

            var functionInfo = self.Value as UserFunctionInfo;

            if (functionInfo != null)
            {
                var param = functionInfo.ParameterNames.ToArray();

                if (param.Length != others.Length)
                {
                    throw new InvalidOperationException();
                }

                var context = new LuryContext(functionInfo.ParentContext);

                for (var i = 0; i < param.Length; i++)
                {
                    context[param[i]] = (LuryObject)others[i];
                }

                return(new LuryVisitor(context).VisitSuite(functionInfo.BodySuite));
            }

            throw new NotImplementedException();
        }
Beispiel #7
0
        /// <summary>
        /// コンパイルするコードを指定してコンパイルし、実行します。
        /// </summary>
        /// <param name="code">コンパイルされるコード文字列。</param>
        /// <returns>コンパイルに成功したとき true、それ以外のとき false。</returns>
        public LuryObject Evaluate(string code)
        {
            var lexer           = new Lexer.Lexer(code + '\n');
            var succeedTokenize = lexer.Tokenize();

            lexer.Logger.CopyTo(this.OutputLogger);

            if (!succeedTokenize)
            {
                return(null);
            }

            var globalContext = new LuryContext();

            Intrinsic.SetBuiltInFunctions(globalContext);

            var     parser  = new Parser();
            Routine routine = null;

            // parsing
            try
            {
                routine = (Routine)parser.yyparse(new Lex2yyInput(lexer), new yydebug.yyDebugSimple());
            }
            catch (yyParser.yyException ex)
            {
                this.ReportyyException(ex, code);
                return(null);
            }

            // running
            if (routine == null)
            {
                return(null);
            }
            else
            {
                try
                {
                    var exit = routine.Evaluate(globalContext);

                    if (exit.ExitReason == StatementExitReason.Break)
                    {
                        throw new LuryException(LuryExceptionType.WrongBreak);
                    }

                    return(exit.ReturnValue);
                }
                catch (LuryException ex)
                {
                    Console.Error.WriteLine(ex.Message);
                    return(null);
                }
            }
        }
Beispiel #8
0
 public override StatementExit Evaluate(LuryContext context)
 {
     if (this.returnValue == null)
     {
         return(new StatementExit(null, StatementExitReason.Return));
     }
     else
     {
         return(new StatementExit(this.returnValue.Evaluate(context), StatementExitReason.Return));
     }
 }
Beispiel #9
0
        public override LuryObject Evaluate(LuryContext context)
        {
            var parentObj = this.parent.Evaluate(context);

            if (parentObj == null)
            {
                throw new LuryException(LuryExceptionType.NilReference);
            }

            return(parentObj[this.child]);
        }
Beispiel #10
0
        public override LuryObject Evaluate(LuryContext context)
        {
            var objects = this.param.Select(p => p == null ? null : p.Evaluate(context)).ToArray();
            var func    = this.function.Evaluate(context);

            if (func == null)
            {
                throw new LuryException(LuryExceptionType.NilReference);
            }

            return(func.Call(objects));
        }
Beispiel #11
0
        public override StatementExit Evaluate(LuryContext context)
        {
            StatementExit exit;
            var           newContext = new LuryContext(context);

            while (true)
            {
                var cond = this.condition.Evaluate(newContext);

                if (cond == null)
                {
                    throw new LuryException(LuryExceptionType.NilReference);
                }

                if (!(cond is LuryBoolean))
                {
                    throw new LuryException(LuryExceptionType.ConditionValueIsNotBoolean);
                }

                if (cond == LuryBoolean.True)
                {
                    exit = this.suite.Evaluate(newContext);

                    if (exit.ExitReason == StatementExitReason.Break)
                    {
                        break;
                    }
                    else if (exit.ExitReason == StatementExitReason.Continue ||
                             exit.ExitReason == StatementExitReason.NormalExit)
                    {
                        continue;
                    }
                    else
                    {
                        return(exit);
                    }
                }
                else
                {
                    if (this.elseSuite != null)
                    {
                        return(this.elseSuite.Evaluate(new LuryContext(context)));
                    }

                    break;
                }
            }

            return(StatementExit.NormalExit);
        }
Beispiel #12
0
        public StatementExit Evaluate(LuryContext context)
        {
            var ret = StatementExit.NormalExit;

            foreach (var statement in this.statements)
            {
                ret = statement.Evaluate(context);

                if (ret.ExitReason != StatementExitReason.NormalExit)
                {
                    break;
                }
            }

            return(ret);
        }
Beispiel #13
0
        public override LuryObject VisitFor_statement(LuryParser.For_statementContext context)
        {
            // for block
            var forCount = 0;

            currentContext = new LuryContext(currentContext);
            try
            {
                var        @object   = VisitExpression(context.Object);
                var        iterator  = LuryFunction.Call(@object.GetMember(IntrinsicConstants.FunctionIterate, currentContext), @object);
                var        moveNext  = LuryFunction.Call(iterator.GetMember(IntrinsicConstants.FunctionMoveNext, currentContext), iterator);
                var        variable  = context.Variable.Text;
                LuryObject forReturn = null;

                while (moveNext.Equals(LuryBoolean.True))
                {
                    forCount++;
                    var fetchedValue = LuryFunction.Call(iterator.GetMember(IntrinsicConstants.FunctionFetch, currentContext), iterator);
                    currentContext[variable] = fetchedValue;
                    forReturn = VisitSuite(context.ForSuite);
                    moveNext  = LuryFunction.Call(iterator.GetMember(IntrinsicConstants.FunctionMoveNext, currentContext), iterator);
                }

                if (forCount > 0)
                {
                    return(forReturn);
                }
            }
            finally { currentContext = currentContext.Parent; }

            // else block
            if (forCount <= 0 || context.ElseSuite == null)
            {
                return(null);
            }

            LuryObject elseReturn;

            currentContext = new LuryContext(currentContext);
            try
            {
                elseReturn = VisitSuite(context.ElseSuite);
            }
            finally { currentContext = currentContext.Parent; }

            return(elseReturn);
        }
Beispiel #14
0
        private LuryObject Invoke(LuryContext context)
        {
            var exit = this.suite.Evaluate(context);

            if (exit.ExitReason == StatementExitReason.Return)
            {
                return(exit.ReturnValue);
            }
            else if (exit.ExitReason == StatementExitReason.NormalExit)
            {
                return(null);
            }
            else
            {
                throw new LuryException(LuryExceptionType.WrongBreak);
            }
        }
Beispiel #15
0
        public override LuryObject Evaluate(LuryContext context)
        {
            var obj = this.lvalue.Evaluate(context);

            if (obj == null)
            {
                throw new LuryException(LuryExceptionType.NilReference);
            }

            if (obj is LuryFunction)
            {
                return(obj.Call());
            }
            else
            {
                return(obj);
            }
        }
Beispiel #16
0
        public override void Assign(LuryObject value, LuryContext context)
        {
            var parentObj = this.parent.Evaluate(context);

            if (parentObj == null)
            {
                throw new LuryException(LuryExceptionType.NilReference);
            }

            if (parentObj.Has(this.child))
            {
                parentObj[this.child] = value;
            }
            else
            {
                throw new LuryException(LuryExceptionType.AttributeIsNotFound);
            }
        }
Beispiel #17
0
        public override StatementExit Evaluate(LuryContext context)
        {
            this.name.Assign(new LuryFunction(args =>
            {
                var newContext = new LuryContext(context);
                var paramCount = (this.parameters == null ? 0 : this.parameters.Count);

                if (args.Length != paramCount)
                {
                    throw new LuryException(LuryExceptionType.NotEnoughFunctionArgumentNumber);
                }

                for (int i = 0; i < args.Length; i++)
                {
                    newContext.SetMemberNoRecursion(this.parameters[i], args[i]);
                }

                return(this.Invoke(newContext));
            }), context);

            return(StatementExit.NormalExit);
        }
Beispiel #18
0
        public override LuryObject Evaluate(LuryContext context)
        {
            if (this.operation == UnaryOperator.Reference)
            {
                if (!(this.target is LValueNode))
                {
                    throw new LuryException(LuryExceptionType.WrongRefReference);
                }

                return(this.target.Evaluate(context));
            }

            var value = this.target.Evaluate(context);

            if (value == null)
            {
                throw new LuryException(LuryExceptionType.NilReference);
            }

            switch (this.operation)
            {
            case UnaryOperator.SignNegative:
                return(value.Neg());

            case UnaryOperator.SignPositive:
                return(value.Pos());

            case UnaryOperator.BitwiseNot:
                return(value.BNot());

            case UnaryOperator.LogicalNot:
                return(value.LNot());

            default:
                throw new InvalidOperationException();
            }
        }
Beispiel #19
0
        public override LuryObject VisitIf_statement(LuryParser.If_statementContext context)
        {
            // if block
            currentContext = new LuryContext(currentContext);
            try
            {
                var condition = VisitExpression(context.Condition) as LuryBoolean;

                if (condition == null)
                {
                    throw new InvalidOperationException();
                }

                if ((bool)condition.Value)
                {
                    return(VisitSuite(context.IfSuite));
                }
            }
            finally { currentContext = currentContext.Parent; }

            // else block
            if (context.ElseSuite == null)
            {
                return(null);
            }

            LuryObject elseReturn;

            currentContext = new LuryContext(currentContext);
            try
            {
                elseReturn = VisitSuite(context.ElseSuite);
            }
            finally { currentContext = currentContext.Parent; }

            return(elseReturn);
        }
Beispiel #20
0
 public override StatementExit Evaluate(LuryContext context)
 {
     this.expression.Evaluate(context);
     return(StatementExit.NormalExit);
 }
Beispiel #21
0
 public override void Assign(LuryObject value, LuryContext context)
 {
     this.lvalue.Assign(value, context);
 }
Beispiel #22
0
 public abstract void Assign(LuryObject value, LuryContext context);
Beispiel #23
0
 public abstract LuryObject Evaluate(LuryContext context);
Beispiel #24
0
 public virtual StatementExit Evaluate(LuryContext context)
 {
     return(null);
 }
Beispiel #25
0
 public override LuryObject Evaluate(LuryContext context)
 {
     return(context[this.reference]);
 }
Beispiel #26
0
 public override void Assign(LuryObject value, LuryContext context)
 {
     context[this.reference] = value;
 }
Beispiel #27
0
        public override LuryObject Evaluate(LuryContext context)
        {
            if (!(this.lvalue is LValueNode))
            {
                throw new LuryException(LuryExceptionType.WrongLValue);
            }

            var dst   = (LValueNode)lvalue;
            var value = this.rvalue.Evaluate(context);

            if (this.operation == BinaryAssignOperator.Assign)
            {
                dst.Assign(value, context);
                return(value);
            }

            var dstValue = dst.Evaluate(context);

            switch (this.operation)
            {
            case BinaryAssignOperator.Power:
                value = dstValue.Pow(value);
                break;

            case BinaryAssignOperator.Multiplication:
                value = dstValue.Mul(value);
                break;

            case BinaryAssignOperator.Division:
                value = dstValue.Div(value);
                break;

            case BinaryAssignOperator.IntDivision:
                value = dstValue.IDiv(value);
                break;

            case BinaryAssignOperator.Modulo:
                value = dstValue.Mod(value);
                break;

            case BinaryAssignOperator.Addition:
                value = dstValue.Add(value);
                break;

            case BinaryAssignOperator.Subtraction:
                value = dstValue.Sub(value);
                break;

            case BinaryAssignOperator.Concatenation:
                value = dstValue.Con(value);
                break;

            case BinaryAssignOperator.LeftShift:
                value = dstValue.Shl(value);
                break;

            case BinaryAssignOperator.RightShift:
                value = dstValue.Shr(value);
                break;

            case BinaryAssignOperator.ArithmeticAnd:
                value = dstValue.BAnd(value);
                break;

            case BinaryAssignOperator.ArithmeticXor:
                value = dstValue.BXor(value);
                break;

            case BinaryAssignOperator.ArithmeticOr:
                value = dstValue.BOr(value);
                break;

            default:
                throw new InvalidOperationException();
            }

            dst.Assign(value, context);
            return(value);
        }
Beispiel #28
0
        public override LuryObject Evaluate(LuryContext context)
        {
            var x = this.x.Evaluate(context);
            var y = this.y.Evaluate(context);

            if (x == null)
            {
                throw new LuryException(LuryExceptionType.NilReference);
            }

            switch (this.operation)
            {
            case BinaryOperator.Power:
                return(x.Pow(y));

            case BinaryOperator.Multiplication:
                return(x.Mul(y));

            case BinaryOperator.Division:
                return(x.Div(y));

            case BinaryOperator.IntDivision:
                return(x.IDiv(y));

            case BinaryOperator.Modulo:
                return(x.Mod(y));

            case BinaryOperator.Addition:
                return(x.Add(y));

            case BinaryOperator.Subtraction:
                return(x.Sub(y));

            case BinaryOperator.Concatenation:
                return(x.Con(y));

            case BinaryOperator.LeftShift:
                return(x.Shl(y));

            case BinaryOperator.RightShift:
                return(x.Shl(y));

            case BinaryOperator.ArithmeticAnd:
                return(x.BAnd(y));

            case BinaryOperator.ArithmeticXor:
                return(x.BXor(y));

            case BinaryOperator.ArithmeticOr:
                return(x.BOr(y));

            case BinaryOperator.LogicalAnd:
                return(x.LAnd(y));

            case BinaryOperator.LogicalOr:
                return(x.LOr(y));

            case BinaryOperator.LessThan:
                return(x.CLt(y));

            case BinaryOperator.GreaterThan:
                return(x.CGt(y));

            case BinaryOperator.LessThanEqual:
                return(x.CELt(y));

            case BinaryOperator.GreaterThanEqual:
                return(x.CEGt(y));

            case BinaryOperator.Equal:
                return(x.CEq(y));

            case BinaryOperator.NotEqual:
                return(x.CNe(y));

            case BinaryOperator.Is:
                return(x.Is(y));

            case BinaryOperator.IsNot:
                return(x.IsNot(y));

            default:
                throw new InvalidOperationException();
            }
        }
Beispiel #29
0
 public LuryVisitor(LuryContext globalContext)
 {
     this.globalContext = globalContext;
     currentContext     = globalContext;
 }
Beispiel #30
0
 public override LuryObject Evaluate(LuryContext context)
 {
     return(this.constant);
 }