Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into particles_od
Browse files Browse the repository at this point in the history
  • Loading branch information
amylizzle committed Feb 20, 2025
2 parents 45e7f16 + 6ffc519 commit 51638ab
Show file tree
Hide file tree
Showing 32 changed files with 351 additions and 82 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/compiler-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ jobs:
ref: dev
path: nebula
- name: Compile Nebula Dev
run: main\bin\DMCompiler\DMCompiler.exe nebula\nebula.dme --suppress-unimplemented
run: main\bin\DMCompiler\DMCompiler.exe nebula\nebula.dme --suppress-unimplemented --version=516.1655
- name: Checkout /vg/station Master
uses: actions/checkout@v2
with:
repository: vgstation-coders/vgstation13
ref: Bleeding-Edge
path: vg
- name: Compile /vg/station Master
run: main\bin\DMCompiler\DMCompiler.exe vg\vgstation13.dme --suppress-unimplemented
run: main\bin\DMCompiler\DMCompiler.exe vg\vgstation13.dme --suppress-unimplemented --version=516.1655
- name: Checkout CM Master
uses: actions/checkout@v2
with:
Expand All @@ -99,4 +99,4 @@ jobs:
ref: master
path: aurora
- name: Compile Aurora Master
run: main\bin\DMCompiler\DMCompiler.exe aurora\aurorastation.dme --suppress-unimplemented
run: main\bin\DMCompiler\DMCompiler.exe aurora\aurorastation.dme --suppress-unimplemented --version=516.1655
18 changes: 18 additions & 0 deletions Content.Tests/DMProject/Tests/Builtins/astype.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

/datum/foo
/datum/foo/bar

/proc/test_null()
var/datum/D = new
var/datum/foo/bar/B = astype(D)
return isnull(B)

/proc/test_type()
var/datum/foo/bar/B = new
var/datum/D = astype(B)
var/datum/foo/F = astype(D)
return F.type

/proc/RunTest()
ASSERT(test_null())
ASSERT(test_type() == /datum/foo/bar)
10 changes: 10 additions & 0 deletions Content.Tests/DMProject/Tests/Builtins/sign.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

/proc/RunTest()
ASSERT(sign(5.2) == 1)
ASSERT(sign(-5.2) == -1)
ASSERT(sign(0) == 0)
ASSERT(sign(null) == 0)
ASSERT(sign("") == 0)
ASSERT(sign("foo") == 0)
ASSERT(sign(list(1)) == 0)

10 changes: 10 additions & 0 deletions Content.Tests/DMProject/Tests/List/ListSplice.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

/proc/RunTest()
var/list/L = list("foo", "bar", "test", "value")
L.Splice(2, 4, "lorem", "ipsum", "word", "another word")
ASSERT(L ~= list("foo","lorem","ipsum","word","another word","value"))

// Again with list() as the arg
var/list/L2 = list("foo", "bar", "test", "value")
L2.Splice(2, 4, list("lorem", "ipsum", "word", "another word"))
ASSERT(L2 ~= list("foo","lorem","ipsum","word","another word","value"))
3 changes: 2 additions & 1 deletion DMCompiler/Bytecode/DreamProcOpcode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ public enum DreamProcOpcode : byte {
Ftp = 0x46,
[OpcodeMetadata(-1)]
Initial = 0x47,
//0x48
[OpcodeMetadata(-1)]
AsType = 0x48,
[OpcodeMetadata(-1)]
IsType = 0x49,
[OpcodeMetadata(-2)]
Expand Down
1 change: 1 addition & 0 deletions DMCompiler/Compiler/DM/AST/DMAST.ExpressionBinary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public sealed class DMASTPower(Location location, DMASTExpression a, DMASTExpres
public sealed class DMASTAdd(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
public sealed class DMASTSubtract(Location location, DMASTExpression a, DMASTExpression b) : DMASTBinary(location, a, b);
public sealed class DMASTArctan2(Location location, DMASTExpression xExpression, DMASTExpression yExpression) : DMASTBinary(location, xExpression, yExpression);
public sealed class DMASTAsType(Location location, DMASTExpression value, DMASTExpression type) : DMASTBinary(location, value, type);
public sealed class DMASTIsType(Location location, DMASTExpression value, DMASTExpression type) : DMASTBinary(location, value, type);
public sealed class DMASTGetStep(Location location, DMASTExpression refValue, DMASTExpression dir) : DMASTBinary(location, refValue, dir);
public sealed class DMASTGetDir(Location location, DMASTExpression loc1, DMASTExpression loc2) : DMASTBinary(location, loc1, loc2);
Expand Down
1 change: 1 addition & 0 deletions DMCompiler/Compiler/DM/AST/DMAST.ExpressionUnary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public sealed class DMASTNameof(Location location, DMASTExpression expression) :
public sealed class DMASTIsSaved(Location location, DMASTExpression expression) : DMASTUnary(location, expression);
public sealed class DMASTIsNull(Location location, DMASTExpression value) : DMASTUnary(location, value);
public sealed class DMASTLength(Location location, DMASTExpression value) : DMASTUnary(location, value);
public sealed class DMASTImplicitAsType(Location location, DMASTExpression value) : DMASTUnary(location, value);
public sealed class DMASTImplicitIsType(Location location, DMASTExpression value) : DMASTUnary(location, value);

/// <summary>
Expand Down
10 changes: 10 additions & 0 deletions DMCompiler/Compiler/DM/DMParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2641,6 +2641,16 @@ private void BracketWhitespace() {
? new DMASTLog(callLoc, callParameters[0].Value, null)
: new DMASTLog(callLoc, callParameters[1].Value, callParameters[0].Value);
}
case "astype": {
if (callParameters.Length != 1 && callParameters.Length != 2) {
Emit(WarningCode.InvalidArgumentCount, callLoc, "astype() requires 1 or 2 arguments");
return new DMASTInvalidExpression(callLoc);
}

return callParameters.Length == 1
? new DMASTImplicitAsType(callLoc, callParameters[0].Value)
: new DMASTAsType(callLoc, callParameters[0].Value, callParameters[1].Value);
}
case "istype": {
if (callParameters.Length != 1 && callParameters.Length != 2) {
Emit(WarningCode.InvalidArgumentCount, callLoc, "istype() requires 1 or 2 arguments");
Expand Down
35 changes: 21 additions & 14 deletions DMCompiler/DM/Builders/DMExpressionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ private DMExpression BuildExpression(DMASTExpression expression, DreamPath? infe
case DMASTNotEqual notEqual: result = BuildNotEqual(notEqual, inferredPath); break;
case DMASTDereference deref: result = BuildDereference(deref, inferredPath); break;
case DMASTLocate locate: result = BuildLocate(locate, inferredPath); break;
case DMASTImplicitAsType implicitAsType: result = BuildImplicitAsType(implicitAsType, inferredPath); break;
case DMASTImplicitIsType implicitIsType: result = BuildImplicitIsType(implicitIsType, inferredPath); break;
case DMASTList list: result = BuildList(list, inferredPath); break;
case DMASTDimensionalList dimensionalList: result = BuildDimensionalList(dimensionalList, inferredPath); break;
Expand Down Expand Up @@ -338,25 +339,21 @@ private DMExpression BuildExpression(DMASTExpression expression, DreamPath? infe
BuildExpression(locateCoordinates.Y, inferredPath),
BuildExpression(locateCoordinates.Z, inferredPath));
break;
case DMASTAsType asType: {
var lhs = BuildExpression(asType.LHS, inferredPath);
var rhs = BuildExpression(asType.RHS, lhs.Path);

result = new AsType(asType.Location, lhs, rhs);
break;
}
case DMASTIsSaved isSaved:
result = new IsSaved(isSaved.Location, BuildExpression(isSaved.Value, inferredPath));
break;
case DMASTIsType isType: {
if (isType.RHS is DMASTIdentifier { Identifier: "__IMPLIED_TYPE__" }) {
var expr = BuildExpression(isType.LHS, inferredPath);
if (expr.Path is null) {
result = BadExpression(WarningCode.BadExpression, isType.Location,
"A type could not be inferred!");
break;
}
var lhs = BuildExpression(isType.LHS, inferredPath);
var rhs = BuildExpression(isType.RHS, lhs.Path);

result = new IsTypeInferred(isType.Location, expr, expr.Path.Value);
break;
}

result = new IsType(isType.Location,
BuildExpression(isType.LHS, inferredPath),
BuildExpression(isType.RHS, inferredPath));
result = new IsType(isType.Location, lhs, rhs);
break;
}

Expand Down Expand Up @@ -1072,6 +1069,16 @@ private DMExpression BuildLocate(DMASTLocate locate, DreamPath? inferredPath) {
return new Locate(locate.Location, pathExpr, container);
}

private DMExpression BuildImplicitAsType(DMASTImplicitAsType asType, DreamPath? inferredPath) {
var expr = BuildExpression(asType.Value, inferredPath);

if (inferredPath is null) {
return BadExpression(WarningCode.BadExpression, asType.Location, "Could not infer a type");
}

return new AsTypeInferred(asType.Location, expr, inferredPath.Value);
}

private DMExpression BuildImplicitIsType(DMASTImplicitIsType isType, DreamPath? inferredPath) {
var expr = BuildExpression(isType.Value, inferredPath);

Expand Down
25 changes: 18 additions & 7 deletions DMCompiler/DM/DMCodeTree.Vars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public override bool TryDefineVar(DMCompiler compiler, int pass) {
if (!compiler.DMObjectTree.TryGetDMObject(owner, out var dmObject))
return false;

if (AlreadyExists(compiler, dmObject)) {
if (CheckCantDefine(compiler, dmObject)) {
_defined = true;
return true;
}
Expand Down Expand Up @@ -162,12 +162,23 @@ private bool HandleInstanceVar(DMCompiler compiler, DMObject dmObject) {
return true;
}

private bool AlreadyExists(DMCompiler compiler, DMObject dmObject) {
// "type" and "tag" can only be defined in DMStandard
if (VarName is "type" or "tag" && !varDef.Location.InDMStandard) {
compiler.Emit(WarningCode.InvalidVarDefinition, varDef.Location,
$"Cannot redefine built-in var \"{VarName}\"");
return true;
private bool CheckCantDefine(DMCompiler compiler, DMObject dmObject) {
if (!compiler.Settings.NoStandard) {
var inStandard = varDef.Location.InDMStandard;

// "type" and "tag" can only be defined in DMStandard
if (VarName is "type" or "tag" && !inStandard) {
compiler.Emit(WarningCode.InvalidVarDefinition, varDef.Location,
$"Cannot redefine built-in var \"{VarName}\"");
return true;
}

// Vars on /world and /list can only be defined in DMStandard
if ((dmObject.Path == DreamPath.World || dmObject.Path == DreamPath.List) && !inStandard) {
compiler.Emit(WarningCode.InvalidVarDefinition, varDef.Location,
$"Cannot define a var on type {dmObject.Path}");
return true;
}
}

//DMObjects store two bundles of variables; the statics in GlobalVariables and the non-statics in Variables.
Expand Down
4 changes: 4 additions & 0 deletions DMCompiler/DM/DMProc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,10 @@ public void IsSaved() {
WriteOpcode(DreamProcOpcode.IsSaved);
}

public void AsType() {
WriteOpcode(DreamProcOpcode.AsType);
}

public void IsType() {
WriteOpcode(DreamProcOpcode.IsType);
}
Expand Down
24 changes: 24 additions & 0 deletions DMCompiler/DM/Expressions/Builtins.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,30 @@ public override void EmitPushValue(ExpressionContext ctx) {
}
}

// astype(x, y)
internal sealed class AsType(Location location, DMExpression expr, DMExpression path) : DMExpression(location) {
public override void EmitPushValue(ExpressionContext ctx) {
expr.EmitPushValue(ctx);
path.EmitPushValue(ctx);
ctx.Proc.AsType();
}
}

// astype(x)
internal sealed class AsTypeInferred(Location location, DMExpression expr, DreamPath path) : DMExpression(location) {
public override void EmitPushValue(ExpressionContext ctx) {
if (!ctx.ObjectTree.TryGetTypeId(path, out var typeId)) {
ctx.Compiler.Emit(WarningCode.ItemDoesntExist, Location, $"Type {path} does not exist");

return;
}

expr.EmitPushValue(ctx);
ctx.Proc.PushType(typeId);
ctx.Proc.AsType();
}
}

// istype(x, y)
internal sealed class IsType(Location location, DMExpression expr, DMExpression path) : DMExpression(location) {
public override DMComplexValueType ValType => DMValueType.Num;
Expand Down
4 changes: 1 addition & 3 deletions DMCompiler/DMStandard/Types/List.dm
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,4 @@
proc/Remove(Item1)
proc/RemoveAll(Item1)
proc/Swap(Index1, Index2)

proc/Splice(Start=1,End=0, ...)
set opendream_unimplemented = TRUE
proc/Splice(Start = 1 as num, End = 0 as num, Item1, ...) as null
5 changes: 4 additions & 1 deletion DMCompiler/DMStandard/Types/Sound.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@
var/pan = 0 as opendream_unimplemented
var/params = null as opendream_unimplemented
var/falloff = 1 as opendream_unimplemented

var/atom/atom as opendream_unimplemented
var/transform as opendream_unimplemented
var/x as opendream_unimplemented
var/y as opendream_unimplemented
var/z as opendream_unimplemented

var/environment as opendream_unimplemented
var/echo as opendream_unimplemented
var/len as opendream_unimplemented
var/offset as opendream_unimplemented
var/offset

var/priority = 0 as opendream_unimplemented
var/status = 0 as opendream_unimplemented
Expand Down
2 changes: 1 addition & 1 deletion DMCompiler/DMStandard/_Standard.dm
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ proc/roll(ndice = 1, sides) as num
proc/round(A, B) as num
proc/sha1(input) as text|null
proc/shutdown(Addr,Natural = 0)
proc/sign(A) as num
proc/sleep(Delay)
proc/sorttext(T1, T2) as num
proc/sorttextEx(T1, T2) as num
Expand Down Expand Up @@ -113,7 +114,6 @@ proc/viewers(Depth, Center = usr) as /list
proc/walk(Ref, Dir, Lag = 0, Speed = 0)
proc/walk_rand(Ref,Lag = 0,Speed = 0)
proc/walk_to(Ref, Trg, Min = 0, Lag = 0, Speed = 0)
set opendream_unimplemented = 1
proc/walk_towards(Ref,Trg,Lag=0,Speed=0)
proc/winclone(player, window_name, clone_name)
proc/winexists(player, control_id) as text
Expand Down
25 changes: 25 additions & 0 deletions DMCompiler/Optimizer/BytecodeOptimizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,17 @@ internal void Optimize(List<IAnnotatedBytecode> input) {
RemoveUnreferencedLabels(input);
JoinAndForwardLabels(input);
RemoveUnreferencedLabels(input);
RemoveImmediateJumps(input);
RemoveUnreferencedLabels(input);

_peepholeOptimizer.RunPeephole(input);

// Run label optimizations again due to possibly removed jumps in peephole optimizers
RemoveUnreferencedLabels(input);
JoinAndForwardLabels(input);
RemoveUnreferencedLabels(input);
RemoveImmediateJumps(input);
RemoveUnreferencedLabels(input);
}

private void RemoveUnreferencedLabels(List<IAnnotatedBytecode> input) {
Expand All @@ -40,6 +49,22 @@ private void RemoveUnreferencedLabels(List<IAnnotatedBytecode> input) {
}
}

/**
* <summary>Removes jumps for which the next element is the jump's destination</summary>
*/
private void RemoveImmediateJumps(List<IAnnotatedBytecode> input) {
for (int i = input.Count - 2; i >= 0; i--) {
if (input[i] is AnnotatedBytecodeInstruction { Opcode: Bytecode.DreamProcOpcode.Jump } instruction) {
if (input[i + 1] is AnnotatedBytecodeLabel followingLabel) {
AnnotatedBytecodeLabel jumpLabelName = instruction.GetArg<AnnotatedBytecodeLabel>(0);
if (jumpLabelName.LabelName == followingLabel.LabelName) {
input.RemoveAt(i);
}
}
}
}
}

private void JoinAndForwardLabels(List<IAnnotatedBytecode> input) {
Dictionary<string, string> labelAliases = new();
for (int i = 0; i < input.Count; i++) {
Expand Down
5 changes: 0 additions & 5 deletions DMCompiler/copy_standard.bat

This file was deleted.

19 changes: 0 additions & 19 deletions DMCompiler/copy_standard.sh

This file was deleted.

6 changes: 3 additions & 3 deletions OpenDreamClient/Audio/DreamSoundEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public void Initialize() {
_netManager.Disconnect += DisconnectedFromServer;
}

public void PlaySound(int channel, MsgSound.FormatType format, ResourceSound sound, float volume) {
public void PlaySound(int channel, MsgSound.FormatType format, ResourceSound sound, float volume, float offset) {
if (_audioSystem == null)
_entitySystemManager.Resolve(ref _audioSystem);

Expand Down Expand Up @@ -59,7 +59,7 @@ public void PlaySound(int channel, MsgSound.FormatType format, ResourceSound sou
}

var db = 20 * MathF.Log10(volume); // convert from DM volume (0-100) to OpenAL volume (db)
var source = _audioSystem.PlayGlobal(stream, AudioParams.Default.WithVolume(db)); // TODO: Positional audio.
var source = _audioSystem.PlayGlobal(stream, AudioParams.Default.WithVolume(db).WithPlayOffset(offset)); // TODO: Positional audio.
if (source == null) {
_sawmill.Error($"Failed to play audio ${sound}");
return;
Expand All @@ -86,7 +86,7 @@ public void StopAllChannels() {
private void RxSound(MsgSound msg) {
if (msg.ResourceId.HasValue) {
_resourceManager.LoadResourceAsync<ResourceSound>(msg.ResourceId.Value,
sound => PlaySound(msg.Channel, msg.Format!.Value, sound, msg.Volume / 100.0f));
sound => PlaySound(msg.Channel, msg.Format!.Value, sound, msg.Volume / 100.0f, msg.Offset));
} else {
StopChannel(msg.Channel);
}
Expand Down
2 changes: 1 addition & 1 deletion OpenDreamClient/Audio/IDreamSoundEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace OpenDreamClient.Audio;

public interface IDreamSoundEngine {
void Initialize();
void PlaySound(int channel, MsgSound.FormatType format, ResourceSound sound, float volume);
void PlaySound(int channel, MsgSound.FormatType format, ResourceSound sound, float volume, float offset);
void StopChannel(int channel);
void StopAllChannels();
}
Loading

0 comments on commit 51638ab

Please sign in to comment.