Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve parity handling of null in various operators #2129

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 39 additions & 9 deletions OpenDreamRuntime/Procs/DMOpcodeHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -923,14 +923,16 @@ public static ProcStatus BitShiftLeft(DMProcState state) {
case DreamValue.DreamValueType.Float when second.Type == DreamValue.DreamValueType.Float:
state.Push(new DreamValue(first.MustGetValueAsInteger() << second.MustGetValueAsInteger()));
break;
case DreamValue.DreamValueType.Float when second.IsNull:
state.Push(new DreamValue(first.MustGetValueAsInteger()));
break;
default:
throw new Exception($"Invalid bit shift left operation on {first} and {second}");
}

return ProcStatus.Continue;
}


public static ProcStatus BitShiftLeftReference(DMProcState state) {
DreamReference reference = state.ReadReference();
DreamValue second = state.Pop();
Expand All @@ -943,9 +945,13 @@ public static ProcStatus BitShiftLeftReference(DMProcState state) {
case DreamValue.DreamValueType.Float when second.Type == DreamValue.DreamValueType.Float:
result = new DreamValue(first.MustGetValueAsInteger() << second.MustGetValueAsInteger());
break;
case DreamValue.DreamValueType.Float when second.IsNull:
result = new DreamValue(first.MustGetValueAsInteger());
break;
default:
throw new Exception($"Invalid bit shift left operation on {first} and {second}");
}

state.AssignReference(reference, result);
state.Push(result);
return ProcStatus.Continue;
Expand All @@ -955,12 +961,18 @@ public static ProcStatus BitShiftRight(DMProcState state) {
DreamValue second = state.Pop();
DreamValue first = state.Pop();

if (first.IsNull) {
state.Push(new DreamValue(0));
} else if (first.Type == DreamValue.DreamValueType.Float && second.Type == DreamValue.DreamValueType.Float) {
state.Push(new DreamValue(first.MustGetValueAsInteger() >> second.MustGetValueAsInteger()));
} else {
throw new Exception($"Invalid bit shift right operation on {first} and {second}");
switch (first.Type) {
case DreamValue.DreamValueType.DreamObject when first.IsNull:
state.Push(new DreamValue(0));
break;
case DreamValue.DreamValueType.Float when second.Type == DreamValue.DreamValueType.Float:
state.Push(new DreamValue(first.MustGetValueAsInteger() >> second.MustGetValueAsInteger()));
break;
case DreamValue.DreamValueType.Float when second.IsNull:
state.Push(new DreamValue(first.MustGetValueAsInteger()));
break;
default:
throw new Exception($"Invalid bit shift right operation on {first} and {second}");
}

return ProcStatus.Continue;
Expand All @@ -978,9 +990,13 @@ public static ProcStatus BitShiftRightReference(DMProcState state) {
case DreamValue.DreamValueType.Float when second.Type == DreamValue.DreamValueType.Float:
result = new DreamValue(first.MustGetValueAsInteger() >> second.MustGetValueAsInteger());
break;
case DreamValue.DreamValueType.Float when second.IsNull:
result = new DreamValue(first.MustGetValueAsInteger());
break;
default:
throw new Exception($"Invalid bit shift right operation on {first} and {second}");
}

state.AssignReference(reference, result);
state.Push(result);
return ProcStatus.Continue;
Expand Down Expand Up @@ -1128,6 +1144,9 @@ public static ProcStatus Mask(DMProcState state) {
case DreamValue.DreamValueType.Float when second.Type == DreamValue.DreamValueType.Float:
result = new DreamValue(first.MustGetValueAsInteger() & second.MustGetValueAsInteger());
break;
case DreamValue.DreamValueType.Float when second.IsNull:
result = new DreamValue(0);
break;
default:
throw new Exception("Invalid mask operation on " + first + " and " + second);
}
Expand Down Expand Up @@ -2728,8 +2747,19 @@ private static DreamValue BitXorValues(DreamObjectTree objectTree, DreamValue fi
}

return new DreamValue(newList);
} else {
return new DreamValue(first.MustGetValueAsInteger() ^ second.MustGetValueAsInteger());
}

switch (first.Type) {
case DreamValue.DreamValueType.Float when second.Type == DreamValue.DreamValueType.Float:
return new DreamValue(first.MustGetValueAsInteger() ^ second.MustGetValueAsInteger());
case DreamValue.DreamValueType.DreamObject when first.IsNull && second.IsNull:
return DreamValue.Null;
case DreamValue.DreamValueType.DreamObject when first.IsNull && second.Type == DreamValue.DreamValueType.Float:
return new DreamValue(second.MustGetValueAsInteger());
case DreamValue.DreamValueType.Float when second.IsNull:
return new DreamValue(first.MustGetValueAsInteger());
default:
throw new Exception($"Invalid xor operation on {first} and {second}");
}
}

Expand Down
Loading