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); }