Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// COMPILE ERROR OD0011
/proc/RunTest()
initial(global)
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

ASSERT(initial(b) == 5)
ASSERT(initial(c) == "e")
ASSERT(initial(args[2]) == 5)

/proc/RunTest()
someargs("3", 5, c = "cc")
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/proc/RunTest()
. = "foo"
ASSERT(initial(.) == "foo")
59 changes: 55 additions & 4 deletions DMCompiler/DM/Expressions/LValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/// <summary>
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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";
}

Expand All @@ -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";
}

Expand All @@ -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";
}

Expand All @@ -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";
}

Expand All @@ -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";
}

Expand All @@ -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";
}

Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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";
}
5 changes: 5 additions & 0 deletions DMCompiler/DM/Expressions/Procs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

// ..
Expand Down
Loading