Ejemplo n.º 1
0
 protected override void ProcessNext()
 {
     if (DmlTokens.IsTimeCommand(CurrentToken))
     {
         ProcessTimeCommand();
     }
     else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_ASSIGN))
     {
         ProcessAssignment(NamespaceType.Timeline);
     }
     else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_RANGE))
     {
         ProcessRange();
     }
     else if (DmlTokens.IsMatch(CurrentToken, "Spawn"))
     {
         if (!inTimeStamp)
         {
             throw DmlSyntaxError.InvalidSpawnPlacement();
         }
         ProcessBehaviour();
     }
     else
     {
         throw DmlSyntaxError.InvalidTokenForContext(CurrentToken, "timeline");
     }
 }
Ejemplo n.º 2
0
 protected override void ProcessNext()
 {
     if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_ASSIGN))
     {
         ProcessAssignment(NamespaceType.BulletUpdate);
     }
     else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_RANGE))
     {
         ProcessRange();
     }
     else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_CHILDREN))
     {
         throw new NotImplementedException("This hasn't been implemented yet, sorry!");
     }
     else if (DmlTokens.IsTimeCommand(CurrentToken))
     {
         ProcessTimeCommand();
     }
     else if (DmlTokens.IsName(CurrentToken) || DmlTokens.IsBuiltin(CurrentToken))
     {
         ProcessExpression(GetUntil(DmlTokens.EOL));
     }
     else if (DmlTokens.IsBehaviour(CurrentToken))
     {
         ProcessBehaviour();
     }
     else
     {
         throw DmlSyntaxError.InvalidTokenForContext(CurrentToken, "bullet update");
     }
 }
Ejemplo n.º 3
0
        protected override void ProcessNext()
        {
            // Check for an assignment statement.
            if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_ASSIGN))
            {
                throw DmlSyntaxError.BadAssignmentNamespace();
            }
            else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_INIT))
            {
                if (Init != null)
                {
                    throw DmlSyntaxError.DuplicateNamespaceInBullet("Init");
                }
                SetExpecting(DmlTokens.LANGLE);
                Advance(exception: DmlSyntaxError.BlockMissingDelimiters("Init"));

                string[]          tokens      = GetNamespaceBlock();
                BulletInitBuilder initBuilder = new BulletInitBuilder(tokens, currentLine);
                initBuilder.Parse();

                var initBlock = (Instruction[])initBuilder.GetResult();
                Init = new CodeBlock(initBlock);
            }
            else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_UPDATE))
            {
                if (Update != null)
                {
                    throw DmlSyntaxError.DuplicateNamespaceInBullet("Update");
                }
                SetExpecting(DmlTokens.LANGLE);
                Advance(exception: DmlSyntaxError.BlockMissingDelimiters("Update"));

                string[]            tokens        = GetNamespaceBlock();
                BulletUpdateBuilder updateBuilder = new BulletUpdateBuilder(tokens, currentLine);
                updateBuilder.Parse();

                var updateBlock = (Instruction[])updateBuilder.GetResult();
                Update = new CodeBlock(updateBlock);
            }
            else
            {
                throw DmlSyntaxError.InvalidTokenForContext(CurrentToken, "bullet");
            }
        }
Ejemplo n.º 4
0
 protected override void ProcessNext()
 {
     if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_ASSIGN))
     {
         ProcessAssignment(NamespaceType.BulletInit);
     }
     else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_RANGE))
     {
         ProcessRange();
     }
     else if (DmlTokens.IsName(CurrentToken) || DmlTokens.IsBuiltin(CurrentToken))
     {
         ProcessExpression(GetUntil(DmlTokens.EOL));
     }
     else
     {
         throw DmlSyntaxError.InvalidTokenForContext(CurrentToken, "bullet init");
     }
 }
Ejemplo n.º 5
0
        protected override void ProcessNext()
        {
            if (DmlTokens.IsMatch(CurrentToken, DmlTokens.AT) ||
                DmlTokens.IsMatch(CurrentToken, DmlTokens.DOLLAR) ||
                DmlTokens.IsNonKeywordName(CurrentToken) ||
                DmlTokens.IsBuiltin(CurrentToken))
            {
                Instruction load;
                string      badName = "Invalid syntax; invalid name \"{0}\".";
                if (DmlTokens.IsMatch(CurrentToken, DmlTokens.AT))
                {
                    Advance(exception: new DmlSyntaxError("Invalid syntax: global identifier `@` must be followed by a name."));
                    if (!DmlTokens.IsName(CurrentToken))
                    {
                        throw new DmlSyntaxError(String.Format(badName, CurrentToken));
                    }
                    load = new LoadGlobal(CurrentToken);
                }
                else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.DOLLAR))
                {
                    Advance(exception: new DmlSyntaxError("Invalid syntax: identifier `$` must be followed by a name."));
                    if (DmlTokens.IsName(CurrentToken))
                    {
                        switch (CurrentToken)
                        {
                        case DmlTokens.INTRINSIC_DIRECTION:
                            load = LoadIntrinsicBulletProperty.Direction;
                            break;

                        case DmlTokens.INTRINSIC_SPEED:
                            load = LoadIntrinsicBulletProperty.Speed;
                            break;

                        case DmlTokens.INTRINSIC_COLOUR:
                            load = LoadIntrinsicBulletProperty.Colour;
                            break;

                        case DmlTokens.INTRINSIC_ORIGIN:
                            load = LoadIntrinsicBulletProperty.Origin;
                            break;

                        case DmlTokens.INTRINSIC_POSITION:
                            load = LoadIntrinsicBulletProperty.Position;
                            break;

                        case DmlTokens.INTRINSIC_VELOCITY:
                            load = LoadIntrinsicBulletProperty.Velocity;
                            break;

                        case DmlTokens.INTRINSIC_TIME:
                            load = LoadIntrinsicBulletProperty.Time;
                            break;

                        default:
                            load = new LoadInstanceBound(CurrentToken);
                            break;
                        }
                    }
                    else
                    {
                        throw new DmlSyntaxError(String.Format(badName, CurrentToken));
                    }
                }
                else if (DmlTokens.IsName(CurrentToken))
                {
                    load = new LoadLocal(CurrentToken);
                }
                else
                {
                    load = new LoadConstant(BuiltinsDict.Builtins[CurrentToken]);
                }

                bool isCall = false;
                // Check if this is a function call.
                // We actually want to catch the ParserError thrown by Advance() in this case
                // because it's very possible the expression could end with a name.
                if (NextToken != null)
                {
                    Advance();
                    if (DmlTokens.IsMatch(CurrentToken, DmlTokens.LPAR))
                    {
                        isCall = true;
                        ParseFuncCall(load);
                    }
                    else
                    {
                        Reverse();
                    }
                }
                if (!isCall)
                {
                    instructions.Add(load);
                }
            }
            else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_TRUE))
            {
                instructions.Add(new LoadConstant(new DmlObject(DmlType.Bool, true)));
            }
            else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_FALSE))
            {
                instructions.Add(new LoadConstant(new DmlObject(DmlType.Bool, false)));
            }
            else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_NULL))
            {
                instructions.Add(new LoadConstant(new DmlObject(DmlType.Null, null)));
            }
            // Check for a left parenthesis.
            else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.LPAR))
            {
                // We know this will never be the start of a function call because
                // that case would be caught by the above if block.
                operators.Push(CurrentToken);
            }
            // Check for a right parenthesis.
            else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.RPAR))
            {
                // By the shunting-yard algorithm, we pop every operator until we find a left
                // parenthesis. If we don't find one, then there are mismatched parentheses.
                if (operators.Count == 0 || !operators.Contains(DmlTokens.LPAR))
                {
                    throw DmlSyntaxError.MismatchedParentheses();
                }
                string top;
                while (operators.Count > 0)
                {
                    top = operators.First();
                    if (DmlTokens.IsMatch(top, DmlTokens.LPAR))
                    {
                        operators.Pop();
                        break;
                    }
                    instructions.Add(OPERATOR_INSTRUCTIONS[operators.Pop()]);
                }
            }
            // Check if the next token is a valid mathematical operator.
            else if (IsOperator(CurrentToken))
            {
                if (operators.Count == 0)
                {
                    operators.Push(CurrentToken);
                }
                // If there are prior operators, pop them and add them to the instructions according to their
                // associativity and precedence.
                else
                {
                    string top;
                    while (operators.Count > 0)
                    {
                        top = operators.First();
                        if ((IsLeftAssociative(top) && OPERATOR_PRECEDENCE[top] >= OPERATOR_PRECEDENCE[CurrentToken]) ||
                            (IsRightAssociative(top) && OPERATOR_PRECEDENCE[top] > OPERATOR_PRECEDENCE[CurrentToken]))
                        {
                            instructions.Add(OPERATOR_INSTRUCTIONS[operators.Pop()]);
                        }
                        else
                        {
                            break;
                        }
                    }
                    operators.Push(CurrentToken);
                }
            }
            // Check for a number.
            else if (DmlTokens.IsNumber(CurrentToken))
            {
                instructions.Add(new LoadConstant(new DmlObject(DmlType.Number, Double.Parse(CurrentToken))));
            }
            // Check for True.
            else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_TRUE))
            {
                instructions.Add(new LoadConstant(new DmlObject(DmlType.Bool, true)));
            }
            // Check for False.
            else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_FALSE))
            {
                instructions.Add(new LoadConstant(new DmlObject(DmlType.Bool, false)));
            }
            // Check for Null.
            else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_NULL))
            {
                instructions.Add(new LoadConstant(new DmlObject(DmlType.Null, null)));
            }
            else if (DmlTokens.IsString(CurrentToken))
            {
                instructions.Add(new LoadConstant(new DmlObject(DmlType.String, CurrentToken)));
            }
            // Check for Lambda.
            else if (DmlTokens.IsMatch(CurrentToken, DmlTokens.KW_LAMBDA))
            {
                throw new NotImplementedException("This hasn't been implemented yet, sorry!");
            }
            else
            {
                throw DmlSyntaxError.InvalidTokenForContext(CurrentToken, "expression");
            }
        }