コード例 #1
0
 public void ProcessStatementOutputControl(DMASTProcStatementOutputControl statementOutputControl)
 {
     DMExpression.Emit(_dmObject, _proc, statementOutputControl.Receiver);
     DMExpression.Emit(_dmObject, _proc, statementOutputControl.Message);
     DMExpression.Emit(_dmObject, _proc, statementOutputControl.Control);
     _proc.OutputControl();
 }
コード例 #2
0
        public void ProcessStatementThrow(DMASTProcStatementThrow statement)
        {
            //TODO proper value handling and catching

            DMExpression.Emit(_dmObject, _proc, statement.Value);
            _proc.Throw();
        }
コード例 #3
0
 public void ProcessStatementBrowse(DMASTProcStatementBrowse statementBrowse)
 {
     DMExpression.Emit(_dmObject, _proc, statementBrowse.Receiver);
     DMExpression.Emit(_dmObject, _proc, statementBrowse.Body);
     DMExpression.Emit(_dmObject, _proc, statementBrowse.Options);
     _proc.Browse();
 }
コード例 #4
0
 public void ProcessStatementBrowseResource(DMASTProcStatementBrowseResource statementBrowseResource)
 {
     DMExpression.Emit(_dmObject, _proc, statementBrowseResource.Receiver);
     DMExpression.Emit(_dmObject, _proc, statementBrowseResource.File);
     DMExpression.Emit(_dmObject, _proc, statementBrowseResource.Filename);
     _proc.BrowseResource();
 }
コード例 #5
0
        public void ProcessStatementIf(DMASTProcStatementIf statement)
        {
            DMExpression.Emit(_dmObject, _proc, statement.Condition);

            if (statement.ElseBody == null)
            {
                string endLabel = _proc.NewLabelName();

                _proc.JumpIfFalse(endLabel);
                _proc.StartScope();
                ProcessBlockInner(statement.Body);
                _proc.EndScope();
                _proc.AddLabel(endLabel);
            }
            else
            {
                string elseLabel = _proc.NewLabelName();
                string endLabel  = _proc.NewLabelName();

                _proc.JumpIfFalse(elseLabel);

                _proc.StartScope();
                ProcessBlockInner(statement.Body);
                _proc.EndScope();
                _proc.Jump(endLabel);

                _proc.AddLabel(elseLabel);
                ProcessBlockInner(statement.ElseBody);
                _proc.AddLabel(endLabel);
            }
        }
コード例 #6
0
        public void ProcessStatementForRange(DMASTProcStatementForRange statementForRange)
        {
            DMExpression.Emit(_dmObject, _proc, statementForRange.RangeStart);
            DMExpression.Emit(_dmObject, _proc, statementForRange.RangeEnd);
            DMExpression.Emit(_dmObject, _proc, statementForRange.Step);
            _proc.CreateRangeEnumerator();
            _proc.StartScope();
            {
                if (statementForRange.Initializer != null)
                {
                    ProcessStatement(statementForRange.Initializer);
                }

                string loopLabel = _proc.NewLabelName();
                _proc.LoopStart(loopLabel);
                {
                    DMExpression outputVariable = DMExpression.Create(_dmObject, _proc, statementForRange.Variable);
                    (DMReference outputRef, _) = outputVariable.EmitReference(_dmObject, _proc);
                    _proc.Enumerate(outputRef);
                    _proc.BreakIfFalse();

                    ProcessBlockInner(statementForRange.Body);

                    _proc.LoopContinue(loopLabel);
                    _proc.LoopJumpToStart(loopLabel);
                }
                _proc.LoopEnd();
            }
            _proc.EndScope();
            _proc.DestroyEnumerator();
        }
コード例 #7
0
        public void ProcessStatementForStandard(DMASTProcStatementForStandard statementForStandard)
        {
            _proc.StartScope();
            {
                if (statementForStandard.Initializer != null)
                {
                    ProcessStatement(statementForStandard.Initializer);
                }

                string loopLabel = _proc.NewLabelName();
                _proc.LoopStart(loopLabel);
                {
                    DMExpression.Emit(_dmObject, _proc, statementForStandard.Comparator);
                    _proc.BreakIfFalse();

                    ProcessBlockInner(statementForStandard.Body);

                    _proc.LoopContinue(loopLabel);
                    if (statementForStandard.Incrementor != null)
                    {
                        DMExpression.Emit(_dmObject, _proc, statementForStandard.Incrementor);
                        _proc.Pop();
                    }
                    _proc.LoopJumpToStart(loopLabel);
                }
                _proc.LoopEnd();
            }
            _proc.EndScope();
        }
コード例 #8
0
        public void ProcessStatementReturn(DMASTProcStatementReturn statement)
        {
            if (statement.Value != null)
            {
                DMExpression.Emit(_dmObject, _proc, statement.Value);
            }
            else
            {
                _proc.PushReferenceValue(DMReference.Self); //Default return value
            }

            _proc.Return();
        }
コード例 #9
0
        public void ProcessStatementSpawn(DMASTProcStatementSpawn statementSpawn)
        {
            DMExpression.Emit(_dmObject, _proc, statementSpawn.Delay);

            string afterSpawnLabel = _proc.NewLabelName();

            _proc.Spawn(afterSpawnLabel);

            ProcessBlockInner(statementSpawn.Body);

            //Prevent the new thread from executing outside its own code
            _proc.PushNull();
            _proc.Return();

            _proc.AddLabel(afterSpawnLabel);
        }
コード例 #10
0
        public void ProcessStatementForList(DMASTProcStatementForList statementForList)
        {
            DMExpression.Emit(_dmObject, _proc, statementForList.List);
            _proc.CreateListEnumerator();
            _proc.StartScope();
            {
                if (statementForList.Initializer != null)
                {
                    ProcessStatement(statementForList.Initializer);
                }

                string loopLabel = _proc.NewLabelName();
                _proc.LoopStart(loopLabel);
                {
                    DMExpression outputVariable = DMExpression.Create(_dmObject, _proc, statementForList.Variable);
                    (DMReference outputRef, _) = outputVariable.EmitReference(_dmObject, _proc);
                    _proc.Enumerate(outputRef);
                    _proc.BreakIfFalse();

                    DMASTProcStatementVarDeclaration varDeclaration = statementForList.Initializer as DMASTProcStatementVarDeclaration;
                    if (varDeclaration != null && varDeclaration.Type != null)
                    {
                        //This is terrible but temporary
                        //TODO: See https://github.com/wixoaGit/OpenDream/issues/50
                        var obj = DMObjectTree.GetDMObject(varDeclaration.Type.Value);
                        if (statementForList.List is DMASTIdentifier list && list.Identifier == "world" && !obj.IsSubtypeOf(DreamPath.Atom))
                        {
                            var warn = new CompilerWarning(statementForList.Location, "Cannot currently loop 'in world' for non-ATOM types");
                            DMCompiler.Warning(warn);
                        }
                        DMExpression.Emit(_dmObject, _proc, statementForList.Variable);
                        _proc.PushPath(varDeclaration.Type.Value);
                        _proc.IsType();

                        _proc.ContinueIfFalse();
                    }

                    ProcessBlockInner(statementForList.Body);

                    _proc.LoopContinue(loopLabel);
                    _proc.LoopJumpToStart(loopLabel);
                }
                _proc.LoopEnd();
            }
            _proc.EndScope();
            _proc.DestroyEnumerator();
        }
コード例 #11
0
        public void ProcessStatementDoWhile(DMASTProcStatementDoWhile statementDoWhile)
        {
            string loopLabel    = _proc.NewLabelName();
            string loopEndLabel = _proc.NewLabelName();

            _proc.LoopStart(loopLabel);
            {
                ProcessBlockInner(statementDoWhile.Body);

                _proc.LoopContinue(loopLabel);
                DMExpression.Emit(_dmObject, _proc, statementDoWhile.Conditional);
                _proc.JumpIfFalse(loopEndLabel);
                _proc.LoopJumpToStart(loopLabel);

                _proc.AddLabel(loopEndLabel);
                _proc.Break();
            }
            _proc.LoopEnd();
        }
コード例 #12
0
        public void ProcessProcDefinition(DMASTProcDefinition procDefinition)
        {
            if (procDefinition.Body == null)
            {
                return;
            }

            foreach (DMASTDefinitionParameter parameter in procDefinition.Parameters)
            {
                string parameterName = parameter.Name;

                if (!_proc.TryAddLocalVariable(parameterName, parameter.ObjectType))
                {
                    DMCompiler.Error(new CompilerError(procDefinition.Location, $"Duplicate argument \"{parameterName}\" on {procDefinition.ObjectPath}/proc/{procDefinition.Name}()"));
                    continue;
                }

                if (parameter.Value != null)   //Parameter has a default value
                {
                    string      afterDefaultValueCheck = _proc.NewLabelName();
                    DMReference parameterRef           = _proc.GetLocalVariableReference(parameterName);

                    //Don't set parameter to default if not null
                    _proc.PushReferenceValue(parameterRef);
                    _proc.IsNull();
                    _proc.JumpIfFalse(afterDefaultValueCheck);

                    //Set default
                    try {
                        DMExpression.Emit(_dmObject, _proc, parameter.Value, parameter.ObjectType);
                    } catch (CompileErrorException e) {
                        DMCompiler.Error(e.Error);
                    }
                    _proc.Assign(parameterRef);
                    _proc.Pop();

                    _proc.AddLabel(afterDefaultValueCheck);
                }
            }

            ProcessBlockInner(procDefinition.Body);
            _proc.ResolveLabels();
        }
コード例 #13
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);
        }
コード例 #14
0
 public void ProcessStatementDel(DMASTProcStatementDel statementDel)
 {
     DMExpression.Emit(_dmObject, _proc, statementDel.Value);
     _proc.DeleteObject();
 }
コード例 #15
0
 public void ProcessStatementExpression(DMASTProcStatementExpression statement)
 {
     DMExpression.Emit(_dmObject, _proc, statement.Expression);
     _proc.Pop();
 }