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
        }
Beispiel #3
0
        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);
            }
        }
Beispiel #4
0
		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);
				}
			}
		}