diff --git a/Content.Tests/DMProject/Tests/SpecialProcs/initial/initial_global.dm b/Content.Tests/DMProject/Tests/SpecialProcs/initial/initial_global.dm new file mode 100644 index 0000000000..f91ca13fc3 --- /dev/null +++ b/Content.Tests/DMProject/Tests/SpecialProcs/initial/initial_global.dm @@ -0,0 +1,3 @@ +// COMPILE ERROR OD0011 +/proc/RunTest() + initial(global) diff --git a/Content.Tests/DMProject/Tests/SpecialProcs/initial/initial_proc_args.dm b/Content.Tests/DMProject/Tests/SpecialProcs/initial/initial_proc_args.dm index f1c9fb49f0..9b977a5d1b 100644 --- a/Content.Tests/DMProject/Tests/SpecialProcs/initial/initial_proc_args.dm +++ b/Content.Tests/DMProject/Tests/SpecialProcs/initial/initial_proc_args.dm @@ -9,6 +9,7 @@ ASSERT(initial(b) == 5) ASSERT(initial(c) == "e") + ASSERT(initial(args[2]) == 5) /proc/RunTest() someargs("3", 5, c = "cc") diff --git a/Content.Tests/DMProject/Tests/SpecialProcs/initial/initial_procself.dm b/Content.Tests/DMProject/Tests/SpecialProcs/initial/initial_procself.dm new file mode 100644 index 0000000000..0a68d6f82b --- /dev/null +++ b/Content.Tests/DMProject/Tests/SpecialProcs/initial/initial_procself.dm @@ -0,0 +1,3 @@ +/proc/RunTest() + . = "foo" + ASSERT(initial(.) == "foo") diff --git a/DMCompiler/DM/Expressions/LValue.cs b/DMCompiler/DM/Expressions/LValue.cs index 79a967aa6b..31ced31aa2 100644 --- a/DMCompiler/DM/Expressions/LValue.cs +++ b/DMCompiler/DM/Expressions/LValue.cs @@ -25,10 +25,7 @@ public void EmitPushValueNoConstant(ExpressionContext ctx) { ctx.Proc.AddLabel(endLabel); } - public virtual void EmitPushInitial(ExpressionContext ctx) { - ctx.Compiler.Emit(WarningCode.BadExpression, Location, $"Can't get initial value of {this}"); - ctx.Proc.PushNullAndError(); - } + public abstract void EmitPushInitial(ExpressionContext ctx); } /// @@ -42,6 +39,11 @@ public override void EmitPushValue(ExpressionContext ctx) { ctx.Proc.PushString("Encountered a bad LValue (compiler bug!)"); ctx.Proc.Throw(); } + + public override void EmitPushInitial(ExpressionContext ctx) { + ctx.Compiler.Emit(WarningCode.BadExpression, Location, "Can't get initial value of a bad LValue (compiler bug!)"); + ctx.Proc.Throw(); + } } // global @@ -51,6 +53,11 @@ public override DMReference EmitReference(ExpressionContext ctx, string endLabel ctx.Compiler.Emit(WarningCode.BadExpression, Location, "attempt to use `global` as a reference"); return DMReference.Invalid; } + + public override void EmitPushInitial(ExpressionContext ctx) { + ctx.Compiler.Emit(WarningCode.BadExpression, Location, "Can't get initial value of `global`"); + ctx.Proc.PushNullAndError(); + } } // src @@ -62,6 +69,11 @@ public override DMReference EmitReference(ExpressionContext ctx, string endLabel return DMReference.Src; } + public override void EmitPushInitial(ExpressionContext ctx) { + ctx.Compiler.Emit(WarningCode.PointlessBuiltinCall, Location, "calling initial() on `src` returns the current value"); + EmitPushValue(ctx); + } + public override string GetNameof(ExpressionContext ctx) => "src"; } @@ -75,6 +87,11 @@ public override DMReference EmitReference(ExpressionContext ctx, string endLabel return DMReference.Usr; } + public override void EmitPushInitial(ExpressionContext ctx) { + ctx.Compiler.Emit(WarningCode.PointlessBuiltinCall, Location, "calling initial() on `usr` returns the current value"); + EmitPushValue(ctx); + } + public override string GetNameof(ExpressionContext ctx) => "usr"; } @@ -85,6 +102,11 @@ public override DMReference EmitReference(ExpressionContext ctx, string endLabel return DMReference.Args; } + public override void EmitPushInitial(ExpressionContext ctx) { + ctx.Compiler.Emit(WarningCode.PointlessBuiltinCall, Location, "calling initial() on `args` returns the current value"); + EmitPushValue(ctx); + } + public override string GetNameof(ExpressionContext ctx) => "args"; } @@ -95,6 +117,12 @@ public override DMReference EmitReference(ExpressionContext ctx, string endLabel return DMReference.Callee; } + public override void EmitPushInitial(ExpressionContext ctx) { + // This happens silently in BYOND + ctx.Compiler.Emit(WarningCode.PointlessBuiltinCall, Location, "calling initial() on constant var `callee` is pointless"); + EmitPushValue(ctx); + } + public override string GetNameof(ExpressionContext ctx) => "callee"; } @@ -105,6 +133,12 @@ public override DMReference EmitReference(ExpressionContext ctx, string endLabel return DMReference.Caller; } + public override void EmitPushInitial(ExpressionContext ctx) { + // This happens silently in BYOND + ctx.Compiler.Emit(WarningCode.PointlessBuiltinCall, Location, "calling initial() on constant var `caller` is pointless"); + EmitPushValue(ctx); + } + public override string GetNameof(ExpressionContext ctx) => "caller"; } @@ -115,6 +149,12 @@ public override DMReference EmitReference(ExpressionContext ctx, string endLabel return DMReference.World; } + public override void EmitPushInitial(ExpressionContext ctx) { + // This happens silently in BYOND + ctx.Compiler.Emit(WarningCode.PointlessBuiltinCall, Location, "calling initial() on constant var `world` is pointless"); + EmitPushValue(ctx); + } + public override string GetNameof(ExpressionContext ctx) => "world"; } @@ -162,6 +202,11 @@ public override void EmitPushInitial(ExpressionContext ctx) { ctx.Proc.PushReferenceValue(DMReference.Src); ctx.Proc.PushString(variable.Name); ctx.Proc.Initial(); + + if (variable.IsConst) { + // This happens silently in BYOND + ctx.Compiler.Emit(WarningCode.PointlessBuiltinCall, Location, "calling initial() on a constant variable is pointless"); + } } public void EmitPushIsSaved(DMProc proc) { @@ -220,5 +265,11 @@ public override void EmitPushValue(ExpressionContext ctx) { ctx.Proc.PushGlobalVars(); } + public override void EmitPushInitial(ExpressionContext ctx) { + // This happens silently in BYOND + ctx.Compiler.Emit(WarningCode.PointlessBuiltinCall, Location, "calling initial() on `global.vars` returns the current value"); + EmitPushValue(ctx); + } + public override string GetNameof(ExpressionContext ctx) => "vars"; } diff --git a/DMCompiler/DM/Expressions/Procs.cs b/DMCompiler/DM/Expressions/Procs.cs index d33663790e..bb96cb6e05 100644 --- a/DMCompiler/DM/Expressions/Procs.cs +++ b/DMCompiler/DM/Expressions/Procs.cs @@ -64,6 +64,11 @@ public override DMReference EmitReference(ExpressionContext ctx, string endLabel ShortCircuitMode shortCircuitMode = ShortCircuitMode.KeepNull) { return DMReference.Self; } + + public override void EmitPushInitial(ExpressionContext ctx) { + ctx.Compiler.Emit(WarningCode.PointlessBuiltinCall, Location, "calling initial() on `.` returns the current value"); + EmitPushValue(ctx); + } } // ..