Exemple #1
0
        public void ProcessStatementSet(DMASTProcStatementSet statementSet)
        {
            //TODO: Proc attributes
            switch (statementSet.Attribute.ToLower())
            {
            case "waitfor": {
                if (!DMExpression.TryConstant(_dmObject, _proc, statementSet.Value, out var constant))
                {
                    throw new CompileErrorException(statementSet.Location, $"waitfor attribute should be a constant");
                }

                _proc.WaitFor(constant.IsTruthy());
                break;
            }

            case "opendream_unimplemented": {
                if (!DMExpression.TryConstant(_dmObject, _proc, statementSet.Value, out var constant))
                {
                    throw new CompileErrorException(statementSet.Location, $"opendream_unimplemented attribute should be a constant");
                }

                _proc.Unimplemented = constant.IsTruthy();
                break;
            }
            }
        }
Exemple #2
0
        public void VisitUpwardPathSearch(DMASTUpwardPathSearch constant)
        {
            DMExpression.TryConstant(_dmObject, _proc, constant.Path, out var pathExpr);
            if (pathExpr is not Expressions.Path)
            {
                throw new CompileErrorException(constant.Location, "Cannot do an upward path search on " + pathExpr);
            }

            DreamPath path      = ((Expressions.Path)pathExpr).Value;
            DreamPath?foundPath = DMObjectTree.UpwardSearch(path, constant.Search.Path);

            if (foundPath == null)
            {
                throw new CompileErrorException(constant.Location, $"Invalid path {path}.{constant.Search.Path}");
            }

            Result = new Expressions.Path(constant.Location, foundPath.Value);
        }
Exemple #3
0
        public void ProcessStatementSwitch(DMASTProcStatementSwitch statementSwitch)
        {
            string endLabel = _proc.NewLabelName();
            List <(string CaseLabel, DMASTProcBlockInner CaseBody)> valueCases = new();
            DMASTProcBlockInner defaultCaseBody = null;

            DMExpression.Emit(_dmObject, _proc, statementSwitch.Value);
            foreach (DMASTProcStatementSwitch.SwitchCase switchCase in statementSwitch.Cases)
            {
                if (switchCase is DMASTProcStatementSwitch.SwitchCaseValues switchCaseValues)
                {
                    string caseLabel = _proc.NewLabelName();

                    foreach (DMASTExpression value in switchCaseValues.Values)
                    {
                        if (value is DMASTSwitchCaseRange range)
                        {
                            if (!DMExpression.TryConstant(_dmObject, _proc, range.RangeStart, out var lower))
                            {
                                throw new CompileErrorException(new CompilerError(range.RangeStart.Location, "Expected a constant"));
                            }
                            if (!DMExpression.TryConstant(_dmObject, _proc, range.RangeEnd, out var upper))
                            {
                                throw new CompileErrorException(new CompilerError(range.RangeEnd.Location, "Expected a constant"));
                            }

                            lower.EmitPushValue(_dmObject, _proc);
                            upper.EmitPushValue(_dmObject, _proc);
                            _proc.SwitchCaseRange(caseLabel);
                        }
                        else
                        {
                            if (!DMExpression.TryConstant(_dmObject, _proc, value, out var constant))
                            {
                                throw new CompileErrorException(new CompilerError(value.Location, "Expected a constant"));
                            }

                            constant.EmitPushValue(_dmObject, _proc);
                            _proc.SwitchCase(caseLabel);
                        }
                    }

                    valueCases.Add((caseLabel, switchCase.Body));
                }
                else
                {
                    defaultCaseBody = ((DMASTProcStatementSwitch.SwitchCaseDefault)switchCase).Body;
                }
            }
            _proc.Pop();

            if (defaultCaseBody != null)
            {
                _proc.StartScope();
                {
                    ProcessBlockInner(defaultCaseBody);
                }
                _proc.EndScope();
            }
            _proc.Jump(endLabel);

            foreach ((string CaseLabel, DMASTProcBlockInner CaseBody)valueCase in valueCases)
            {
                _proc.AddLabel(valueCase.CaseLabel);
                _proc.StartScope();
                {
                    ProcessBlockInner(valueCase.CaseBody);
                }
                _proc.EndScope();
                _proc.Jump(endLabel);
            }

            _proc.AddLabel(endLabel);
        }
Exemple #4
0
        public void ProcessStatementSet(DMASTProcStatementSet statementSet)
        {
            var attribute = statementSet.Attribute.ToLower();

            if (!DMExpression.TryConstant(_dmObject, _proc, statementSet.Value, out var constant))
            {
                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;
                }

                if (!DMCompiler.Settings.SuppressUnimplementedWarnings)
                {
                    DMCompiler.Warning(new CompilerWarning(statementSet.Location, "set hidden is not implemented"));
                }

                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;
                }

                if (!DMCompiler.Settings.SuppressUnimplementedWarnings)
                {
                    DMCompiler.Warning(new CompilerWarning(statementSet.Location, "set popup_menu is not implemented"));
                }

                break;

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

                if (!DMCompiler.Settings.SuppressUnimplementedWarnings)
                {
                    DMCompiler.Warning(new CompilerWarning(statementSet.Location, "set instant is not implemented"));
                }
                break;

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

                if (!DMCompiler.Settings.SuppressUnimplementedWarnings)
                {
                    DMCompiler.Warning(new CompilerWarning(statementSet.Location, "set background is not implemented"));
                }
                break;

            case "name":
                DMASTConstantString name = statementSet.Value as DMASTConstantString;
                if (name is null)
                {
                    throw new CompileErrorException(statementSet.Location, "bad text");
                }
                _proc.VerbName = name.Value;

                if (!DMCompiler.Settings.SuppressUnimplementedWarnings)
                {
                    DMCompiler.Warning(new CompilerWarning(statementSet.Location, "set name is not implemented"));
                }

                break;

            case "category":
                DMASTConstantString category = statementSet.Value as DMASTConstantString;
                if (category is null)
                {
                    throw new CompileErrorException(statementSet.Location, "bad text");
                }
                _proc.VerbCategory = category.Value;

                if (!DMCompiler.Settings.SuppressUnimplementedWarnings)
                {
                    DMCompiler.Warning(new CompilerWarning(statementSet.Location, "set category is not implemented"));
                }
                break;

            case "desc":
                DMASTConstantString desc = statementSet.Value as DMASTConstantString;
                if (desc is null)
                {
                    throw new CompileErrorException(statementSet.Location, "bad text");
                }
                _proc.VerbDesc = desc.Value;

                if (!DMCompiler.Settings.SuppressUnimplementedWarnings)
                {
                    DMCompiler.Warning(new CompilerWarning(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
                DMASTConstantFloat invisFloat = statementSet.Value as DMASTConstantFloat;
                if (invisFloat is null)
                {
                    DMASTConstantInteger invisInt = statementSet.Value as DMASTConstantInteger;
                    if (invisInt is null)
                    {
                        throw new CompileErrorException(statementSet.Location, "bad num");
                    }
                    _proc.Invisibility = Convert.ToSByte(Math.Clamp(invisInt.Value, 0, 100));
                }
                else
                {
                    _proc.Invisibility = Convert.ToSByte(Math.Clamp(Math.Floor(invisFloat.Value), 0, 100));
                }

                if (!DMCompiler.Settings.SuppressUnimplementedWarnings)
                {
                    DMCompiler.Warning(new CompilerWarning(statementSet.Location, "set invisibility is not implemented"));
                }
                break;

            case "src":
                if (!DMCompiler.Settings.SuppressUnimplementedWarnings)
                {
                    DMCompiler.Warning(new CompilerWarning(statementSet.Location, "set src is not implemented"));
                }
                break;
            }
        }
Exemple #5
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;
            }
        }