private bool IsSimpleEnough(Expression exp)
        {
            if (exp is NullConstant ||
                exp is BooleanConstant ||
                exp is IntegerConstant ||
                exp is FloatConstant ||
                exp is StringConstant ||
                exp is Variable)
            {
                return true;
            }

            if (exp is DotField)
            {
                return IsSimpleEnough(((DotField)exp).Root);
            }

            if (exp is IndexExpression)
            {
                return
                    IsSimpleEnough(((IndexExpression)exp).Root) &&
                    IsSimpleEnough(((IndexExpression)exp).Index);
            }

            return false;
        }
 public SliceExpression(Expression root, Token bracketToken, IList<Expression> components)
     : base(root.FirstToken)
 {
     this.Root = root;
     this.BracketToken = bracketToken;
     this.Components = components.ToArray();
 }
 public Assignment(Expression target, Token assignmentToken, Expression value)
     : base(target.FirstToken)
 {
     this.AssignmentToken = assignmentToken;
     this.Target = target;
     this.Value = value;
 }
 public Ternary(Expression condition, Expression trueCode, Expression falseCode)
     : base(trueCode.FirstToken)
 {
     this.TrueExpression = trueCode;
     this.FalseExpression = falseCode;
     this.Condition = condition;
 }
 public ForEachLoop(Token forToken, Token iteratorVariable, Expression iterableExpression, IList<Executable> body)
     : base(forToken)
 {
     this.IteratorVariable = iteratorVariable;
     this.IterableExpression = iterableExpression;
     this.Body = body.ToArray();
 }
 public Negation(Token token, Expression root, PrefixType type)
     : base(token)
 {
     this.Op = token;
     this.Root = root;
     this.Type = type;
 }
 public override Expression Resolve()
 {
     this.Left = this.Left.Resolve();
     this.Right = this.Right.Resolve();
     // TODO: resolve boolean constants
     return this;
 }
 public BooleanCombinator(Expression left, Expression right, string type)
     : base(left.FirstToken)
 {
     this.IsAnd = type == "and";
     this.Left = left;
     this.Right = right;
 }
 public IndexExpression(Expression root, Token bracketToken, Expression index)
     : base(root.FirstToken)
 {
     this.Root = root;
     this.BracketToken = bracketToken;
     this.Index = index;
 }
		protected override void X_DrawTriangle(List<string> output, Expression screen, Expression x1, Expression y1, Expression x2, Expression y2, Expression x3, Expression y3, Expression red, Expression green, Expression blue)
		{
			output.Add("pygame.draw.polygon(");
			SerializeExpression(output, screen);
			output.Add(", (");
			SerializeExpression(output, red);
			output.Add(", ");
			SerializeExpression(output, green);
			output.Add(", ");
			SerializeExpression(output, blue);
			output.Add("), ((");
			SerializeExpression(output, x1);
			output.Add(", ");
			SerializeExpression(output, y1);
			output.Add("), (");
			SerializeExpression(output, x2);
			output.Add(", ");
			SerializeExpression(output, y2);
			output.Add("), (");
			SerializeExpression(output, x3);
			output.Add(", ");
			SerializeExpression(output, y3);
			output.Add(")))");

		}
 public override Expression Resolve()
 {
     this.Condition = this.Condition.Resolve();
     this.TrueExpression = this.TrueExpression.Resolve();
     this.FalseExpression = this.FalseExpression.Resolve();
     return this;
 }
 public DotField(Expression root, Token dotToken, Token fieldToken, string fieldName)
     : base(root.FirstToken)
 {
     this.Root = root;
     this.DotToken = dotToken;
     this.FieldToken = fieldToken;
     this.FieldName = fieldName;
 }
 public IfStatement(Token ifToken, Expression condition, IList<Executable> trueCode)
     : base(ifToken)
 {
     this.IfToken = ifToken;
     this.Condition = condition;
     this.TrueCode = trueCode.ToArray();
     this.FalseCode = EMPTY_LIST;
 }
 public override Expression Resolve()
 {
     this.Root = this.Root.Resolve();
     for (int i = 0; i < this.Args.Length; ++i)
     {
         this.Args[i] = this.Args[i].Resolve();
     }
     return this;
 }
 public ForLoop(Token forToken, ForEachLoop originalForEachLoop, IList<Executable> init, Expression condition, IList<Executable> step, IList<Executable> body)
     : base(forToken)
 {
     this.Init = init.ToArray();
     this.Condition = condition;
     this.Step = step.ToArray();
     this.Body = body.ToArray();
     this.OriginalForEachLoop = originalForEachLoop;
 }
 protected override void X_DictionaryGetWithDefault(List<string> output, Expression dictionary, Expression key, Expression defaultValue)
 {
     SerializeExpression(output, dictionary);
     output.Add(".get(");
     SerializeExpression(output, key);
     output.Add(", ");
     SerializeExpression(output, defaultValue);
     output.Add(")");
 }
        public override IList<Executable> Resolve()
        {
            if (this.Value == null)
            {
                this.Value = new NullConstant(null);
            }

            this.Value = this.Value.Resolve();

            return Listify(this);
        }
        public IfRawComponent(Token token, Expression nullableCondition, IList<Executable> body)
            : base(token)
        {
            // I find the following 3 lines mildly humorous.
            if (token.Value == "if") this.Type = ComponentType.IF;
            else if (token.Value == "elif") this.Type = ComponentType.ELIF;
            else this.Type = ComponentType.ELSE;

            this.NullableExpression = nullableCondition;
            this.Body = body.ToArray();
        }
 public override Expression Resolve()
 {
     this.Root = this.Root.Resolve();
     for (int i = 0; i < this.Components.Length; ++i)
     {
         if (this.Components[i] != null)
         {
             this.Components[i] = this.Components[i].Resolve();
         }
     }
     return this;
 }
		protected override void X_DrawEllipse(List<string> output, Expression screen, Expression left, Expression top, Expression width, Expression height, Expression red, Expression green, Expression blue)
		{
			output.Add("pygame.draw.ellipse(");
			SerializeExpression(output, screen);
			output.Add(", (");
			SerializeExpression(output, red);
			output.Add(", ");
			SerializeExpression(output, green);
			output.Add(", ");
			SerializeExpression(output, blue);
			output.Add("), pygame.Rect(");
			SerializeExpression(output, left);
			output.Add(", ");
			SerializeExpression(output, top);
			output.Add(", ");
			SerializeExpression(output, width);
			output.Add(", ");
			SerializeExpression(output, height);
			output.Add("))");
		}
        public override IList<Executable> Resolve()
        {
            this.Value = this.Value.Resolve();
            Expression t = this.Target;
            bool targetValid = true;
            if (t is Variable)
            {
                // nothing to do
            }
            else if (t is DotField)
            {
                DotField dotField = (DotField)t;
                this.Target = dotField.Resolve();
                if (!(this.Target is DotField))
                {
                    targetValid = false;
                }
            }
            else if (t is IndexExpression)
            {
                IndexExpression index = (IndexExpression)t;
                this.Target = index.Resolve();
                if (!(this.Target is IndexExpression))
                {
                    targetValid = false;
                }
            }
            else
            {
                targetValid = false;
            }

            if (!targetValid)
            {
                throw new ParserException(this.FirstToken, "Invalid target for assignment.");
            }

            return Listify(this);
        }
 public override void SerializeExpression(List<string> output, Expression expr)
 {
     if (expr is FunctionInvocation) SerializeFunctionInvocation(output, (FunctionInvocation)expr);
     else if (expr is Variable) SerializeVariable(output, (Variable)expr);
     else if (expr is StringConstant) SerializeStringConstant(output, (StringConstant)expr);
     else if (expr is IntegerConstant) SerializeIntegerConstant(output, (IntegerConstant)expr);
     else if (expr is DotField) SerializeDotField(output, (DotField)expr);
     else if (expr is BinaryOpChain) SerializeBinaryOpChain(output, (BinaryOpChain)expr);
     else if (expr is ParenthesisGroup) SerializeParenthesisGroup(output, (ParenthesisGroup)expr);
     else if (expr is InlineList) SerializeInlineList(output, (InlineList)expr);
     else if (expr is InlineTuple) SerializeInlineTuple(output, (InlineTuple)expr);
     else if (expr is BooleanConstant) SerializeBooleanConstant(output, (BooleanConstant)expr);
     else if (expr is NullConstant) output.Add("null");
     else if (expr is SystemFunctionInvocation) SerializeSystemFunctionInvocation(output, (SystemFunctionInvocation)expr);
     else if (expr is BooleanCombinator) SerializeBooleanCombinator(output, (BooleanCombinator)expr);
     else if (expr is FloatConstant) SerializeFloatConstant(output, (FloatConstant)expr);
     else if (expr is Negation) SerializeNegation(output, (Negation)expr);
     else if (expr is InlineDictionary) SerializeInlineDictionary(output, (InlineDictionary)expr);
     else if (expr is IndexExpression) SerializeIndex(output, (IndexExpression)expr);
     else if (expr is SliceExpression) SerializeSlice(output, (SliceExpression)expr);
     else if (expr is Ternary) SerializeTernary(output, (Ternary)expr);
     else throw new NotImplementedException(expr.GetType().ToString());
 }
 public FunctionInvocation(Expression root, IList<Expression> args)
     : base(root.FirstToken)
 {
     this.Root = root;
     this.Args = args.ToArray();
 }
 protected override void X_DrawTriangle(List<string> output, Expression screen, Expression x1, Expression y1, Expression x2, Expression y2, Expression x3, Expression y3, Expression red, Expression green, Expression blue)
 {
     output.Add("CRAYON_BUG_WORKAROUND_BLARG = 12345");
 }
 protected override void X_DictionaryKeys(List<string> output, Expression dict)
 {
     SerializeExpression(output, dict);
     output.Add(".keys()");
 }
 protected override void X_Str(List<string> output, Expression value)
 {
     output.Add("('' + (");
     SerializeExpression(output, value);
     output.Add("))");
 }
 protected override void X_MusicPlay(List<string> output, Expression song)
 {
     output.Add("$abs(0)"); // TODO: music in Crayon
 }
 protected override void X_ListRemove(List<string> output, Expression list, Expression index)
 {
     SerializeExpression(output, list);
     output.Add(".remove(");
     SerializeExpression(output, index);
     output.Add(")");
 }
 public abstract void SerializeExpression(List<string> output, Expression expression);
 protected abstract void X_Int(List<string> output, Expression num);