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 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 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); }
public void ProcessBlockInner(DMASTBlockInner blockInner) { foreach (DMASTStatement statement in blockInner.Statements) { try { ProcessStatement(statement); } catch (CompileErrorException e) { DMCompiler.Error(e.Error); } } }
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); } } }
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(); }
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); } } }
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(); }
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); } } }
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 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); } }