Пример #1
0
 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 + "... ");
     }
 }
Пример #2
0
 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);
 }
Пример #3
0
    // 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);
    }