private VarItem ImportVar(IBranch varBranch, bool native) { // protect ourselves from recursion if (varBranch == FormulaBeingEdited) { return null; } else { Func<String, String> attr = s => varBranch.GetValue(s) == null ? "" : varBranch.GetValue(s).ContentString; _varNames.Add(varBranch.VPath, attr("name")); _varTypes.Add(varBranch.VPath, attr("type")); var @newitem = new VarItem(varBranch, _varNames[varBranch.VPath], varBranch.VPath.ToElfIdentifier()); if (native) { _native.Add(@newitem); } else { if (new VariableExpression(@newitem.InternalName).PieType() == PieType.Var) { _externalVars.Add(@newitem); } else { _externalNodes.Add(@newitem); } } return @newitem; } }
public TillerIntegrationContext(IBranch common, IBranch activeParticle, Func<IBranch> branchSelector, Func<IBranch> nodeSelector) { Common = common; FormulaBeingEdited = activeParticle; BranchSelector = branchSelector; NodeSelector = nodeSelector; var svds = Enumerable.Empty<IBranch>(); if (FormulaBeingEdited != null) { var particle = FormulaBeingEdited.Parent.Parent; var partDecl = particle.GetBranches().SingleOrDefault(b => b.Name == "_sourceValueDeclarations"); var partFlae = particle.GetBranches().SingleOrDefault(b => b.Name == "_formulaDeclarations"); if (partFlae != null) svds = partFlae.AsArray().Concat(svds); if (partDecl != null) svds = partDecl.AsArray().Concat(svds); } Func<IBranch, String> type = b => b.GetValue("type") == null ? null : b.GetValue("type").ContentString; svds.Distinct().SelectMany(svd => svd.GetBranches()) .Where(var => var != FormulaBeingEdited && type(var) != "text" && type(var) != "string") .ForEach(var => ImportVar(var)); var elf = activeParticle.GetValue("elfCode") == null ? null : activeParticle.GetValue("elfCode").ContentString; if (elf != null) elf.RenderLightElfAsPublicText(this); // as a side effect this will fill in the externals }
private static Expression ExpandRhs(IBranch b, IVault repository, List<Expression> stack, Dictionary<String, IBranch> nodes) { var elf = b.GetValue("elfCode").ContentString.ToCanonicalElf(); var script = (Script)new ElfAstBuilder(elf).BuildAst(); var assign = (AssignmentExpression)((ExpressionStatement) script.Classes.Single().Funcs.Single().Body.Statements.Single()).Expression; var rhs = assign.Expression; if (stack.Contains(rhs)) { throw new EvalStackOverflowException(); } else { stack.Add(rhs); return Expand(rhs, b.Vault, repository, stack, nodes); } }
public object Eval(IBranch b, string childScript) { try { if (!Cache.ContainsKey(b.VPath)) { if (b.GetOrCreateValue("declarationType", "source").ContentString == "source") { String val; IValue v; val = (v = b.GetValue("valueForTesting")) == null ? "" : v.ContentString; if (string.IsNullOrEmpty(val)) { var repositoryVal = (v = b.GetValue("repositoryValue")) == null ? null : v.ContentString; if (!string.IsNullOrEmpty(repositoryVal)) { val = Repository.GetValue(repositoryVal).ContentString; } } var type = (v = b.GetValue("type")) == null ? "string" : v.ContentString; var script = String.Format("'[[{0}]]{1}'", type, val); Cache.Add(b.VPath, EvalScript(script)); } else { if (NodesInProgress.Contains(b.VPath)) { throw new EvalStackOverflowException(b, NodesInProgress.Select(vp => Vault.GetBranch(vp))); } else { object result; var old = NodeInProgress; NodeInProgress = b; NodesInProgress.Add(b.VPath); try { var source = b.GetValue("elfCode").ContentString; if (!string.IsNullOrEmpty(source)) { IBranch conditions = null; // in case of a conditional node, we replace its formula body with the corresponding body of checked child node if (_checkedNodes != null && (conditions = b.Parent.Parent.GetBranch("_conditions")) != null && conditions.GetBranches().Length > 0) { var index = 0; if ((index = source.IndexOf('=')) > 0) // is subject to replace? { // look for the very first checked child foreach (var child in b.Parent.Parent.GetBranches()) { if (!_checkedNodes.Contains(child.Id)) continue; var varName = source.Substring(0, index); var formulasBranch = child.GetBranch("_formulaDeclarations"); if (formulasBranch == null) continue; foreach (var formula in formulasBranch.GetBranches()) { var formulaBody = ""; // look for the very first formula body having $varName within if (string.IsNullOrEmpty(formulaBody = formula.GetValue("elfCode").ContentString) || formulaBody.IndexOf(varName) < 0) continue; var lines = formulaBody.Split('\n'); lines[lines.Length - 1] = "ret " + lines[lines.Length - 1]; source = string.Join(Environment.NewLine, lines); break; } break; } } } if (!string.IsNullOrEmpty(childScript)) source = string.Concat(source, Environment.NewLine, childScript); } result = EvalScript(source); } finally { NodeInProgress = old; NodesInProgress.Remove(b.VPath); } Cache.Add(b.VPath, result); } } } return Cache[b.VPath]; } catch (BaseEvalException) { throw; } catch (ErroneousScriptRuntimeException esex) { if (esex.Type == ElfExceptionType.OperandsDontSuitMethod) { throw new ArgsDontSuitTheFunctionException(b, esex.Thread.RuntimeContext.PendingClrCall, esex); } else { throw new UnexpectedErrorException(b, esex); } } catch (Exception ex) { if (ex.InnerException is FormatException) { throw new BadFormatOfSerializedStringException(b, ex); } else { throw new UnexpectedErrorException(b, ex); } } }