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(); }
public void ProcessStatementThrow(DMASTProcStatementThrow statement) { //TODO proper value handling and catching DMExpression.Emit(_dmObject, _proc, statement.Value); _proc.Throw(); }
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(); }
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(); }
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); } }
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(); }
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(); }
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(); }
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); }
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 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(); }
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(); }
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); }
public void ProcessStatementDel(DMASTProcStatementDel statementDel) { DMExpression.Emit(_dmObject, _proc, statementDel.Value); _proc.DeleteObject(); }
public void ProcessStatementExpression(DMASTProcStatementExpression statement) { DMExpression.Emit(_dmObject, _proc, statement.Expression); _proc.Pop(); }