public void VisitDereference(DMASTDereference dereference)
        {
            var expr = DMExpression.Create(_dmObject, _proc, dereference.Expression, _inferredPath);

            if (dereference.Type == DMASTDereference.DereferenceType.Direct && !Dereference.DirectConvertable(expr, dereference))
            {
                if (expr.Path == null)
                {
                    throw new CompileErrorException(dereference.Location, $"Invalid property \"{dereference.Property}\"");
                }

                DMObject dmObject = DMObjectTree.GetDMObject(expr.Path.Value, false);
                if (dmObject == null)
                {
                    throw new CompileErrorException(dereference.Location, $"Type {expr.Path.Value} does not exist");
                }

                var property = dmObject.GetVariable(dereference.Property);
                if (property != null)
                {
                    Result = new Expressions.Dereference(dereference.Location, property.Type, expr, dereference.Conditional, dereference.Property);
                }
                else
                {
                    var globalId = dmObject.GetGlobalVariableId(dereference.Property);
                    if (globalId != null)
                    {
                        property = DMObjectTree.Globals[globalId.Value];
                        Result   = new Expressions.GlobalField(dereference.Location, property.Type, globalId.Value);
                    }
                }

                if (property == null)
                {
                    throw new CompileErrorException(dereference.Location, $"Invalid property \"{dereference.Property}\" on type {dmObject.Path}");
                }

                if ((property.Value?.ValType & DMValueType.Unimplemented) == DMValueType.Unimplemented)
                {
                    DMCompiler.UnimplementedWarning(dereference.Location, $"{dmObject.Path}.{dereference.Property} is not implemented and will have unexpected behavior");
                }
            }
            else
            {
                Result = new Expressions.Dereference(dereference.Location, null, expr, dereference.Conditional, dereference.Property);
            }
        }
Exemple #2
0
        public void ProcessStatementSet(DMASTProcStatementSet statementSet)
        {
            var attribute = statementSet.Attribute.ToLower();

            // TODO deal with "src"
            if (!DMExpression.TryConstant(_dmObject, _proc, statementSet.Value, out var constant) && attribute != "src")
            {
                throw new CompileErrorException(statementSet.Location, $"{attribute} attribute should be a constant");
            }

            switch (statementSet.Attribute.ToLower())
            {
            case "waitfor": {
                _proc.WaitFor(constant.IsTruthy());
                break;
            }

            case "opendream_unimplemented": {
                if (constant.IsTruthy())
                {
                    _proc.Attributes |= ProcAttributes.Unimplemented;
                }
                else
                {
                    _proc.Attributes &= ~ProcAttributes.Unimplemented;
                }
                break;
            }

            case "hidden":
                if (constant.IsTruthy())
                {
                    _proc.Attributes |= ProcAttributes.Hidden;
                }
                else
                {
                    _proc.Attributes &= ~ProcAttributes.Hidden;
                }
                break;

            case "popup_menu":
                if (constant.IsTruthy())     // The default is to show it so we flag it if it's hidden
                {
                    _proc.Attributes &= ~ProcAttributes.HidePopupMenu;
                }
                else
                {
                    _proc.Attributes |= ProcAttributes.HidePopupMenu;
                }

                DMCompiler.UnimplementedWarning(statementSet.Location, "set popup_menu is not implemented");
                break;

            case "instant":
                if (constant.IsTruthy())
                {
                    _proc.Attributes |= ProcAttributes.Instant;
                }
                else
                {
                    _proc.Attributes &= ~ProcAttributes.Instant;
                }

                DMCompiler.UnimplementedWarning(statementSet.Location, "set instant is not implemented");
                break;

            case "background":
                if (constant.IsTruthy())
                {
                    _proc.Attributes |= ProcAttributes.Background;
                }
                else
                {
                    _proc.Attributes &= ~ProcAttributes.Background;
                }
                break;

            case "name":
                if (constant is not Expressions.String nameStr)
                {
                    throw new CompileErrorException(statementSet.Location, "name attribute must be a string");
                }

                _proc.VerbName = nameStr.Value;
                break;

            case "category":
                _proc.VerbCategory = constant switch {
                    Expressions.String str => str.Value,
                                       Expressions.Null => null,
                                       _ => throw new CompileErrorException(statementSet.Location, "category attribute must be a string or null")
                };

                break;

            case "desc":
                if (constant is not Expressions.String descStr)
                {
                    throw new CompileErrorException(statementSet.Location, "desc attribute must be a string");
                }

                _proc.VerbDesc = descStr.Value;
                DMCompiler.UnimplementedWarning(statementSet.Location, "set desc is not implemented");
                break;

            case "invisibility":
                // The ref says 0-101 for atoms and 0-100 for verbs
                // BYOND doesn't clamp the actual var value but it does seem to treat out-of-range values as their extreme
                if (constant is not Expressions.Number invisNum)
                {
                    throw new CompileErrorException(statementSet.Location, "invisibility attribute must be an int");
                }

                _proc.Invisibility = Convert.ToSByte(Math.Clamp(Math.Floor(invisNum.Value), 0, 100));
                DMCompiler.UnimplementedWarning(statementSet.Location, "set invisibility is not implemented");
                break;

            case "src":
                DMCompiler.UnimplementedWarning(statementSet.Location, "set src is not implemented");
                break;
            }
        }
Exemple #3
0
 public override bool TryAsJsonRepresentation(out object json)
 {
     json = null;
     DMCompiler.UnimplementedWarning(Location, "DMM overrides for newlist() are not implemented");
     return(true); //TODO
 }