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}"); } }
public override void EmitPushValue(DMObject dmObject, DMProc proc) { _x.EmitPushValue(dmObject, proc); _y.EmitPushValue(dmObject, proc); _z.EmitPushValue(dmObject, proc); proc.LocateCoordinates(); }
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; }
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); }
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}\""); } } }
public override (DMReference Reference, bool Conditional) EmitReference(DMObject dmObject, DMProc proc) { _expr.EmitPushValue(dmObject, proc); _index.EmitPushValue(dmObject, proc); return(DMReference.ListIndex, _conditional); }
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; }
public override void EmitPushValue(DMObject dmObject, DMProc proc) { _var.EmitPushValue(dmObject, proc); _start.EmitPushValue(dmObject, proc); _end.EmitPushValue(dmObject, proc); proc.IsInRange(); }
public override void EmitOp(DMObject dmObject, DMProc proc, DMReference reference) { proc.PushReferenceValue(reference); RHS.EmitPushValue(dmObject, proc); proc.BitShiftRight(); proc.Assign(reference); }
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}"); } }
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) });
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); }
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); }
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 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); }
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); }
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}"); }
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); }
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); }
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(); }
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); } }
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; }
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); }
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); }
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}\""); }
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); }
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); } }
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); } }
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); } }
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); } }