コード例 #1
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;
        }
コード例 #2
0
        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;
        }
コード例 #3
0
        public void ProcessStatementTryCatch(DMASTProcStatementTryCatch tryCatch)
        {
            string catchLabel = _proc.NewLabelName();
            string endLabel   = _proc.NewLabelName();

            _proc.StartScope();
            ProcessBlockInner(tryCatch.TryBody);
            _proc.EndScope();
            _proc.Jump(endLabel);

            if (tryCatch.CatchParameter != null)
            {
                //TODO set the value to what is thrown in try
                var param = tryCatch.CatchParameter as DMASTProcStatementVarDeclaration;
                if (!_proc.TryAddLocalVariable(param.Name, param.Type))
                {
                    DMCompiler.Error(new CompilerError(param.Location, $"Duplicate var {param.Name}"));
                }
            }

            //TODO make catching actually work
            _proc.AddLabel(catchLabel);
            if (tryCatch.CatchBody != null)
            {
                _proc.StartScope();
                ProcessBlockInner(tryCatch.CatchBody);
                _proc.EndScope();
            }
            _proc.AddLabel(endLabel);
        }
コード例 #4
0
 public void ProcessBlockInner(DMASTBlockInner blockInner)
 {
     foreach (DMASTStatement statement in blockInner.Statements)
     {
         try {
             ProcessStatement(statement);
         } catch (CompileErrorException e) {
             DMCompiler.Error(e.Error);
         }
     }
 }
コード例 #5
0
ファイル: DMProcBuilder.cs プロジェクト: ZeWaka/OpenDream
 public void ProcessBlockInner(DMASTProcBlockInner block)
 {
     foreach (DMASTProcStatement statement in block.Statements)
     {
         try {
             ProcessStatement(statement);
         } catch (CompileErrorException e) { //Retreat from the statement when there's an error
             DMCompiler.Error(e.Error);
         }
     }
 }
コード例 #6
0
        public void ProcessStatementVarDeclaration(DMASTProcStatementVarDeclaration varDeclaration)
        {
            if (varDeclaration.IsGlobal)
            {
                return;
            }                                        //Currently handled by DMObjectBuilder

            DMExpression value;

            if (varDeclaration.Value != null)
            {
                try {
                    value = DMExpression.Create(_dmObject, _proc, varDeclaration.Value, varDeclaration.Type);
                } catch (CompileErrorException e) {
                    DMCompiler.Error(e.Error);
                    value = new Expressions.Null(varDeclaration.Location);
                }
            }
            else
            {
                value = new Expressions.Null(varDeclaration.Location);
            }

            bool successful;

            if (varDeclaration.IsConst)
            {
                if (!value.TryAsConstant(out var constValue))
                {
                    DMCompiler.Error(new CompilerError(varDeclaration.Location, "Const var must be set to a constant"));
                    return;
                }

                successful = _proc.TryAddLocalConstVariable(varDeclaration.Name, varDeclaration.Type, constValue);
            }
            else
            {
                successful = _proc.TryAddLocalVariable(varDeclaration.Name, varDeclaration.Type);
            }

            if (!successful)
            {
                DMCompiler.Error(new CompilerError(varDeclaration.Location, $"Duplicate var {varDeclaration.Name}"));
                return;
            }

            value.EmitPushValue(_dmObject, _proc);
            _proc.Assign(_proc.GetLocalVariableReference(varDeclaration.Name));
            _proc.Pop();
        }
コード例 #7
0
 public void ProcessBlockInner(DMASTProcBlockInner block)
 {
     // TODO ProcessStatementSet() needs to be before any loops but this is nasty
     foreach (var stmt in block.Statements)
     {
         if (stmt is DMASTProcStatementSet set)
         {
             try
             {
                 ProcessStatementSet(set);
             }
             catch (CompileAbortException e)
             {
                 // The statement's location info isn't passed all the way down so change the error to make it more accurate
                 e.Error.Location = set.Location;
                 DMCompiler.Error(e.Error);
                 return;                       // Don't spam the error that will continue to exist
             }
             catch (CompileErrorException e) { //Retreat from the statement when there's an error
                 DMCompiler.Error(e.Error);
             }
         }
     }
     foreach (DMASTProcStatement statement in block.Statements)
     {
         try
         {
             // see above
             if (statement is DMASTProcStatementSet)
             {
                 continue;
             }
             ProcessStatement(statement);
         }
         catch (CompileAbortException e)
         {
             // The statement's location info isn't passed all the way down so change the error to make it more accurate
             e.Error.Location = statement.Location;
             DMCompiler.Error(e.Error);
             return;                       // Don't spam the error that will continue to exist
         }
         catch (CompileErrorException e) { //Retreat from the statement when there's an error
             DMCompiler.Error(e.Error);
         }
     }
 }
コード例 #8
0
        public void ProcessProcDefinition(DMASTProcDefinition procDefinition)
        {
            if (procDefinition.Body == null)
            {
                return;
            }

            foreach (DMASTDefinitionParameter parameter in procDefinition.Parameters)
            {
                string parameterName = parameter.Name;

                if (!_proc.TryAddLocalVariable(parameterName, parameter.ObjectType))
                {
                    DMCompiler.Error(new CompilerError(procDefinition.Location, $"Duplicate argument \"{parameterName}\" on {procDefinition.ObjectPath}/proc/{procDefinition.Name}()"));
                    continue;
                }

                if (parameter.Value != null)   //Parameter has a default value
                {
                    string      afterDefaultValueCheck = _proc.NewLabelName();
                    DMReference parameterRef           = _proc.GetLocalVariableReference(parameterName);

                    //Don't set parameter to default if not null
                    _proc.PushReferenceValue(parameterRef);
                    _proc.IsNull();
                    _proc.JumpIfFalse(afterDefaultValueCheck);

                    //Set default
                    try {
                        DMExpression.Emit(_dmObject, _proc, parameter.Value, parameter.ObjectType);
                    } catch (CompileErrorException e) {
                        DMCompiler.Error(e.Error);
                    }
                    _proc.Assign(parameterRef);
                    _proc.Pop();

                    _proc.AddLabel(afterDefaultValueCheck);
                }
            }

            ProcessBlockInner(procDefinition.Body);
            _proc.ResolveLabels();
        }
コード例 #9
0
 public void ProcessBlockInner(DMASTProcBlockInner block)
 {
     foreach (DMASTProcStatement statement in block.Statements)
     {
         try
         {
             ProcessStatement(statement);
         }
         catch (CompileAbortException e)
         {
             // The statement's location info isn't passed all the way down so change the error to make it more accurate
             e.Error.Location = statement.Location;
             DMCompiler.Error(e.Error);
             return;                       // Don't spam the error that will continue to exist
         }
         catch (CompileErrorException e) { //Retreat from the statement when there's an error
             DMCompiler.Error(e.Error);
         }
     }
 }
コード例 #10
0
        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;
        }
コード例 #11
0
        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);
            }
        }