示例#1
0
 public void VisitProcBlockInner(DMASTProcBlockInner procBlockInner)
 {
     foreach (DMASTProcStatement statement in procBlockInner.Statements)
     {
         statement.Visit(this);
     }
 }
示例#2
0
 public DMASTProcStatementForLoop(DMASTProcStatementVarDeclaration variableDeclaration, DMASTCallable variable, DMASTExpression condition, DMASTExpression incrementer, DMASTProcBlockInner body)
 {
     VariableDeclaration = variableDeclaration;
     Variable            = variable;
     Condition           = condition;
     Incrementer         = incrementer;
     Body = body;
 }
示例#3
0
 public void ProcessBlockInner(DMASTProcBlockInner block)
 {
     foreach (DMASTProcStatement statement in block.Statements)
     {
         try {
             ProcessStatement(statement);
         } catch (CompileErrorException e) { //Retreat from the statement when there's an error
             DMCompiler.Error(e.Error);
         }
     }
 }
示例#4
0
        // TODO Move this to an appropriate location
        static public IEnumerable <DMASTProcStatement> GetStatements(DMASTProcBlockInner block)
        {
            foreach (var stmt in block.Statements)
            {
                yield return(stmt);

                List <DMASTProcBlockInner> recurse;
                switch (stmt)
                {
                case DMASTProcStatementSpawn ps: recurse = new() { ps.Body }; break;

                case DMASTProcStatementIf ps: recurse = new() { ps.Body, ps.ElseBody }; break;

                case DMASTProcStatementFor ps: recurse = new() { ps.Body }; break;

                case DMASTProcStatementForLoop ps: recurse = new() { ps.Body }; break;

                case DMASTProcStatementForRaw ps: recurse = new() { ps.Body }; break;

                case DMASTProcStatementWhile ps: recurse = new() { ps.Body }; break;

                case DMASTProcStatementDoWhile ps: recurse = new() { ps.Body }; break;

                case DMASTProcStatementInfLoop ps: recurse = new() { ps.Body }; break;

                // TODO Good luck if you declare a static var inside a switch
                case DMASTProcStatementSwitch ps: {
                    recurse = new();
                    foreach (var swcase in ps.Cases)
                    {
                        recurse.Add(swcase.Body);
                    }
                    break;
                }

                case DMASTProcStatementTryCatch ps: recurse = new() { ps.TryBody, ps.CatchBody }; break;

                default: recurse = new(); break;
                }
                foreach (var subblock in recurse)
                {
                    if (subblock == null)
                    {
                        continue;
                    }
                    foreach (var substmt in GetStatements(subblock))
                    {
                        yield return(substmt);
                    }
                }
            }
        }
示例#5
0
 public void ProcessBlockInner(DMASTProcBlockInner block)
 {
     // TODO ProcessStatementSet() needs to be before any loops but this is nasty
     foreach (var stmt in block.Statements)
     {
         if (stmt is DMASTProcStatementSet set)
         {
             try
             {
                 ProcessStatementSet(set);
             }
             catch (CompileAbortException e)
             {
                 // The statement's location info isn't passed all the way down so change the error to make it more accurate
                 e.Error.Location = set.Location;
                 DMCompiler.Error(e.Error);
                 return;                       // Don't spam the error that will continue to exist
             }
             catch (CompileErrorException e) { //Retreat from the statement when there's an error
                 DMCompiler.Error(e.Error);
             }
         }
     }
     foreach (DMASTProcStatement statement in block.Statements)
     {
         try
         {
             // see above
             if (statement is DMASTProcStatementSet)
             {
                 continue;
             }
             ProcessStatement(statement);
         }
         catch (CompileAbortException e)
         {
             // The statement's location info isn't passed all the way down so change the error to make it more accurate
             e.Error.Location = statement.Location;
             DMCompiler.Error(e.Error);
             return;                       // Don't spam the error that will continue to exist
         }
         catch (CompileErrorException e) { //Retreat from the statement when there's an error
             DMCompiler.Error(e.Error);
         }
     }
 }
示例#6
0
 public void ProcessBlockInner(DMASTProcBlockInner block)
 {
     foreach (DMASTProcStatement statement in block.Statements)
     {
         try
         {
             ProcessStatement(statement);
         }
         catch (CompileAbortException e)
         {
             // The statement's location info isn't passed all the way down so change the error to make it more accurate
             e.Error.Location = statement.Location;
             DMCompiler.Error(e.Error);
             return;                       // Don't spam the error that will continue to exist
         }
         catch (CompileErrorException e) { //Retreat from the statement when there's an error
             DMCompiler.Error(e.Error);
         }
     }
 }
示例#7
0
 public DMASTProcStatementForRange(DMASTProcStatement initializer, DMASTIdentifier variable, DMASTExpression rangeStart, DMASTExpression rangeEnd, DMASTExpression step, DMASTProcBlockInner body) : base(initializer, body)
 {
     Variable   = variable;
     RangeStart = rangeStart;
     RangeEnd   = rangeEnd;
     Step       = step;
 }
示例#8
0
        public void ProcessStatementSwitch(DMASTProcStatementSwitch statementSwitch)
        {
            string endLabel = _proc.NewLabelName();
            List <(string CaseLabel, DMASTProcBlockInner CaseBody)> valueCases = new();
            DMASTProcBlockInner defaultCaseBody = null;

            DMExpression.Emit(_dmObject, _proc, statementSwitch.Value);
            foreach (DMASTProcStatementSwitch.SwitchCase switchCase in statementSwitch.Cases)
            {
                if (switchCase is DMASTProcStatementSwitch.SwitchCaseValues switchCaseValues)
                {
                    string caseLabel = _proc.NewLabelName();

                    foreach (DMASTExpression value in switchCaseValues.Values)
                    {
                        if (value is DMASTSwitchCaseRange range)
                        {
                            if (!DMExpression.TryConstant(_dmObject, _proc, range.RangeStart, out var lower))
                            {
                                throw new CompileErrorException(new CompilerError(range.RangeStart.Location, "Expected a constant"));
                            }
                            if (!DMExpression.TryConstant(_dmObject, _proc, range.RangeEnd, out var upper))
                            {
                                throw new CompileErrorException(new CompilerError(range.RangeEnd.Location, "Expected a constant"));
                            }

                            lower.EmitPushValue(_dmObject, _proc);
                            upper.EmitPushValue(_dmObject, _proc);
                            _proc.SwitchCaseRange(caseLabel);
                        }
                        else
                        {
                            if (!DMExpression.TryConstant(_dmObject, _proc, value, out var constant))
                            {
                                throw new CompileErrorException(new CompilerError(value.Location, "Expected a constant"));
                            }

                            constant.EmitPushValue(_dmObject, _proc);
                            _proc.SwitchCase(caseLabel);
                        }
                    }

                    valueCases.Add((caseLabel, switchCase.Body));
                }
                else
                {
                    defaultCaseBody = ((DMASTProcStatementSwitch.SwitchCaseDefault)switchCase).Body;
                }
            }
            _proc.Pop();

            if (defaultCaseBody != null)
            {
                _proc.StartScope();
                {
                    ProcessBlockInner(defaultCaseBody);
                }
                _proc.EndScope();
            }
            _proc.Jump(endLabel);

            foreach ((string CaseLabel, DMASTProcBlockInner CaseBody)valueCase in valueCases)
            {
                _proc.AddLabel(valueCase.CaseLabel);
                _proc.StartScope();
                {
                    ProcessBlockInner(valueCase.CaseBody);
                }
                _proc.EndScope();
                _proc.Jump(endLabel);
            }

            _proc.AddLabel(endLabel);
        }
示例#9
0
 public SwitchCaseValues(DMASTExpressionConstant[] values, DMASTProcBlockInner body) : base(body)
 {
     Values = values;
 }
示例#10
0
 public SwitchCaseDefault(DMASTProcBlockInner body) : base(body)
 {
 }
示例#11
0
 protected SwitchCase(DMASTProcBlockInner body)
 {
     Body = body;
 }
示例#12
0
 public DMASTProcStatementDoWhile(DMASTExpression conditional, DMASTProcBlockInner body)
 {
     Conditional = conditional;
     Body        = body;
 }
示例#13
0
 public DMASTProcDefinition(DMASTPath path, DMASTDefinitionParameter[] parameters, DMASTProcBlockInner body)
 {
     Path       = path;
     Parameters = parameters;
     Body       = body;
 }
示例#14
0
 public DMASTProcStatementForList(DMASTProcStatement initializer, DMASTIdentifier variable, DMASTExpression list, DMASTProcBlockInner body) : base(initializer, body)
 {
     Variable = variable;
     List     = list;
 }
示例#15
0
 public DMASTProcStatementForStandard(DMASTProcStatement initializer, DMASTExpression comparator, DMASTExpression incrementor, DMASTProcBlockInner body) : base(initializer, body)
 {
     Comparator  = comparator;
     Incrementor = incrementor;
 }
示例#16
0
 public DMASTProcStatementFor(DMASTProcStatement initializer, DMASTProcBlockInner body)
 {
     Initializer = initializer;
     Body        = body;
 }
示例#17
0
 public DMASTProcStatementIf(DMASTExpression condition, DMASTProcBlockInner body, DMASTProcBlockInner elseBody = null)
 {
     Condition = condition;
     Body      = body;
     ElseBody  = elseBody;
 }
示例#18
0
 public DMASTProcStatementSpawn(DMASTExpression time, DMASTProcBlockInner body)
 {
     Time = time;
     Body = body;
 }