예제 #1
0
파일: Metal.cs 프로젝트: kayateia/climoo
        public void Metal()
        {
            Runner r = new Runner();
            Action<string> adder = s =>
            r.state.scope.set( "output",
                r.state.scope.get( "output" ) + s + "\r\n" );
            r.state.scope.set( "testfunc",
            new FValue( (state, ps) => adder( "Native write: {0}\r\n".FormatI( ps[0] ) ) )
            {
                scope = r.state.scope
            }
            );
            r.state.scope.set( "metal",
            new MetalObject()
            {
                indexLookup = (state, idx) =>
                {
                    adder( "Index lookup for {0}".FormatI( idx ) );
                    state.pushResult( new LValue()
                    {
                        read = st => { adder( "Index {0} was read".FormatI( idx ) ); return 0; },
                        write = (st,val) => { adder( "Index {0} was written: {1}".FormatI( idx, val ) ); }
                    } );
                },
                memberLookup = (state, name) =>
                {
                    adder( "Member lookup for {0}".FormatI( name ) );
                    state.pushResult( new LValue()
                    {
                        read = st => { adder( "Member {0} was read".FormatI( name ) ); return 0; },
                        write = (st,val) => { adder( "Member {0} was written: {1}".FormatI( name, val ) ); }
                    } );
                }
            }
            );
            r.state.scope.set( "output", "" );
            r.setScopeCallback( st =>
            {
                if( st.StartsWithI( "#" ) )
                {
                    return st;
                }
                else
                    return null;
            }
            );

            string program = @"
            testfunc(""stuff!"")
            a = metal.foo
            metal.foo = 10
            metal.bar = a
            b = metal[5]
            metal[""bear""] = ""kitten""
            c = #10
            ";
            runAndDump( "Metal", r, program, null );
        }
예제 #2
0
 public void ConstScope()
 {
     string program = @"
     a = testconst
     b = """"
     try:
     testconst = 5
     except exc:
     b = exc
     ";
     Runner r = new Runner();
     ConstScope scope = new ConstScope( r.state.scope );
     scope.setConstant( "testconst", 10 );
     r.pushScope( scope );
     runAndDump( "ConstScope", r, program, null );
 }
예제 #3
0
파일: Player.cs 프로젝트: kayateia/climoo
        public Player( int id )
        {
            _id = id;

            // Default to acting as the player.
            _coralState = new Coral.State();
            Coral.Runner r = new Coral.Runner( _coralState );
            r.pushSecurityContext( new SecurityContext( "base", _id ) );

            // If we're anon, make a mob for it.
            if( id == Mob.Anon.id )
            {
            _anonWorld = new AnonWorld();
            _anonMob = new AnonMob( _anonWorld, this );
            _anonWorld.anonMob = _anonMob;
            }
        }
예제 #4
0
파일: CallFunc.cs 프로젝트: kayateia/climoo
 public void CallFunc()
 {
     string program = @"
     def fib(n):
     if n == 0:
     return 1
     elif n == 1:
     return 1
     else:
     return fib(n-2) + fib(n-1)
     ";
     Runner r = new Runner();
     runAndDump( "CallFunc", r, program, () =>
     {
         object rv = r.callFunction( "fib", new object[] { 5 }, typeof( int ), new StackTrace.StackFrame() );
         return "function return value: {0}".FormatI( dumpObject( rv ) );
     }
     );
 }
예제 #5
0
 void runAndDump( string name, Runner r, string code, Func<string> extra )
 {
     CodeFragment cf = Compiler.Compile( "test", code );
     r.runSync( cf );
     string results = dumpScope( r.state );
     if( extra != null )
     results += extra();
     TestCommon.CompareRef( Path.Combine( "Coral", name ), results );
 }
예제 #6
0
 void runAndDump( string name, string code )
 {
     Runner r = new Runner();
     runAndDump( name, r, code, null );
 }
예제 #7
0
파일: Player.cs 프로젝트: kayateia/climoo
 /// <summary>
 /// Pushes an actor context onto the Coral state. Do this before running code.
 /// </summary>
 public void actorContextPush( string name, int id )
 {
     Coral.Runner r = new Coral.Runner( _coralState );
     r.pushSecurityContext( new SecurityContext( name, id ) );
 }
예제 #8
0
        public void Passthrough()
        {
            PtTest pt = new PtTest();
            Passthrough pter = new Passthrough( pt );

            string program = @"
            pt.test(5, ""bob"", [""1"", ""2""], true, pt)
            pt.property = ""bar""
            a = pt.property
            b = pt.arbitrary
            c = pt.other
            pt.arbitrary = ""new value""
            d = pt.arbitrary
            pt.test2(1, 2, ""3"")

            e = """"
            def func(x):
            e += x

            pt.complex(1, func)
            f = pt.complex(2)
            g = pt.complex(3)
            h = pt.complex(4)
            i = pt.complex(5)
            j = pt.dumpcontext()

            k = 0
            try:
            pt.complex(6)
            except e:
            k = e

            l = 0
            try:
            l = pt.throwme
            except e:
            l = e

            m = 0
            try:
            pt.throwme = ""foo""
            except e:
            m = e

            n = 0
            try:
            pt.callnthrow()
            except e:
            n = e

            ";
            Runner r = new Runner();
            r.pushSecurityContext( new TestSC( "Base Context" ) );
            pter.registerConst( r.state.constScope, "pt" );
            runAndDump( "Passthrough", r, program,
            () => "object dump: {0} {1} {2} {3} {4} {5}\r\n".FormatI(
                dumpObject( pt._a ), dumpObject( pt._b ), dumpObject( pt._c ), dumpObject( pt._d ), dumpObject( pt._e ), dumpObject( pt._f )
            ) );
        }
예제 #9
0
파일: Verb.cs 프로젝트: kayateia/climoo
        public object invoke( VerbParameters param, bool coralContinuation )
        {
            // Inject the verb script blob parameters as script variables.
            var scope = new Dictionary<string, object>();
            scope["input"] = param.input;
            scope["inputwords"] = param.inputwords;
            scope["self"] = new Proxies.MobProxy(param.self, param.player);
            scope["obj"] = new Proxies.MobProxy(param.dobj, param.player);
            if (param.prep != Prep.None)
            scope["prep"] = param.prep.ToString().ToLowerInvariant();
            else
            scope["prep"] = null;
            scope["indobj"] = new Proxies.MobProxy(param.iobj, param.player);
            if (param.prep2 != Prep.None)
            scope["prep2"] = param.prep2.ToString().ToLowerInvariant();
            else
            scope["prep2"] = null;
            scope["indobj2"] = new Proxies.MobProxy(param.iobj2, param.player);

            scope["objwords"] = param.dobjwords;
            scope["prepwords"] = param.prepwords;
            scope["indobjwords"] = param.iobjwords;
            scope["prep2words"] = param.prep2words;
            scope["indobj2words"] = param.iobj2words;

            // Inject some standard MOO objects.
            scope["ambiguous"] = Proxies.MobProxy.Ambiguous;
            scope["none"] = Proxies.MobProxy.None;

            // Inject the player object.
            Proxies.PlayerProxy player = null;
            if (param.player != null)
            player = new Proxies.PlayerProxy( param.player, param.world );
            scope["player"] = player;

            // "caller" is the same as the player, unless otherwise specified.
            if (param.caller != null)
            scope["caller"] = new Proxies.MobProxy(param.caller, param.player);
            else
            scope["caller"] = player;

            scope["args"] = param.args;
            scope["world"] = new Proxies.WorldProxy(param.world, param.player);
            scope["$"] = new Proxies.MobProxy(param.world.findObject(1), param.player);
            scope["perms"] = Proxies.PermBitsProxy.Static;

            Func<string,object> querier = (name) => {
            if (name.StartsWithI("#")) {
                int number = CultureFree.ParseInt(name.Substring(1));
                if( number == Mob.Anon.id )
                {
                    Mob m = param.player.anonMob;
                    if( m != null )
                        return new Proxies.MobProxy( m, param.player );
                }
                return new Proxies.MobProxy(param.world.findObject(number), param.player);
            }
            return null;
            };

            // Is the verb valid / compiled properly?
            if( !_coral.success )
            {
            player.write( "Verb was not properly compiled." );
            if( _coral.errors != null )
            {
                foreach( var err in _coral.errors )
                    player.write( " line {0}, col {1}: {2}".FormatI( err.line, err.col, err.message ) );
            }
            return null;
            }

            // We have to run the code first, for it to define its verb.
            var runner = new Coral.Runner();
            var tempScope = new Coral.StandardScope( runner.state.baseScope );
            runner.pushScope( tempScope );
            runner.setScopeCallback( querier );
            foreach( var kv in scope )
            runner.addToScope( kv.Key, kv.Value );
            runner.runSync( _coral );
            Coral.FValue verbFunc = (Coral.FValue)tempScope.get( "verb" );
            tempScope.delete( "verb" );

            // Now that's done, hook up to the main state.
            runner = new Coral.Runner( param.player.coralState );
            runner.pushScope( tempScope );

            // Pass these on literally to any down-stream invokes.
            runner.state.baggage.set( VerbParamsKey, param );

            Coral.StackTrace.StackFrame frame = new Coral.StackTrace.StackFrame()
            {
            unitName = "<climoo>",
            funcName = "<trampoline>"
            };

            // If there wasn't one, throw a sensible error.
            if( verbFunc == null )
            throw new InvalidOperationException( "Verb does not define a function called 'verb'." );

            // Print security context debug info if the player's debug flag is set.
            if( player.get.attrHas( "debug" ) )
            {
            var value = player.get.attrGet( "debug" ).contents;
            if( value is bool && (bool)value )
            {
                string securityStack = String.Join( "->",
                    param.player.actorContextStack.Select( id => "{0}".FormatI( id ) )
                        .ToArray()
                );
                string securityText = "[color=#0cc]Running {0} as {1} ({2})[/color]".FormatI( this.name, param.player.actorContext, securityStack );
                param.player.writeError( securityText );
            }
            }

            // If we came from Coral and we're going to Coral, use a continuation.
            if( coralContinuation )
            {
            return new Coral.AsyncAction()
            {
                action = Coral.AsyncAction.Action.Call,
                function = verbFunc,
                args = param.args,
                frame = frame
            };
            }
            else
            {
            try
            {
                runner.state.scope.set( "!verb-" + this.name, verbFunc );
                return runner.callFunction( "!verb-" + this.name, param.args, typeof( object ), frame );
            }
            catch( Coral.CoralException ex )
            {
                param.player.writeError( "Unhandled exception {0}: {1}\n{2}".FormatI( ex.name, ex.Message, ex.trace ) );
                return null;
            }
            }
        }
예제 #10
0
파일: Climoo.cs 프로젝트: kayateia/climoo
        public void Climoo()
        {
            // This test does its best to simulate some conditions that might occur during
            // normal use within Climoo. It tests things like cross-module calls and exceptions.
            string program1 = @"
            def verb(arg1, arg2):
            arg1.other(arg2)

            def verb2(arg1):
            arg1.thrower()
            ";
            string program2 = @"
            def verb(arg):
            arg.foo = ""test""

            def thrower():
            inner()

            def inner():
            throw { ""name"":""inner_exception"" }
            ";
            CodeFragment prog1 = Compiler.Compile( "verb1", program1 );
            var obj = new ClimooObj( program2 );

            Runner r = new Runner();
            r.runSync( prog1 );
            var dictObj = new Dictionary<object, object>();
            dictObj["foo"] = "unset";
            r.state.scope.set( "test", dictObj );

            string rv = "";
            try
            {
            r.callFunction( "verb", new object[] {
                obj,
                dictObj
            }, typeof( object ), new StackTrace.StackFrame() );
            }
            catch( Exception ex )
            {
            rv += "Exception: " + ex + "\r\n";
            }

            try
            {
            r.callFunction( "verb2", new object[] {
                obj
            }, typeof( object ), new StackTrace.StackFrame() );
            }
            catch( CoralException ex )
            {
            rv += "CoralException: " + dumpObject( ex.data ) + "\r\n";
            }
            catch( Exception ex )
            {
            rv += "Exception: " + ex + "\r\n";
            }

            string results = dumpScope( r.state ) + rv;
            TestCommon.CompareRef( Path.Combine( "Coral", "Climoo" ), results );
        }
예제 #11
0
파일: Climoo.cs 프로젝트: kayateia/climoo
 public object callMethod( State state, string name, object[] args )
 {
     if( name == "other" )
     {
     Runner r = new Runner();
     r.runSync( _code );
     return new AsyncAction()
     {
         action = AsyncAction.Action.Call,
         function = (FValue)r.state.scope.get( "verb" ),
         args = args,
         frame = new StackTrace.StackFrame()
     };
     }
     else if( name == "thrower" )
     {
     Runner r = new Runner();
     r.runSync( _code );
     return new AsyncAction()
     {
         action = AsyncAction.Action.Call,
         function = (FValue)r.state.scope.get( "thrower" ),
         args = args,
         frame = new StackTrace.StackFrame()
     };
     }
     else
     throw new NotImplementedException();
 }
예제 #12
0
        public void Exceptions()
        {
            string program = @"
            bb = 0
            cc = 0
            dd = 0

            def deeper():
            try:
            throw { ""name"":""bar"" }
            except:
            throw { ""name"":""baz"" }
            finally:
            dd = ""yep""
            try:
            a = 10
            // throw { ""name"":""Foo"" }
            deeper()
            except b:
            bb = b
            finally:
            cc = ""foo""

            ee = 0
            try:
            try:
            throw { ""name"": ""e"" }
            except:
            pass
            finally:
            throw { ""name"": ""f"" }
            except c:
            ee = c

            ff = 0
            try:
            bob = 10 / 0
            except c:
            ff = c
            ";
            runAndDump( "Exceptions", new Runner(), program, () =>
            {
                string program2 = @"throw { ""name"": ""escaped"", ""message"":""Whee, I'm free!"" }";
                CodeFragment cf = Compiler.Compile( "test", program2 );
                try
                {
                    var r = new Runner();
                    r.runSync( cf );
                    return "second test failed";
                }
                catch( CoralException ex )
                {
                    return "second test succeeded: {0}, {1}".FormatI( ex.name, ex.Message );
                }
            }
            );
        }