public DMASTProcStatementForLoop(DMASTProcStatementVarDeclaration variableDeclaration, DMASTCallable variable, DMASTExpression condition, DMASTExpression incrementer, DMASTProcBlockInner body) { VariableDeclaration = variableDeclaration; Variable = variable; Condition = condition; Incrementer = incrementer; Body = body; }
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(); }
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(); }
public void VisitProcStatementVarDeclaration(DMASTProcStatementVarDeclaration varDeclaration) { SimplifyExpression(ref varDeclaration.Value); }