private static object Eval(object value, DekiScriptRuntime runtime) { if(value is XUri) { DekiScriptLiteral uri = DekiScriptExpression.Constant((XUri)value); if(DekiScriptRuntime.IsProperty(uri)) { value = runtime.EvaluateProperty(Location.None, uri, runtime.CreateEnv()).NativeValue; } } return value; }
private static object Eval(object value, DekiScriptRuntime runtime) { if (value is XUri) { DekiScriptLiteral uri = DekiScriptExpression.Constant((XUri)value); if (DekiScriptRuntime.IsProperty(uri)) { value = runtime.EvaluateProperty(Location.None, uri, runtime.CreateEnv()).NativeValue; } } return(value); }
public DekiScriptLiteral Visit(DekiScriptVar expr, DekiScriptEnv env) { if (expr.Name.EqualsInvariant(DekiScriptRuntime.ENV_ID)) { DekiScriptMap vars = new DekiScriptMap(); vars.AddRange(env.Globals); vars.AddRange(env.Locals); return(vars); } // check if variable exists DekiScriptLiteral result = env[expr.Name]; if (result == null) { throw new DekiScriptUndefinedNameException(expr.Line, expr.Column, expr.Name); } result = DekiScriptRuntime.EvaluateProperty(result, env); return(result); }
public DekiScriptExpression Visit(DekiScriptAccess expr, DekiScriptOptimizerState state) { DekiScriptExpression prefix = expr.Prefix.VisitWith(this, state); DekiScriptExpression index = expr.Index.VisitWith(this, state); DekiScriptAccess access = new DekiScriptAccess(expr.Line, expr.Column, prefix, index); if ((prefix is DekiScriptLiteral) && (index is DekiScriptLiteral)) { // BUGBUGBUG (steveb): don't eval properties! DekiScriptLiteral result = DekiScriptExpressionEvaluation.Instance.Evaluate(access, state.Env, false); // check if result is a property if (DekiScriptRuntime.IsProperty(result)) { // retrieve property information DekiScriptFunction function; if (DekiScriptLibrary.Functions.TryGetValue(((DekiScriptUri)result).Value, out function)) { if (function is DekiScriptFunctionNative) { DekiScriptFunctionNative native = (DekiScriptFunctionNative)function; // check if function is idempotent; if so, execute it if (native.IsIdempotent) { // evaluate property, since it never changes return(DekiScriptRuntime.EvaluateProperty(result, state.Env)); } } } return(new DekiScriptCall(expr.Line, expr.Column, result, new DekiScriptList(), false)); } return(result); } return(access); }
internal DekiScriptLiteral Evaluate(DekiScriptAccess expr, DekiScriptEnv env, bool evaluateProperties) { DekiScriptLiteral prefix = expr.Prefix.VisitWith(this, env); DekiScriptLiteral index = expr.Index.VisitWith(this, env); switch (prefix.ScriptType) { case DekiScriptType.MAP: { DekiScriptLiteral result = ((DekiScriptMap)prefix)[index]; if (evaluateProperties) { result = DekiScriptRuntime.EvaluateProperty(result, env); } return(result); } case DekiScriptType.LIST: { DekiScriptLiteral value = DekiScriptNumber.New(index.AsNumber()); DekiScriptLiteral result = ((DekiScriptList)prefix)[value]; if (evaluateProperties) { result = DekiScriptRuntime.EvaluateProperty(result, env); } return(result); } case DekiScriptType.URI: { DekiScriptUri uri = (DekiScriptUri)prefix; // coerce the index type to STR index = DekiScriptString.New(index.AsString()); if (index.ScriptType != DekiScriptType.STR) { throw new DekiScriptBadTypeException(expr.Line, expr.Column, index.ScriptType, new[] { DekiScriptType.STR }); } // curry the argument DekiScriptList args; if (!uri.Arguments.IsNil) { // the uri already has curried parameters, make sure they are in LIST format; otherwise fail if (uri.Arguments.ScriptType != DekiScriptType.LIST) { throw new DekiScriptBadTypeException(expr.Line, expr.Column, uri.Arguments.ScriptType, new[] { DekiScriptType.NIL, DekiScriptType.LIST }); } args = new DekiScriptList((DekiScriptList)uri.Arguments); } else { args = new DekiScriptList(); } args.Add(index); return(new DekiScriptUri(uri.Value, args)); } case DekiScriptType.STR: { DekiScriptString text = (DekiScriptString)prefix; // coerce the index type to NUM double?value = index.AsNumber(); if (value == null) { throw new DekiScriptBadTypeException(expr.Line, expr.Column, index.ScriptType, new[] { DekiScriptType.NUM }); } // retrieve character at given index position int position = (int)value; if ((position < 0) || (position >= text.Value.Length)) { // index is out of bounds, return nil return(DekiScriptNil.Value); } return(DekiScriptString.New(text.Value[position].ToString())); } case DekiScriptType.XML: { string path = index.AsString(); if (path == null) { throw new DekiScriptBadTypeException(expr.Line, expr.Column, index.ScriptType, new[] { DekiScriptType.STR }); } XDoc doc = ((DekiScriptXml)prefix).Value[path]; if (doc.HasName("html")) { doc = DekiScriptLibrary.CleanseHtmlDocument(doc); } return(new DekiScriptXml(doc)); } case DekiScriptType.NIL: return(DekiScriptNil.Value); } throw new DekiScriptBadTypeException(expr.Line, expr.Column, prefix.ScriptType, new[] { DekiScriptType.MAP, DekiScriptType.LIST, DekiScriptType.XML, DekiScriptType.STR, DekiScriptType.URI }); }