public void ProcessVarDefinition(DMASTObjectVarDefinition varDefinition)
        {
            DMObject   oldObject = _currentObject;
            DMVariable variable;

            _currentObject = DMObjectTree.GetDMObject(varDefinition.ObjectPath);

            if (varDefinition.IsGlobal)
            {
                variable = _currentObject.CreateGlobalVariable(varDefinition.Type, varDefinition.Name, varDefinition.IsConst);
            }
            else
            {
                variable = new DMVariable(varDefinition.Type, varDefinition.Name, false, varDefinition.IsConst);
                _currentObject.Variables[variable.Name] = variable;
            }

            try {
                SetVariableValue(variable, varDefinition.Value, varDefinition.ValType);
            } catch (CompileErrorException e) {
                DMCompiler.Error(e.Error);
            }

            _currentObject = oldObject;
        }
Exemple #2
0
        public void ProcessVarOverride(DMASTObjectVarOverride varOverride)
        {
            DMObject oldObject = _currentObject;

            _currentObject = DMObjectTree.GetDMObject(varOverride.ObjectPath);

            try {
                if (varOverride.VarName == "parent_type")
                {
                    DMASTConstantPath parentType = varOverride.Value as DMASTConstantPath;

                    if (parentType == null)
                    {
                        throw new CompileErrorException(varOverride.Location, "Expected a constant path");
                    }
                    _currentObject.Parent = DMObjectTree.GetDMObject(parentType.Value.Path);
                }
                else
                {
                    DMVariable variable = new DMVariable(null, varOverride.VarName, false, false);

                    SetVariableValue(variable, varOverride.Value);
                    _currentObject.VariableOverrides[variable.Name] = variable;
                }
            } catch (CompileErrorException e) {
                DMCompiler.Error(e.Error);
            }

            _currentObject = oldObject;
        }
Exemple #3
0
        public DereferenceProc(Location location, DMExpression expr, DMASTDereferenceProc astNode) : base(location)
        {
            _expr        = expr;
            _conditional = astNode.Conditional;
            _field       = astNode.Property;

            if (astNode.Type == DMASTDereference.DereferenceType.Direct)
            {
                if (Dereference.DirectConvertable(expr, astNode))
                {
                    astNode.Type = DMASTDereference.DereferenceType.Search;
                    return;
                }
                else if (expr.Path == null)
                {
                    throw new CompileErrorException(astNode.Location, $"Invalid property \"{_field}\"");
                }

                DMObject dmObject = DMObjectTree.GetDMObject(_expr.Path.Value, false);
                if (dmObject == null)
                {
                    throw new CompileErrorException(Location, $"Type {expr.Path.Value} does not exist");
                }
                if (!dmObject.HasProc(_field))
                {
                    throw new CompileErrorException(Location, $"Type {_expr.Path.Value} does not have a proc named \"{_field}\"");
                }
            }
        }
Exemple #4
0
        public (DMObject ProcOwner, DMProc Proc) GetProc()
        {
            if (_expr.Path == null)
            {
                return(null, null);
            }

            DMObject dmObject = DMObjectTree.GetDMObject(_expr.Path.Value);
            var      procId   = dmObject.GetProcs(_field)?[^ 1];
        public void ProcessObjectDefinition(DMASTObjectDefinition objectDefinition)
        {
            DMObject oldObject = _currentObject;

            DMCompiler.VerbosePrint($"Generating {objectDefinition.Path}");
            _currentObject = DMObjectTree.GetDMObject(objectDefinition.Path);
            if (objectDefinition.InnerBlock != null)
            {
                ProcessBlockInner(objectDefinition.InnerBlock);
            }
            _currentObject = oldObject;
        }
Exemple #6
0
        public override bool TryAsConstant(out Constant constant)
        {
            if (_expr.Path is not null)
            {
                var obj      = DMObjectTree.GetDMObject(_expr.Path.GetValueOrDefault());
                var variable = obj.GetVariable(PropertyName);
                if (variable.IsConst)
                {
                    return(variable.Value.TryAsConstant(out constant));
                }
            }

            constant = null;
            return(false);
        }
Exemple #7
0
        public void ProcessStatementForList(DMASTProcStatementForList statementForList)
        {
            DMExpression.Emit(_dmObject, _proc, statementForList.List);
            _proc.CreateListEnumerator();
            _proc.StartScope();
            {
                if (statementForList.Initializer != null)
                {
                    ProcessStatement(statementForList.Initializer);
                }

                string loopLabel = _proc.NewLabelName();
                _proc.LoopStart(loopLabel);
                {
                    DMExpression outputVariable = DMExpression.Create(_dmObject, _proc, statementForList.Variable);
                    (DMReference outputRef, _) = outputVariable.EmitReference(_dmObject, _proc);
                    _proc.Enumerate(outputRef);
                    _proc.BreakIfFalse();

                    DMASTProcStatementVarDeclaration varDeclaration = statementForList.Initializer as DMASTProcStatementVarDeclaration;
                    if (varDeclaration != null && varDeclaration.Type != null)
                    {
                        //This is terrible but temporary
                        //TODO: See https://github.com/wixoaGit/OpenDream/issues/50
                        var obj = DMObjectTree.GetDMObject(varDeclaration.Type.Value);
                        if (statementForList.List is DMASTIdentifier list && list.Identifier == "world" && !obj.IsSubtypeOf(DreamPath.Atom))
                        {
                            var warn = new CompilerWarning(statementForList.Location, "Cannot currently loop 'in world' for non-ATOM types");
                            DMCompiler.Warning(warn);
                        }
                        DMExpression.Emit(_dmObject, _proc, statementForList.Variable);
                        _proc.PushPath(varDeclaration.Type.Value);
                        _proc.IsType();

                        _proc.ContinueIfFalse();
                    }

                    ProcessBlockInner(statementForList.Body);

                    _proc.LoopContinue(loopLabel);
                    _proc.LoopJumpToStart(loopLabel);
                }
                _proc.LoopEnd();
            }
            _proc.EndScope();
            _proc.DestroyEnumerator();
        }
Exemple #8
0
        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.Settings.SuppressUnimplementedWarnings)
                {
                    DMCompiler.Warning(new CompilerWarning(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 #9
0
        public void BuildObjectTree(DMASTFile astFile)
        {
            DMObjectTree.Reset();
            ProcessFile(astFile);

            foreach (DMObject dmObject in DMObjectTree.AllObjects)
            {
                dmObject.CompileProcs();
            }

            DMObject root = DMObjectTree.GetDMObject(DreamPath.Root);

            foreach (DMProc gProc in DMObjectTree.GlobalProcs.Values)
            {
                gProc.Compile(root);
            }

            DMObjectTree.CreateGlobalInitProc();
        }
        public void ProcessVarOverride(DMASTObjectVarOverride varOverride)
        {
            DMObject oldObject = _currentObject;

            _currentObject = DMObjectTree.GetDMObject(varOverride.ObjectPath);

            try
            {
                switch (varOverride.VarName)
                {
                case "parent_type":
                {
                    DMASTConstantPath parentType = varOverride.Value as DMASTConstantPath;

                    if (parentType == null)
                    {
                        throw new CompileErrorException(varOverride.Location, "Expected a constant path");
                    }
                    _currentObject.Parent = DMObjectTree.GetDMObject(parentType.Value.Path);
                    break;
                }

                case "tag":
                    DMCompiler.Error(new CompilerError(varOverride.Location, "tag: may not be set at compile-time"));
                    break;

                default:
                {
                    DMVariable variable = new DMVariable(null, varOverride.VarName, false, false);

                    SetVariableValue(variable, varOverride.Value);
                    _currentObject.VariableOverrides[variable.Name] = variable;
                    break;
                }
                }
            } catch (CompileErrorException e) {
                DMCompiler.Error(e.Error);
            }

            _currentObject = oldObject;
        }
        public void ProcessFile(DMASTFile file)
        {
            _currentObject = DMObjectTree.GetDMObject(DreamPath.Root);

            ProcessBlockInner(file.BlockInner);
        }
        public void ProcessProcDefinition(DMASTProcDefinition procDefinition)
        {
            string   procName = procDefinition.Name;
            DMObject dmObject = _currentObject;

            try {
                if (procDefinition.ObjectPath.HasValue)
                {
                    dmObject = DMObjectTree.GetDMObject(_currentObject.Path.Combine(procDefinition.ObjectPath.Value));
                }

                if (!procDefinition.IsOverride && dmObject.HasProc(procName))
                {
                    throw new CompileErrorException(procDefinition.Location, $"Type {dmObject.Path} already has a proc named \"{procName}\"");
                }

                DMProc proc;

                if (procDefinition.ObjectPath == null)
                {
                    if (DMObjectTree.TryGetGlobalProc(procDefinition.Name, out _))
                    {
                        throw new CompileErrorException(new CompilerError(procDefinition.Location, $"proc {procDefinition.Name} is already defined in global scope"));
                    }

                    proc = DMObjectTree.CreateDMProc(dmObject, procDefinition);
                    DMObjectTree.AddGlobalProc(proc.Name, proc.Id);
                }
                else
                {
                    proc = DMObjectTree.CreateDMProc(dmObject, procDefinition);
                    dmObject.AddProc(procName, proc);
                }

                if (procDefinition.Body != null)
                {
                    foreach (var stmt in GetStatements(procDefinition.Body))
                    {
                        // TODO multiple var definitions.
                        if (stmt is DMASTProcStatementVarDeclaration varDeclaration && varDeclaration.IsGlobal)
                        {
                            DMVariable variable = proc.CreateGlobalVariable(varDeclaration.Type, varDeclaration.Name, varDeclaration.IsConst);
                            variable.Value = new Expressions.Null(varDeclaration.Location);

                            if (varDeclaration.Value != null)
                            {
                                DMVisitorExpression._scopeMode = "static";
                                DMExpression expression = DMExpression.Create(dmObject, proc, varDeclaration.Value, varDeclaration.Type);
                                DMVisitorExpression._scopeMode = "normal";
                                DMObjectTree.AddGlobalInitAssign(dmObject, proc.GetGlobalVariableId(varDeclaration.Name).Value, expression);
                            }
                        }
                    }
                }

                if (procDefinition.IsVerb && (dmObject.IsSubtypeOf(DreamPath.Atom) || dmObject.IsSubtypeOf(DreamPath.Client)) && !DMCompiler.Settings.NoStandard)
                {
                    Expressions.Field  field    = new Expressions.Field(Location.Unknown, dmObject.GetVariable("verbs"));
                    DreamPath          procPath = new DreamPath(".proc/" + procName);
                    Expressions.Append append   = new Expressions.Append(Location.Unknown, field, new Expressions.Path(Location.Unknown, procPath));

                    dmObject.InitializationProcExpressions.Add(append);
                }
            } catch (CompileErrorException e) {
                DMCompiler.Error(e.Error);
            }
        }