public override IElfObject Get(RuntimeContext ctx, string name, IElfObject @this) { var b = Vault(ctx).GetBranch(name.FromElfIdentifier()); if (b == null) { throw new ReferencedBranchDoesNotExistException(Node(ctx), name); } else { if (b.IsFov()) { var eval = Session(ctx).Eval(b); var typeToken = b.GetValue("type").ContentString; var val = typeToken == "percent" ? ((double)eval) * 100 : eval; var obj_t = typeToken.GetTypeFromToken(); var obj = (IElfObject)Activator.CreateInstance(obj_t, val); obj.Bind(ctx.VM); return obj; } else { return new ScenarioNode(b); } } }
public NativeCallContext(NativeMethod source, IElfObject @this, params IElfObject[] args) { Stack = new Stack<IElfObject>(); var callScope = new Scope(); callScope.Add("@this", @this); source.FuncDef.Args.Zip(args, callScope.Add); Scopes = new Stack<Scope>(); Scopes.Push(callScope); Source = source; if (source.FuncDef.Args.Count() != args.Length) { throw new UnexpectedElfRuntimeException(@this.VM, String.Format( "Fatal error invoking native call '{0}({1})' with args '{2}'. Reason: args count mismatch.", Source.Name, Source.FuncDef.Args.StringJoin(), args.StringJoin())); } CurrentEvi = 0; PrevEvi = -1; if (source.Body.IsNullOrEmpty()) { throw new UnexpectedElfRuntimeException(@this.VM, String.Format( "Fatal error invoking native call '{0}'. Reason: empty method body.", Source.Name)); } }
public override void Set(RuntimeContext ctx, string name, IElfObject value, IElfObject @this) { var pbag = (PropertyBag)ctx.VM.Context["iactx"]; if (pbag.ContainsKey(name)) { pbag[name] = @this.VM.Marshaller.Marshal(value); return; } try { base.Set(ctx, name, value, @this); } catch (ErroneousScriptRuntimeException e) { if (e.Type == ElfExceptionType.CannotResolveVariable) { pbag.Add(name, @this.VM.Marshaller.Marshal(value)); } else { throw; } } }
public override IElfObject Get(RuntimeContext ctx, string name, IElfObject @this) { var pbag = (PropertyBag)ctx.VM.Context["iactx"]; if (pbag.ContainsKey(name)) { return @this.VM.Marshaller.Unmarshal(pbag[name]); } return base.Get(ctx, name, @this); }
public override void Declare(RuntimeContext ctx, string name, IElfObject @this) { if (name.Contains(".")) { throw new ErroneousScriptRuntimeException(ElfExceptionType.DuplicateVariableName, ctx.VM); } else { base.Declare(ctx, name, @this); } }
public override IElfObject Get(RuntimeContext ctx, string name, IElfObject @this) { var script = (ToyScript)@this.VM.Marshaller.Marshal(@this); if (name.Contains(".")) { // release code should feature type check here return @this.VM.Marshaller.Unmarshal((double)script[name]); } return base.Get(ctx, name, @this); }
public override void Set(RuntimeContext ctx, string name, IElfObject value, IElfObject @this) { var script = (ToyScript)@this.VM.Marshaller.Marshal(@this); if (script[name] != null) { // release code should feature type check here script[name] = (double)@this.VM.Marshaller.Marshal(value); return; } base.Set(ctx, name, value, @this); }
public override void Declare(RuntimeContext ctx, string name, IElfObject @this) { var pbag = (PropertyBag)ctx.VM.Context["iactx"]; if (pbag.ContainsKey(name)) { throw new ErroneousScriptRuntimeException(ElfExceptionType.DuplicateVariableName, ctx.VM); } else { base.Declare(ctx, name, @this); } }
public virtual IElfObject Get(RuntimeContext ctx, string name, IElfObject @this) { var current = ctx.CallStack.Peek(); foreach(var scope in current.Scopes) { if (scope.ContainsKey(name)) { return scope[name]; } } throw new ErroneousScriptRuntimeException(ElfExceptionType.CannotResolveVariable, @this.VM); }
public virtual void Declare(RuntimeContext ctx, string name, IElfObject @this) { var current = ctx.CallStack.Peek(); foreach(var scope in current.Scopes) { if (scope.ContainsKey(name)) { throw new ErroneousScriptRuntimeException(ElfExceptionType.DuplicateVariableName, @this.VM); } } current.Scopes.Peek().Add(name, new ElfVoid()); }
public override IElfObject Get(RuntimeContext ctx, string name, IElfObject @this) { var node = (ColaNode)ctx.VM.Context["cc_node"]; var qualifiedName = name.Contains(".") ? name : node.TPath + "." + name; var pbag = (ParametersValues)ctx.VM.Context["cc_values"]; if (pbag.ContainsKey(qualifiedName)) { return @this.VM.Marshaller.Unmarshal(pbag[qualifiedName]); } return base.Get(ctx, name, @this); }
public object Marshal(IElfObject elf) { if (elf == null) { return null; } else { if (elf is ElfVoid) { return new ElfVoid(); } else if (elf is ElfScriptDefinedClassInstance) { return ((ElfScriptDefinedClassInstance)elf).ClrObject; } else { var cast = ImplicitCasts.Where( mi => mi.GetParameters()[0].ParameterType.IsAssignableFrom(elf.GetType())).SingleOrDefault(); if (cast != null) { return cast.Invoke(null, new object[] { elf }); } else { var valprop = elf.GetType().GetProperty("Val", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); if (valprop != null && valprop.CanRead) { return valprop.GetValue(elf, null); } else { throw new NotSupportedException(String.Format( "Elf object '{0}' of type '{1}' is not supported.", elf, elf.GetType())); } } } } }
public override void Set(RuntimeContext ctx, string name, IElfObject value, IElfObject @this) { var node = (ColaNode)ctx.VM.Context["cc_node"]; var qualifiedName = name.Contains(".") ? name : node.TPath + "." + name; var pbag = (ParametersValues)ctx.VM.Context["cc_values"]; if (pbag.ContainsKey(qualifiedName)) { pbag[qualifiedName] = @this.VM.Marshaller.Marshal(value); return; } try { base.Set(ctx, name, value, @this); } catch (ErroneousScriptRuntimeException) { pbag.Add(new Parameter(qualifiedName), @this.VM.Marshaller.Marshal(value)); return; } }
public override void Declare(RuntimeContext ctx, string name, IElfObject @this) { if (name.Contains(".")) { // todo. is this behavior really unacceptable? throw new ErroneousScriptRuntimeException(ElfExceptionType.BadVariableName, ctx.VM); } else { var node = (ColaNode)ctx.VM.Context["cc_node"]; var qualifiedName = name.Contains(".") ? name : node.TPath + "." + name; var pbag = (ParametersValues)ctx.VM.Context["cc_values"]; if (pbag.ContainsKey(qualifiedName)) { throw new ErroneousScriptRuntimeException(ElfExceptionType.DuplicateVariableName, ctx.VM); } else { base.Declare(ctx, name, @this); } } }
private void ProcessCurrentEvi(NativeCallContext currentFrame, ElfVmInstruction currentEvi) { // perverted solution, but I really cba to introduce an enum for evis // neither I like solution with introduction of visitor var @this = Ctx.CallStack.Peek().Scopes.Last()["@this"]; var scopeResolver = (IScopeResolver)Activator.CreateInstance(@this.Type.ScopeResolver); var invocationResolver = (IInvocationResolver)Activator.CreateInstance(@this.Type.InvocationResolver); switch (currentEvi.GetType().Name.ToLower()) { case "decl": var decl = (Decl)currentEvi; scopeResolver.Declare(Ctx, decl.Name, @this); ++currentFrame.CurrentEvi; break; case "dup": currentFrame.Stack.Push(currentFrame.Stack.Peek()); ++currentFrame.CurrentEvi; break; case "enter": scopeResolver.EnterScope(Ctx, @this); ++currentFrame.CurrentEvi; break; case "invoke": var invoke = (Invoke)currentEvi; var args = new IElfObject[invoke.Argc]; for (var i = invoke.Argc - 1; i >= 0; --i) args[i] = currentFrame.Stack.Pop(); try {invocationResolver.PrepareCallContext(Ctx, invoke.Name, @this, args);} catch (Exception e) { // that's pretty awful, tho logically correct if (e is ErroneousScriptRuntimeException) throw; throw new UnexpectedRtimplRuntimeException(VM, String.Format( "Fatal runtime error in an Elf thread. VM dump:{0}{1}", Environment.NewLine, VM.DumpAll()), e); } if (Ctx.PendingClrCall != null) ProcessClrCall(Ctx.PendingClrCall); ++currentFrame.CurrentEvi; break; case "jf": case "jt": var test = currentFrame.Stack.Pop(); if (!(test is ElfBoolean)) { throw new ErroneousScriptRuntimeException(ElfExceptionType.ConditionNotBoolean, VM); } else { var jf = currentEvi as Jf; var jt = currentEvi as Jt; var jlabel = jf != null ? jf.Label : jt.Label; if ((((ElfBoolean)test).Val) ^ jf != null) { var target = currentFrame.Source.Body .OfType<Label>().Single(b => b.Name == jlabel); currentFrame.CurrentEvi = Array.IndexOf(currentFrame.Source.Body, target); } else { ++currentFrame.CurrentEvi; } } break; case "label": ++currentFrame.CurrentEvi; break; case "leave": scopeResolver.LeaveScope(Ctx, @this); ++currentFrame.CurrentEvi; break; case "pop": currentFrame.Stack.Pop(); ++currentFrame.CurrentEvi; break; case "popall": currentFrame.Stack.Clear(); ++currentFrame.CurrentEvi; break; case "popref": var value = currentFrame.Stack.Pop(); var popRef = (PopRef)currentEvi; try {scopeResolver.Set(Ctx, popRef.Ref, value, @this);} catch (Exception e) { // that's pretty awful, tho logically correct if (e is ErroneousScriptRuntimeException) throw; throw new UnexpectedRtimplRuntimeException(VM, String.Format( "Fatal runtime error in an Elf thread. VM dump:{0}{1}", Environment.NewLine, VM.DumpAll()), e); } ++currentFrame.CurrentEvi; break; case "pushref": var pushRef = (PushRef)currentEvi; IElfObject value2; try { value2 = scopeResolver.Get(Ctx, pushRef.Ref, @this); } catch(Exception e) { // that's pretty awful, tho logically correct if (e is ErroneousScriptRuntimeException) throw; throw new UnexpectedRtimplRuntimeException(VM, String.Format( "Fatal runtime error in an Elf thread. VM dump:{0}{1}", Environment.NewLine, VM.DumpAll()), e); } currentFrame.Stack.Push(value2); ++currentFrame.CurrentEvi; break; case "pushval": var pushVal = (PushVal)currentEvi; var value3 = VM.Marshaller.Unmarshal(pushVal.Val); currentFrame.Stack.Push(value3); ++currentFrame.CurrentEvi; break; case "ret": var retval = currentFrame.Stack.SingleOrDefault() ?? new ElfVoid(); Ctx.CallStack.Pop(); if (Ctx.CallStack.Count > 0) { Ctx.CallStack.Peek().Stack.Push(retval); } else { ExecutionResult = retval; } break; default: throw new UnexpectedElfRuntimeException(VM, String.Format( "Fatal error executing evi '{0}'. Reason: evi type '{1}' not supported.", currentEvi, currentEvi.GetType())); } }
public override void Set(RuntimeContext ctx, string name, IElfObject value, IElfObject @this) { // todo. temporarily not implemented }
public ClrCallContext(ClrMethod source, IElfObject @this, params IElfObject[] args) { Source = source; This = @this; Args = args; }
public virtual void LeaveScope(RuntimeContext ctx, IElfObject @this) { ctx.CallStack.Peek().Scopes.Pop(); }
public DefaultEntryPoint(NativeMethod codePoint, IElfObject @this, IElfObject[] args) { CodePoint = codePoint; This = @this; Args = args; }
public virtual void EnterScope(RuntimeContext ctx, IElfObject @this) { ctx.CallStack.Peek().Scopes.Push(new Scope()); }
public virtual void PrepareCallContext(RuntimeContext ctx, string name, IElfObject @this, params IElfObject[] args) { var resolved = Resolve(@this.VM, name, @this.Type, args.Select(arg => arg.Type).ToArray()); if (resolved == null) { throw new ErroneousScriptRuntimeException(ElfExceptionType.CannotResolveInvocation, ctx.VM); } else { if (resolved is NativeMethod) { // this class, elf method if (resolved.Argc == args.Length) { ctx.CallStack.Push(new NativeCallContext( (NativeMethod)resolved, @this, args)); } // other class, elf method as well else { ctx.CallStack.Push(new NativeCallContext( (NativeMethod)resolved, args[0], args.Skip(1).ToArray())); } } else { var mi = ((ClrMethod)resolved).Rtimpl; if (mi.DeclaringType != @this.Type.ClrType) { if (mi.IsConstructor) { // other class, clr ctor ctx.PendingClrCall = new ClrCallContext( (ClrMethod)resolved, null, args); } else if (mi.IsStatic) { // other class, static clr method ctx.PendingClrCall = new ClrCallContext( (ClrMethod)resolved, args[0], args); } else { // other class, instance clr method ctx.PendingClrCall = new ClrCallContext( (ClrMethod)resolved, args[0], args.Skip(1).ToArray()); } } else { if (mi.IsStatic) { // this class, static clr method ctx.PendingClrCall = new ClrCallContext( (ClrMethod)resolved, @this, @this.AsArray().Concat(args).ToArray()); } else { // this class, instance clr method ctx.PendingClrCall = new ClrCallContext( (ClrMethod)resolved, @this, args); } } } } }