Esempio n. 1
0
 public DMASTProcStatementForLoop(DMASTProcStatementVarDeclaration variableDeclaration, DMASTCallable variable, DMASTExpression condition, DMASTExpression incrementer, DMASTProcBlockInner body)
 {
     VariableDeclaration = variableDeclaration;
     Variable            = variable;
     Condition           = condition;
     Incrementer         = incrementer;
     Body = body;
 }
Esempio n. 2
0
        public void ProcessStatementVarDeclaration(DMASTProcStatementVarDeclaration varDeclaration)
        {
            if (varDeclaration.IsGlobal)
            {
                return;
            }                                        //Currently handled by DMObjectBuilder

            DMExpression value;

            if (varDeclaration.Value != null)
            {
                try {
                    value = DMExpression.Create(_dmObject, _proc, varDeclaration.Value, varDeclaration.Type);
                } catch (CompileErrorException e) {
                    DMCompiler.Error(e.Error);
                    value = new Expressions.Null(varDeclaration.Location);
                }
            }
            else
            {
                value = new Expressions.Null(varDeclaration.Location);
            }

            bool successful;

            if (varDeclaration.IsConst)
            {
                if (!value.TryAsConstant(out var constValue))
                {
                    DMCompiler.Error(new CompilerError(varDeclaration.Location, "Const var must be set to a constant"));
                    return;
                }

                successful = _proc.TryAddLocalConstVariable(varDeclaration.Name, varDeclaration.Type, constValue);
            }
            else
            {
                successful = _proc.TryAddLocalVariable(varDeclaration.Name, varDeclaration.Type);
            }

            if (!successful)
            {
                DMCompiler.Error(new CompilerError(varDeclaration.Location, $"Duplicate var {varDeclaration.Name}"));
                return;
            }

            value.EmitPushValue(_dmObject, _proc);
            _proc.Assign(_proc.GetLocalVariableReference(varDeclaration.Name));
            _proc.Pop();
        }
Esempio n. 3
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();
        }
Esempio n. 4
0
 public void VisitProcStatementVarDeclaration(DMASTProcStatementVarDeclaration varDeclaration)
 {
     SimplifyExpression(ref varDeclaration.Value);
 }