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

Typemaker 1.1 rebased - fixes and improvements #2208

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
8138046
Fix CallOperation in TypeMaker
out-of-phaze Oct 25, 2024
5304f5b
Normalize relative paths in error source file paths
out-of-phaze Oct 25, 2024
ac7ab0d
Add ValType overrides to various expressions
out-of-phaze Oct 25, 2024
f5d34f4
Infer ValType for local vars from path hints
out-of-phaze Oct 25, 2024
55bf917
Improve CallOperation type inference
out-of-phaze Oct 25, 2024
b87c796
Add inference based on variable typepath
out-of-phaze Oct 25, 2024
4e450f1
Add Typemaker types to file resources
out-of-phaze Oct 25, 2024
87d2c86
Improve DMStandard type hints
out-of-phaze Oct 25, 2024
6dac11a
Further expand DMStandard typehints
out-of-phaze Oct 31, 2024
dd046fd
Expand GetAtomType
out-of-phaze Oct 31, 2024
c15512a
Make var declaration valtype nullable
out-of-phaze Oct 31, 2024
15d1065
Separate instance and path DMValueTypes
out-of-phaze Oct 31, 2024
1ff9eac
Make automatic local valtype inference more permissive
out-of-phaze Oct 31, 2024
633b58d
Make typepath unions use common ancestors
out-of-phaze Oct 31, 2024
7923fd4
Add typed lists to Typemaker
out-of-phaze Oct 31, 2024
a638edf
Improve proc call return value checking
out-of-phaze Oct 31, 2024
3e80ffb
Add ValType override to ScopeReference
out-of-phaze Oct 31, 2024
0224295
Implement params[] typehints
out-of-phaze Oct 31, 2024
9679ed0
Expand return value validation to check more code paths
out-of-phaze Nov 8, 2024
44c18cb
Propagate valtype information from input() to vars
out-of-phaze Nov 8, 2024
8f36d16
Add more expression ValType overrides
out-of-phaze Nov 8, 2024
b87aa85
Improve IndexOperation ValType inference
out-of-phaze Nov 8, 2024
5e19b38
Add type coercion for Message and Color types
out-of-phaze Nov 8, 2024
a22b2fc
Add even more typehints to DMStandard
out-of-phaze Nov 8, 2024
ed07ef9
Fix null reference exception in ProcVarEnd
out-of-phaze Nov 27, 2024
eebc55f
Fix nested list types in Typemaker
out-of-phaze Dec 6, 2024
61e1e90
Add even more typehints to DMStandard
out-of-phaze Feb 23, 2025
a021030
Improve Typemaker return type checking
out-of-phaze Feb 23, 2025
eb945b9
Improve Typemaker return type inference
out-of-phaze Feb 23, 2025
1918f37
Prevent false-positive test fail from DMStandard static typing
out-of-phaze Feb 23, 2025
201b1ec
Readd crash to jointext with invalid argument type
out-of-phaze Feb 23, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@

/proc/RunTest()
return
#pragma ImplicitNullType notice
4 changes: 2 additions & 2 deletions DMCompiler/Compiler/DM/AST/DMAST.ObjectStatements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public sealed class DMASTObjectVarDefinition(
Location location,
DreamPath path,
DMASTExpression value,
DMComplexValueType valType,
DMComplexValueType? valType,
DreamPath? valPath = null) : DMASTStatement(location) {
/// <summary>The path of the object that we are a property of.</summary>
public DreamPath ObjectPath => _varDecl.ObjectPath;
Expand All @@ -80,7 +80,7 @@ public sealed class DMASTObjectVarDefinition(
public bool IsFinal => _varDecl.IsFinal;
public bool IsTmp => _varDecl.IsTmp;

public readonly DMComplexValueType ValType = valType;
public readonly DMComplexValueType? ValType = valType;
}

public sealed class DMASTMultipleObjectVarDefinitions(Location location, DMASTObjectVarDefinition[] varDefinitions)
Expand Down
5 changes: 3 additions & 2 deletions DMCompiler/Compiler/DM/AST/DMAST.ProcStatements.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,14 @@ public sealed class DMASTProcStatementExpression(Location location, DMASTExpress
public DMASTExpression Expression = expression;
}

public sealed class DMASTProcStatementVarDeclaration(Location location, DMASTPath path, DMASTExpression? value, DMComplexValueType valType)
public sealed class DMASTProcStatementVarDeclaration(Location location, DMASTPath path, DMASTExpression? value, DMComplexValueType? valType)
: DMASTProcStatement(location) {
public DMASTExpression? Value = value;

public DreamPath? Type => _varDecl.IsList ? DreamPath.List : _varDecl.TypePath;
public DMComplexValueType? ExplicitValType => valType;

public DMComplexValueType ValType => valType;
public DMComplexValueType ValType => ExplicitValType ?? DMValueType.Anything;

public string Name => _varDecl.VarName;
public bool IsGlobal => _varDecl.IsStatic;
Expand Down
290 changes: 195 additions & 95 deletions DMCompiler/Compiler/DM/DMParser.cs

Large diffs are not rendered by default.

53 changes: 34 additions & 19 deletions DMCompiler/DM/Builders/DMExpressionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ public void Emit(DMASTExpression expression, DreamPath? inferredPath = null) {
expr.EmitPushValue(ctx);
}

public void Emit(DMASTExpression expression, out DMExpression returnedExpr, DreamPath? inferredPath = null) {
returnedExpr = Create(expression, inferredPath);
returnedExpr.EmitPushValue(ctx);
}

public bool TryConstant(DMASTExpression expression, out Constant? constant) {
var expr = Create(expression);
return expr.TryAsConstant(Compiler, out constant);
Expand All @@ -64,7 +69,7 @@ private DMExpression BuildExpression(DMASTExpression expression, DreamPath? infe
case DMASTStringFormat stringFormat: result = BuildStringFormat(stringFormat, inferredPath); break;
case DMASTIdentifier identifier: result = BuildIdentifier(identifier, inferredPath); break;
case DMASTScopeIdentifier globalIdentifier: result = BuildScopeIdentifier(globalIdentifier, inferredPath); break;
case DMASTCallableSelf: result = new ProcSelf(expression.Location, ctx.Proc.ReturnTypes); break;
case DMASTCallableSelf: result = new ProcSelf(expression.Location, ctx.Proc.RawReturnTypes); break;
case DMASTCallableSuper: result = new ProcSuper(expression.Location, ctx.Type.GetProcReturnTypes(ctx.Proc.Name)); break;
case DMASTCallableProcIdentifier procIdentifier: result = BuildCallableProcIdentifier(procIdentifier, ctx.Type); break;
case DMASTProcCall procCall: result = BuildProcCall(procCall, inferredPath); break;
Expand Down Expand Up @@ -272,10 +277,10 @@ private DMExpression BuildExpression(DMASTExpression expression, DreamPath? infe

if (b.ValType.TypePath != null && c.ValType.TypePath != null && b.ValType.TypePath != c.ValType.TypePath) {
Compiler.Emit(WarningCode.LostTypeInfo, ternary.Location,
$"Ternary has type paths {b.ValType.TypePath} and {c.ValType.TypePath} but a value can only have one type path. Using {b.ValType.TypePath}.");
$"Ternary has type paths {b.ValType.TypePath} and {c.ValType.TypePath} but a value can only have one type path. Using their common ancestor, {b.ValType.TypePath.Value.GetLastCommonAncestor(Compiler, c.ValType.TypePath.Value)}.");
}

result = new Ternary(ternary.Location, a, b, c);
result = new Ternary(Compiler, ternary.Location, a, b, c);
break;
case DMASTNewPath newPath:
if (BuildExpression(newPath.Path, inferredPath) is not IConstantPath path) {
Expand All @@ -284,11 +289,11 @@ private DMExpression BuildExpression(DMASTExpression expression, DreamPath? infe
break;
}

result = new NewPath(Compiler, newPath.Location, path,
result = new NewPath(newPath.Location, path,
BuildArgumentList(newPath.Location, newPath.Parameters, inferredPath));
break;
case DMASTNewExpr newExpr:
result = new New(Compiler, newExpr.Location,
result = new New(newExpr.Location,
BuildExpression(newExpr.Expression, inferredPath),
BuildArgumentList(newExpr.Location, newExpr.Parameters, inferredPath));
break;
Expand All @@ -305,7 +310,7 @@ private DMExpression BuildExpression(DMASTExpression expression, DreamPath? infe
break;
}

result = new NewPath(Compiler, newInferred.Location, inferredType,
result = new NewPath(newInferred.Location, inferredType,
BuildArgumentList(newInferred.Location, newInferred.Parameters, inferredPath));
break;
case DMASTPreIncrement preIncrement:
Expand Down Expand Up @@ -581,7 +586,7 @@ private DMExpression BuildIdentifier(DMASTIdentifier identifier, DreamPath? infe
if (scopeMode == Normal) {
var localVar = ctx.Proc?.GetLocalVariable(name);
if (localVar != null)
return new Local(identifier.Location, localVar);
return new Local(identifier.Location, localVar, localVar.ExplicitValueType);
}

var field = ctx.Type.GetVariable(name);
Expand Down Expand Up @@ -615,7 +620,7 @@ private DMExpression BuildScopeIdentifier(DMASTScopeIdentifier scopeIdentifier,
return UnknownReference(location, $"No global proc named \"{bIdentifier}\" exists");

var arguments = BuildArgumentList(location, scopeIdentifier.CallArguments, inferredPath);
return new ProcCall(location, new GlobalProc(location, globalProc), arguments, DMValueType.Anything);
return new ProcCall(Compiler, location, new GlobalProc(location, globalProc), arguments, DMValueType.Anything);
}

// ::vars, special case
Expand Down Expand Up @@ -701,7 +706,7 @@ private DMExpression BuildScopeIdentifier(DMASTScopeIdentifier scopeIdentifier,
if (variable == null)
return UnknownIdentifier(location, bIdentifier);

return new ScopeReference(ObjectTree, location, expression, bIdentifier, variable);
return new ScopeReference(Compiler, location, expression, bIdentifier, variable);
}
}

Expand All @@ -715,7 +720,7 @@ private DMExpression BuildCallableProcIdentifier(DMASTCallableProcIdentifier pro
}

if (dmObject.HasProc(procIdentifier.Identifier)) {
return new Proc(procIdentifier.Location, procIdentifier.Identifier);
return new Proc(procIdentifier.Location, procIdentifier.Identifier, dmObject);
}

if (ObjectTree.TryGetGlobalProc(procIdentifier.Identifier, out var globalProc)) {
Expand Down Expand Up @@ -752,10 +757,10 @@ private DMExpression BuildProcCall(DMASTProcCall procCall, DreamPath? inferredPa
if (target is Proc targetProc) { // GlobalProc handles returnType itself
var returnType = targetProc.GetReturnType(ctx.Type);

return new ProcCall(procCall.Location, target, args, returnType);
return new ProcCall(Compiler, procCall.Location, target, args, returnType);
}

return new ProcCall(procCall.Location, target, args, DMValueType.Anything);
return new ProcCall(Compiler, procCall.Location, target, args, DMValueType.Anything);
}

private ArgumentList BuildArgumentList(Location location, DMASTCallParameter[]? arguments, DreamPath? inferredPath = null) {
Expand Down Expand Up @@ -885,7 +890,7 @@ private DMExpression BuildDereference(DMASTDereference deref, DreamPath? inferre
var argumentList = BuildArgumentList(deref.Expression.Location, callOperation.Parameters, inferredPath);

var globalProcExpr = new GlobalProc(expr.Location, globalProc);
expr = new ProcCall(expr.Location, globalProcExpr, argumentList, DMValueType.Anything);
expr = new ProcCall(Compiler, expr.Location, globalProcExpr, argumentList, DMValueType.Anything);
break;

case DMASTDereference.FieldOperation:
Expand Down Expand Up @@ -1021,6 +1026,7 @@ private DMExpression BuildDereference(DMASTDereference deref, DreamPath? inferre
case DMASTDereference.CallOperation callOperation: {
var field = callOperation.Identifier;
var argumentList = BuildArgumentList(deref.Expression.Location, callOperation.Parameters, inferredPath);
DreamPath? nextPath = null;

if (!callOperation.NoSearch && !pathIsFuzzy) {
if (prevPath == null) {
Expand All @@ -1031,16 +1037,25 @@ private DMExpression BuildDereference(DMASTDereference deref, DreamPath? inferre
return UnknownReference(callOperation.Location, $"Type {prevPath.Value} does not exist");
if (!fromObject.HasProc(field))
return UnknownIdentifier(callOperation.Location, field);

var returnTypes = fromObject.GetProcReturnTypes(field, argumentList) ?? DMValueType.Anything;
nextPath = returnTypes.HasPath ? returnTypes.TypePath : returnTypes.AsPath();
if (!returnTypes.HasPath & nextPath.HasValue) {
var thePath = nextPath!.Value;
thePath.Type = DreamPath.PathType.UpwardSearch;
nextPath = thePath;
}
}

operation = new Dereference.CallOperation {
Parameters = argumentList,
Safe = callOperation.Safe,
Identifier = field,
Path = null
Path = prevPath
};
prevPath = null;
pathIsFuzzy = true;
prevPath = nextPath;
if(prevPath is null)
pathIsFuzzy = true;
break;
}

Expand All @@ -1062,7 +1077,7 @@ private DMExpression BuildLocate(DMASTLocate locate, DreamPath? inferredPath) {
if (inferredPath == null)
return BadExpression(WarningCode.BadExpression, locate.Location, "inferred locate requires a type");

return new LocateInferred(locate.Location, inferredPath.Value, container);
return new LocateInferred(Compiler, locate.Location, inferredPath.Value, container);
}

var pathExpr = BuildExpression(locate.Expression, inferredPath);
Expand Down Expand Up @@ -1103,7 +1118,7 @@ private DMExpression BuildList(DMASTList list, DreamPath? inferredPath) {
}
}

return new List(list.Location, values);
return new List(Compiler, list.Location, values);
}

private DMExpression BuildDimensionalList(DMASTDimensionalList list, DreamPath? inferredPath) {
Expand Down Expand Up @@ -1209,7 +1224,7 @@ private DMExpression BuildPick(DMASTPick pick, DreamPath? inferredPath) {
pickValues[i] = new Pick.PickValue(weight, value);
}

return new Pick(pick.Location, pickValues);
return new Pick(Compiler, pick.Location, pickValues);
}

private DMExpression BuildLog(DMASTLog log, DreamPath? inferredPath) {
Expand Down
Loading
Loading