void ExecuteStatement(AbstractSyntaxTree node) { if (node == null) { return; } else if (node.ValueType == ValueTypes.code && node.IsOperand) { ApplyRules(AllRules.Where(r => r.Atom == node.Value).ToList()); // WhenPlayBegins; } else if (node.ValueType == ValueTypes.code && node.Value == "(" && !node.Contains(FillInThisBlank)) // Heading(Foyer), Description(Foyer).... { Rule invokedRule = AllRules.Find(r => r.Atom == node.ToString()); if (invokedRule != null) { ApplyRule(invokedRule); } else { ApplyRules(AllRules.Where(r => r.Atom.StartsWith(node.Left.Value + "(")).ToList(), node.Right); } } else if (node.ValueType == ValueTypes.code && node.Value == "(" && node.Contains(FillInThisBlank)) // understand(_,cloak) { foreach (var item in ForEach_(node)) { ExecuteStatement(item); } } else if (node.ValueType == ValueTypes.code) { EvalCode(node); } else if (node.ValueType == ValueTypes.text) { Console.Write(node.Value); } else if (node.ValueType == ValueTypes.number) { Console.Write(node.Value); } else if (node.ValueType == ValueTypes.boolean) { Console.Write(node.Value == "true" ? "yes" : "no"); } else { throw new Exception("We never defined: do " + node.Value + "... "); } }
public bool Contains(string atomWithoutParens) { if (Value == atomWithoutParens) { return(true); } if (Left != null && Left.Contains(atomWithoutParens)) { return(true); } if (Right != null && Right.Contains(atomWithoutParens)) { return(true); } return(false); }
// if the passed-in node is a string value, number, or bool, it returns it. It does NOT auto-print it. AbstractSyntaxTree EvalCode(AbstractSyntaxTree node) { if (node == null) { return(null); } switch (node.Value) // nodes which are either Operands or mustn't eval both sides immediately { case "?": AbstractSyntaxTree lhs = node.Left; Rule iteratorVar = new Rule { Atom = "each", Location = "local", IsPrivateToFile = "local" }; LocalVariables.Push(new List <Rule>() { iteratorVar }); AllRules.Add(iteratorVar); // todo remove if (lhs.Value == "(") { iteratorVar.Atom += lhs.Left.Value; } else { lhs = EvalCode(lhs); } foreach (AbstractSyntaxTree code in ForEach_(lhs)) { iteratorVar.Code = code; // set the "eachFoo" variable to the next value in the list ExecuteStatement(node.Right); } LocalVariables.Pop(); AllRules.Remove(iteratorVar); // todo remove return(null); case "}": LocalVariables.Pop(); return(null); case "Parse": CrappyHardCodedParser(); return(null); case null: return(null); } if (node.IsOperand) { return(node); } AbstractSyntaxTree left = EvalCode(node.Left); AbstractSyntaxTree right = EvalCode(node.Right); switch (node.Value) // nodes which will print a value or alter the ruleset { case "{": ExecuteStatement(left); LocalVariables.Push(new List <Rule>()); ExecuteStatement(right); return(null); case ";": ExecuteStatement(left); ExecuteStatement(right); return(null); case ":=": var rule = AllRules.FirstOrDefault(r => r.Atom == left.ToString()); if (rule == null) { rule = new Rule { Atom = left.ToString(), Code = right }; AllRules.Add(rule); } if (right.Value == "ReadKeyboard") { rule.Code = new AbstractSyntaxTree(Console.ReadLine(), ValueTypes.text); } else if (right.Value == "ReadKey") { rule.Code = new AbstractSyntaxTree(Console.ReadKey().KeyChar.ToString(), ValueTypes.text); } else if (right.Contains("_")) { foreach (var item in ForEach_(right)) { rule.Code = item; } } else { rule.Code = right; } return(null); case "(": // we fill-in the values, but don't know if we're going to := assert it or ?{} test it bool allBound; return(CloneTreeWithParamsBoundToArgs(node, out allBound)); case ",": return(node); } // at this point, any items of the shape foo(bar,blah) are relations, not function-invocations. We test for existance and value. if (left.ValueType == ValueTypes.code) { left = TestRelation(left); } if (right.ValueType == ValueTypes.code) { right = TestRelation(right); } // these produce a value. Statements (above) do not produce values. switch (node.Value) { case "<": return(Compare(left, right) < 0 ? Yes : No); case "<=": return(Compare(left, right) <= 0 ? Yes : No); case "<>": case "!=": return(Compare(left, right) != 0 ? Yes : No); case ">": return(Compare(left, right) > 0 ? Yes : No); case ">=": return(Compare(left, right) >= 0 ? Yes : No); case "==": return(Compare(left, right) == 0 ? Yes : No); case "&": case "&&": return(AsBoolean(left) && AsBoolean(right) ? Yes : No); case "|": case "||": return(AsBoolean(left) || AsBoolean(right) ? Yes : No); case "+": return(new AbstractSyntaxTree((decimal.Parse(left.Value) + decimal.Parse(right.Value)).ToString(), ValueTypes.number)); case "-": return(new AbstractSyntaxTree((decimal.Parse(left.Value) - decimal.Parse(right.Value)).ToString(), ValueTypes.number)); case "*": return(new AbstractSyntaxTree((decimal.Parse(left.Value) * decimal.Parse(right.Value)).ToString(), ValueTypes.number)); case "/": return(new AbstractSyntaxTree((decimal.Parse(left.Value) / decimal.Parse(right.Value)).ToString(), ValueTypes.number)); } return(node); }