示例#1
0
        internal static dynamic Resolve(object rawName, object rawScope)
        {
            if (rawName.GetType() == typeof(InstanceReference))
            {
                var iref   = (InstanceReference)rawName;
                var lval   = CompilerServices.CompileExpression(iref.LValue, (KumaScope)rawScope);
                var gmArgs = new List <Expression> ();
                gmArgs.Add(Expression.Constant(lval, typeof(object)));
                return(Dynamic(typeof(object), new InteropBinder.GetMember(iref.Key, (KumaScope)rawScope), gmArgs));
            }
            var name  = (string)rawName;
            var scope = (KumaScope)rawScope;

            if (name.StartsWith("$") && name != "$:")
            {
                scope = scope.GlobalScope;
                name  = name.Substring(1);
            }
            if (name.StartsWith("@") && scope["<kuma_context_invokemember>"] != null)
            {
                if (name.StartsWith("@@"))
                {
                    var _val = Resolve("self", scope);
                    if (!(_val is KumaInstance))
                    {
                        // native object?
                        _val = Kuma.Box((object)_val, scope);
                    }
                    var @class = ((KumaInstance)_val).Class;
                    return
                        (CompilerServices.CompileExpression(
                             KumaExpression.Variable(KumaExpression.InstanceRef(Expression.Constant(@class),
                                                                                Expression.Constant(name.Substring(2)))), scope));
                }
                return
                    (CompilerServices.CompileExpression(
                         KumaExpression.Variable(
                             KumaExpression.InstanceRef(KumaExpression.Variable(Expression.Constant("self")),
                                                        Expression.Constant(name.Substring(1)))), scope));
            }

            var val = scope[name];

            // The cast is needed here because if we get a non-nullable type (such as System.Int32) the check here will throw an exception.
            // By casting to System.Object we can avoid the exception since it is a boxed value that can be null.
            if ((object)val == null)
            {
                Type type;
                if ((type = KumaTypeResolver.Resolve(name)) != null)
                {
                    var @class = KumaClass.BoxClass(type);
                    scope.GlobalScope[@class.Name] = @class;
                    val = @class;
                }
            }
            return(val);
        }
 internal static dynamic Include(List <string> names)
 {
     // this has a different meaning when were defining classes
     if (!_inClassDefine)
     {
         var s = new StringBuilder();
         names.ForEach(name => s.AppendFormat("{0}.", name));
         s.Remove(s.Length - 1, 1);
         KumaTypeResolver.Include(s.ToString());
         return(null);
     }
     return(null);
 }
        internal static dynamic Begin(object rawTryExpression, List <Expression> rescueBlocksRaw,
                                      object rawEnsureBlock, object rawElseBlock, object rawScope)
        {
            var     tryExpression   = (Expression)rawTryExpression;
            var     ensureBlock     = (Expression)rawEnsureBlock;
            var     elseBlock       = (Expression)rawElseBlock;
            var     scope           = (KumaScope)rawScope;
            dynamic retVal          = null;
            var     exceptionRaised = false;
            var     ensureRun       = false;
            var     rescueBlocks    = new List <RescueExpression>();

            rescueBlocksRaw.ForEach(
                rawBlock =>
            {
                var block = rawBlock as RescueExpression;
                if (block != null)
                {
                    rescueBlocks.Add(block);
                }
            });

            try
            {
                retVal = CompilerServices.CompileExpression(tryExpression, scope);
            }
            catch (Exception e)
            {
                var KumaException = e as KumaException;
                var exType        = KumaException != null ? KumaException.ExceptionClass.Name : e.GetType().Name;
                var found         = false;
                exceptionRaised = true;
                foreach (var rescueBlock in rescueBlocks)
                {
                    var exceptionTypes = new List <string>();
                    if (!rescueBlock.IsWildcard)
                    {
                        foreach (var type in rescueBlock.ExceptionTypes)
                        {
                            var obj      = Resolve(type, scope);
                            var instance = obj as KumaInstance;
                            if (instance != null)
                            {
                                exceptionTypes.Add(instance.Class.Name);
                            }
                            else
                            {
                                var @class = obj as KumaClass;
                                if (@class != null)
                                {
                                    exceptionTypes.Add(@class.Name);
                                }
                                var s = obj as string;
                                if (s != null)
                                {
                                    exceptionTypes.Add(s);
                                }
                                var ss = obj as KumaString;
                                if (ss != null)
                                {
                                    exceptionTypes.Add(ss);
                                }
                            }
                        }
                    }
                    var exMatches = rescueBlock.IsWildcard;
                    if (!exMatches)
                    {
                        if ((from type in exceptionTypes select KumaTypeResolver.Resolve(type) into _exType where _exType != null let __exType = KumaTypeResolver.Resolve(exType) where __exType != null && __exType.IsSubclassOf(_exType) || __exType == _exType select _exType).Any())
                        {
                            exMatches = true;
                        }
                    }
                    found = exMatches;
                    if (!found)
                    {
                        if (exceptionTypes.Contains(exType))
                        {
                            found = true;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    var exception = e as KumaException;
                    if (exception != null)
                    {
                        scope[rescueBlock.VarName] = exception.InnerObject;
                    }
                    else
                    {
                        scope[rescueBlock.VarName] = e;
                    }
                    try
                    {
                        retVal = CompilerServices.CompileExpression(rescueBlock.Body, scope);
                    }
                    catch (Exception)
                    {
                        if (ensureBlock == null)
                        {
                            throw;
                        }
                        ensureRun = true;
                        CompilerServices.CompileExpression(ensureBlock, scope);
                        throw;
                    }
                    break;
                }
                if (!found)
                {
                    throw;
                }
            }
            finally
            {
                if (!exceptionRaised && elseBlock != null)
                {
                    CompilerServices.CompileExpression(elseBlock, scope);
                }
                if (!ensureRun && ensureBlock != null)
                {
                    CompilerServices.CompileExpression(ensureBlock, scope);
                }
            }
            return(retVal);
        }