Inheritance: Parsed.Object
示例#1
0
        public VariableAssignment (string variableName, Expression assignedExpression)
        {
            this.variableName = variableName;

            // Defensive programming in case parsing of assignedExpression failed
            if( assignedExpression )
                this.expression = AddContent(assignedExpression);
        }
示例#2
0
文件: Conditional.cs 项目: inkle/ink
        public Conditional (Expression condition, List<ConditionalSingleBranch> branches)
        {
            this.initialCondition = condition;
            if (this.initialCondition) {
                AddContent (condition);
            }

            this.branches = branches;
            if (this.branches != null) {
                AddContent (this.branches.Cast<Parsed.Object> ().ToList ());
            }

        }
        protected Expression ExpressionInfixRight(Parsed.Expression left, InfixOperator op)
        {
            Whitespace();

            var right = Parse(() => Expression(op.precedence));

            if (right)
            {
                // We assume that the character we use for the operator's type is the same
                // as that used internally by e.g. Runtime.Expression.Add, Runtime.Expression.Multiply etc
                var expr = new BinaryExpression(left, right, op.type);
                return(expr);
            }

            return(null);
        }
示例#4
0
文件: Expression.cs 项目: inkle/ink
		public BinaryExpression(Expression left, Expression right, string opName)
		{
            leftExpression = AddContent(left);
            rightExpression = AddContent(right);
			this.opName = opName;
		}
示例#5
0
文件: Expression.cs 项目: inkle/ink
        public UnaryExpression(Expression inner, string op)
		{
            this.innerExpression = AddContent(inner);
            this.op = op;
		}
示例#6
0
文件: Expression.cs 项目: inkle/ink
        // Attempt to flatten inner expression immediately
        // e.g. convert (-(5)) into (-5)
        public static Expression WithInner(Expression inner, string op) {

            var innerNumber = inner as Number;
            if( innerNumber ) {

                if( op == "-" ) {
                    if( innerNumber.value is int ) {
                        return new Number( -((int)innerNumber.value) );
                    } else if( innerNumber.value is float ) {
                        return new Number( -((float)innerNumber.value) );
                    }
                }

                else if( op == "!" || op == "not" ) {
                    if( innerNumber.value is int ) {
                        return new Number( ((int)innerNumber.value == 0) ? 1 : 0 );
                    } else if( innerNumber.value is float ) {
                        return new Number( ((float)innerNumber.value == 0.0f) ? 1 : 0 );
                    }
                }

                System.Diagnostics.Debug.Fail ("Unexpected operation or number type");
            }

            // Normal fallback
            var unary = new UnaryExpression (inner, op);
            return unary;
        }
示例#7
0
        protected Conditional InnerConditionalContent(Expression initialQueryExpression)
        {
            List<ConditionalSingleBranch> alternatives;

            bool canBeInline = initialQueryExpression != null;
            bool isInline = Newline () == null;

            if (isInline && !canBeInline) {
                return null;
            }

            // Inline innards
            if (isInline) {
                alternatives = InlineConditionalBranches ();
            } 

            // Multiline innards
            else {
                alternatives = MultilineConditionalBranches ();
                if (alternatives == null) {

                    // Allow single piece of content within multi-line expression, e.g.:
                    // { true: 
                    //    Some content that isn't preceded by '-'
                    // }
                    if (initialQueryExpression) {
                        List<Parsed.Object> soleContent = StatementsAtLevel (StatementLevel.InnerBlock);
                        if (soleContent != null) {
                            var soleBranch = new ConditionalSingleBranch (soleContent);
                            alternatives = new List<ConditionalSingleBranch> ();
                            alternatives.Add (soleBranch);

                            // Also allow a final "- else:" clause
                            var elseBranch = Parse(SingleMultilineCondition);
                            if (elseBranch) {
                                if (!elseBranch.isElse) {
                                    ErrorWithParsedObject ("Expected an '- else:' clause here rather than an extra condition", elseBranch);
                                    elseBranch.isElse = true;
                                }
                                alternatives.Add (elseBranch);
                            }
                        }
                    }

                    // Still null?
                    if (alternatives == null) {
                        return null;
                    }
                }

                // Like a switch statement
                // { initialQueryExpression:
                //    ... match the expression
                // }
                if (initialQueryExpression) {

                    bool earlierBranchesHaveOwnExpression = false;
                    for (int i = 0; i < alternatives.Count; ++i) {
                        var branch = alternatives [i];
                        bool isLast = (i == alternatives.Count - 1);

                        // Match query
                        if (branch.ownExpression) {
                            branch.shouldMatchEquality = true;
                            earlierBranchesHaveOwnExpression = true;
                        }

                        // Else (final branch)
                        else if (earlierBranchesHaveOwnExpression && isLast) {
                            branch.isElse = true;
                        } 

                        // Binary condition:
                        // { trueOrFalse:
                        //    - when true
                        //    - when false
                        // }
                        else {

                            if (!isLast && alternatives.Count > 2) {
                                ErrorWithParsedObject ("Only final branch can be an 'else'. Did you miss a ':'?", branch);
                            } else {
                                if (i == 0)
                                    branch.isTrueBranch = true;
                                else
                                    branch.isElse = true;
                            }
                        }
                    }
                } 

                // No initial query, so just a multi-line conditional. e.g.:
                // {
                //   - x > 3:  greater than three
                //   - x == 3: equal to three
                //   - x < 3:  less than three
                // }
                else {
                    
                    for (int i = 0; i < alternatives.Count; ++i) {
                        var alt = alternatives [i];
                        bool isLast = (i == alternatives.Count - 1);
                        if (alt.ownExpression == null) {
                            if (isLast) {
                                alt.isElse = true;
                            } else {
                                if (alt.isElse) {
                                    // Do we ALSO have a valid "else" at the end? Let's report the error there.
                                    var finalClause = alternatives [alternatives.Count - 1];
                                    if (finalClause.isElse) {
                                        ErrorWithParsedObject ("Multiple 'else' cases. Can have a maximum of one, at the end.", finalClause);
                                    } else {
                                        ErrorWithParsedObject ("'else' case in conditional should always be the final one", alt);
                                    }
                                } else {
                                    ErrorWithParsedObject ("Branch doesn't have condition. Are you missing a ':'? ", alt);
                                }

                            }
                        }
                    }
                        
                    if (alternatives.Count == 1 && alternatives [0].ownExpression == null) {
                        ErrorWithParsedObject ("Condition block with no conditions", alternatives [0]);
                    }
                }
            }

            // TODO: Come up with water-tight error conditions... it's quite a flexible system!
            // e.g.
            //   - inline conditionals must have exactly 1 or 2 alternatives
            //   - multiline expression shouldn't have mixed existence of branch-conditions?
            if (alternatives == null)
                return null;

            var cond = new Conditional (initialQueryExpression, alternatives);
            return cond;
        }