Esempio n. 1
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            switch (_expr)
            {
            case Field field:
                field.EmitPushIsSaved(proc);
                return;

            case Dereference dereference:
                dereference.EmitPushIsSaved(dmObject, proc);
                return;

            case Local:
                proc.PushFloat(0);
                return;

            case ListIndex idx:
                proc.PushFloat(0);
                //TODO Support "vars" properly
                idx.IsSaved();
                return;

            default:
                throw new CompileErrorException(Location, $"can't get saved value of {_expr}");
            }
        }
Esempio n. 2
0
 public override void EmitPushValue(DMObject dmObject, DMProc proc)
 {
     _x.EmitPushValue(dmObject, proc);
     _y.EmitPushValue(dmObject, proc);
     _z.EmitPushValue(dmObject, proc);
     proc.LocateCoordinates();
 }
Esempio n. 3
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;
        }
Esempio n. 4
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            if (_astNode.Parameters.Length == 0 || _astNode.Parameters.Length > 4)
            {
                throw new CompileErrorException(_astNode.Location, "Invalid input() parameter count");
            }

            //Push input's four arguments, pushing null for the missing ones
            for (int i = 3; i >= 0; i--)
            {
                if (i < _astNode.Parameters.Length)
                {
                    DMASTCallParameter parameter = _astNode.Parameters[i];

                    if (parameter.Key != null)
                    {
                        throw new CompileErrorException(parameter.Location, "input() does not take named arguments");
                    }
                    DMExpression.Create(dmObject, proc, parameter.Value).EmitPushValue(dmObject, proc);
                }
                else
                {
                    proc.PushNull();
                }
            }

            proc.Prompt(_astNode.Types);
        }
Esempio n. 5
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}\"");
                }
            }
        }
Esempio n. 6
0
        public override (DMReference Reference, bool Conditional) EmitReference(DMObject dmObject, DMProc proc)
        {
            _expr.EmitPushValue(dmObject, proc);
            _index.EmitPushValue(dmObject, proc);

            return(DMReference.ListIndex, _conditional);
        }
Esempio n. 7
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;
        }
Esempio n. 8
0
 public override void EmitPushValue(DMObject dmObject, DMProc proc)
 {
     _var.EmitPushValue(dmObject, proc);
     _start.EmitPushValue(dmObject, proc);
     _end.EmitPushValue(dmObject, proc);
     proc.IsInRange();
 }
Esempio n. 9
0
 public override void EmitOp(DMObject dmObject, DMProc proc, DMReference reference)
 {
     proc.PushReferenceValue(reference);
     RHS.EmitPushValue(dmObject, proc);
     proc.BitShiftRight();
     proc.Assign(reference);
 }
Esempio n. 10
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            switch (_expr)
            {
            case Field field:
                field.EmitPushIsSaved(proc);
                return;

            case Dereference dereference:
                dereference.EmitPushIsSaved(dmObject, proc);
                return;

            case Local:
                proc.PushFloat(0);
                return;

            case ListIndex:
                proc.PushFloat(0);
                // Silent in BYOND
                DMCompiler.Warning(new CompilerWarning(_expr.Location, "calling issaved() on a list index is always false"));
                return;

            default:
                throw new CompileErrorException(Location, $"can't get saved value of {_expr}");
            }
        }
Esempio n. 11
0
 public (DMObject ProcOwner, DMProc Proc) GetTargetProc(DMObject dmObject)
 {
     return(_target switch {
         Proc procTarget => (dmObject, procTarget.GetProc(dmObject)),
         GlobalProc procTarget => (null, procTarget.GetProc()),
         DereferenceProc derefTarget => derefTarget.GetProc(),
         _ => (null, null)
     });
Esempio n. 12
0
 public override (DMReference Reference, bool Conditional) EmitReference(DMObject dmObject, DMProc proc)
 {
     if (!proc.IsOverride)
     {
         DMCompiler.Warning(new CompilerWarning(Location, "Calling parents via ..() in a proc definition does nothing"));
     }
     return(DMReference.SuperProc, false);
 }
Esempio n. 13
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            for (int i = Expressions.Length - 1; i >= 0; i--)
            {
                Expressions[i].EmitPushValue(dmObject, proc);
            }

            proc.FormatString(Value);
        }
Esempio n. 14
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];
Esempio n. 15
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            string endLabel = proc.NewLabelName();

            LHS.EmitPushValue(dmObject, proc);
            proc.BooleanAnd(endLabel);
            RHS.EmitPushValue(dmObject, proc);
            proc.AddLabel(endLabel);
        }
Esempio n. 16
0
        public override (DMReference Reference, bool Conditional) EmitReference(DMObject dmObject, DMProc proc)
        {
            if (!DMObjectTree.TryGetGlobalProc(_name, out _))
            {
                throw new CompileErrorException(Location, $"There is no global proc named \"{_name}\"");
            }

            return(DMReference.CreateGlobalProc(_name), false);
        }
Esempio n. 17
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            if (_expr is LValue lValue)
            {
                lValue.EmitPushInitial(dmObject, proc);
                return;
            }

            throw new CompileErrorException(Location, $"can't get initial value of {_expr}");
        }
Esempio n. 18
0
 public override void EmitPushInitial(DMObject dmObject, DMProc proc)
 {
     // This happens silently in BYOND
     // TODO Support "vars" actually pushing initial() correctly
     if (_expr is Dereference deref && deref.PropertyName != "vars")
     {
         DMCompiler.Warning(new CompilerWarning(Location, "calling initial() on a list index returns the current value"));
     }
     EmitPushValue(dmObject, proc);
 }
Esempio n. 19
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            foreach (DMExpression parameter in _parameters)
            {
                parameter.EmitPushValue(dmObject, proc);
                proc.PushArguments(0);
                proc.CreateObject();
            }

            proc.CreateList(_parameters.Length);
        }
Esempio n. 20
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            if (_b != null)
            {
                _b.EmitPushValue(dmObject, proc);
            }

            _a.EmitPushValue(dmObject, proc);
            _procArgs.EmitPushArguments(dmObject, proc);
            proc.CallStatement();
        }
Esempio n. 21
0
 public override (DMReference Reference, bool Conditional) EmitReference(DMObject dmObject, DMProc proc)
 {
     if (LocalVar.IsParameter)
     {
         return(DMReference.CreateArgument(LocalVar.Id), false);
     }
     else
     {
         return(DMReference.CreateLocal(LocalVar.Id), false);
     }
 }
Esempio n. 22
0
        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;
        }
Esempio n. 23
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            //We don't have to do any checking of our parameters since that was already done by VisitAddText(), hopefully. :)

            //Push addtext's arguments
            foreach (DMExpression parameter in parameters)
            {
                parameter.EmitPushValue(dmObject, proc);
            }

            proc.MassConcatenation(parameters.Length);
        }
Esempio n. 24
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            string cLabel   = proc.NewLabelName();
            string endLabel = proc.NewLabelName();

            _a.EmitPushValue(dmObject, proc);
            proc.JumpIfFalse(cLabel);
            _b.EmitPushValue(dmObject, proc);
            proc.Jump(endLabel);
            proc.AddLabel(cLabel);
            _c.EmitPushValue(dmObject, proc);
            proc.AddLabel(endLabel);
        }
Esempio n. 25
0
        public override (DMReference Reference, bool Conditional) EmitReference(DMObject dmObject, DMProc proc)
        {
            if (dmObject.HasProc(_identifier))
            {
                return(DMReference.CreateSrcProc(_identifier), false);
            }
            else if (DMObjectTree.TryGetGlobalProc(_identifier, out _))
            {
                return(DMReference.CreateGlobalProc(_identifier), false);
            }

            throw new CompileErrorException(Location, $"Type {dmObject.Path} does not have a proc named \"{_identifier}\"");
        }
Esempio n. 26
0
        public override void EmitOp(DMObject dmObject, DMProc proc, DMReference reference)
        {
            string skipLabel = proc.NewLabelName();
            string endLabel  = proc.NewLabelName();

            proc.PushReferenceValue(reference);
            proc.JumpIfTrue(skipLabel);

            RHS.EmitPushValue(dmObject, proc);
            proc.Assign(reference);
            proc.Jump(endLabel);

            proc.AddLabel(skipLabel);
            proc.PushReferenceValue(reference);
            proc.AddLabel(endLabel);
        }
Esempio n. 27
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            bool weighted = false;

            foreach (PickValue pickValue in _values)
            {
                if (pickValue.Weight != null)
                {
                    weighted = true;
                    break;
                }
            }

            if (weighted)
            {
                if (_values.Length == 1)
                {
                    DMCompiler.Warning(new CompilerWarning(Location, "Weighted pick() with one argument"));
                }

                foreach (PickValue pickValue in _values)
                {
                    DMExpression weight = pickValue.Weight ?? DMExpression.Create(dmObject, proc, new DMASTConstantInteger(Location, 100)); //Default of 100

                    weight.EmitPushValue(dmObject, proc);
                    pickValue.Value.EmitPushValue(dmObject, proc);
                }

                proc.PickWeighted(_values.Length);
            }
            else
            {
                foreach (PickValue pickValue in _values)
                {
                    if (pickValue.Value is Arglist args)
                    {
                        args.EmitPushArglist(dmObject, proc);
                    }
                    else
                    {
                        pickValue.Value.EmitPushValue(dmObject, proc);
                    }
                }

                proc.PickUnweighted(_values.Length);
            }
        }
Esempio n. 28
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);
            }
        }
Esempio n. 29
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            (DMReference reference, bool conditional) = EmitReference(dmObject, proc);

            if (conditional)
            {
                string skipLabel = proc.NewLabelName();

                proc.JumpIfNullDereference(reference, skipLabel);
                proc.PushReferenceValue(reference);
                proc.AddLabel(skipLabel);
            }
            else
            {
                proc.PushReferenceValue(reference);
            }
        }
Esempio n. 30
0
        public override void EmitPushValue(DMObject dmObject, DMProc proc)
        {
            (DMReference reference, bool conditional) = LHS.EmitReference(dmObject, proc);

            if (conditional)
            {
                string nullSkipLabel = proc.NewLabelName();

                proc.JumpIfNullDereference(reference, nullSkipLabel);
                EmitOp(dmObject, proc, reference);
                proc.AddLabel(nullSkipLabel);
            }
            else
            {
                EmitOp(dmObject, proc, reference);
            }
        }