Newer
Older
TheVengeance-Project-IADE-Unity2D / Assets / Ink / InkLibs / InkCompiler / ParsedHierarchy / VariableAssignment.cs
  1. using System.Collections.Generic;
  2. namespace Ink.Parsed
  3. {
  4. public class VariableAssignment : Parsed.Object
  5. {
  6. public string variableName
  7. {
  8. get { return variableIdentifier.name; }
  9. }
  10. public Identifier variableIdentifier { get; protected set; }
  11. public Expression expression { get; protected set; }
  12. public ListDefinition listDefinition { get; protected set; }
  13. public bool isGlobalDeclaration { get; set; }
  14. public bool isNewTemporaryDeclaration { get; set; }
  15. public bool isDeclaration {
  16. get {
  17. return isGlobalDeclaration || isNewTemporaryDeclaration;
  18. }
  19. }
  20. public VariableAssignment (Identifier identifier, Expression assignedExpression)
  21. {
  22. this.variableIdentifier = identifier;
  23. // Defensive programming in case parsing of assignedExpression failed
  24. if( assignedExpression )
  25. this.expression = AddContent(assignedExpression);
  26. }
  27. public VariableAssignment (Identifier identifier, ListDefinition listDef)
  28. {
  29. this.variableIdentifier = identifier;
  30. if (listDef) {
  31. this.listDefinition = AddContent (listDef);
  32. this.listDefinition.variableAssignment = this;
  33. }
  34. // List definitions are always global
  35. isGlobalDeclaration = true;
  36. }
  37. public override Runtime.Object GenerateRuntimeObject ()
  38. {
  39. FlowBase newDeclScope = null;
  40. if (isGlobalDeclaration) {
  41. newDeclScope = story;
  42. } else if(isNewTemporaryDeclaration) {
  43. newDeclScope = ClosestFlowBase ();
  44. }
  45. if( newDeclScope )
  46. newDeclScope.TryAddNewVariableDeclaration (this);
  47. // Global declarations don't generate actual procedural
  48. // runtime objects, but instead add a global variable to the story itself.
  49. // The story then initialises them all in one go at the start of the game.
  50. if( isGlobalDeclaration )
  51. return null;
  52. var container = new Runtime.Container ();
  53. // The expression's runtimeObject is actually another nested container
  54. if( expression != null )
  55. container.AddContent (expression.runtimeObject);
  56. else if( listDefinition != null )
  57. container.AddContent (listDefinition.runtimeObject);
  58. _runtimeAssignment = new Runtime.VariableAssignment(variableName, isNewTemporaryDeclaration);
  59. container.AddContent (_runtimeAssignment);
  60. return container;
  61. }
  62. public override void ResolveReferences (Story context)
  63. {
  64. base.ResolveReferences (context);
  65. // List definitions are checked for conflicts separately
  66. if( this.isDeclaration && listDefinition == null )
  67. context.CheckForNamingCollisions (this, variableIdentifier, this.isGlobalDeclaration ? Story.SymbolType.Var : Story.SymbolType.Temp);
  68. // Initial VAR x = [intialValue] declaration, not re-assignment
  69. if (this.isGlobalDeclaration) {
  70. var variableReference = expression as VariableReference;
  71. if (variableReference && !variableReference.isConstantReference && !variableReference.isListItemReference) {
  72. Error ("global variable assignments cannot refer to other variables, only literal values, constants and list items");
  73. }
  74. }
  75. if (!this.isNewTemporaryDeclaration) {
  76. var resolvedVarAssignment = context.ResolveVariableWithName(this.variableName, fromNode: this);
  77. if (!resolvedVarAssignment.found) {
  78. if (story.constants.ContainsKey (variableName)) {
  79. Error ("Can't re-assign to a constant (do you need to use VAR when declaring '" + this.variableName + "'?)", this);
  80. } else {
  81. Error ("Variable could not be found to assign to: '" + this.variableName + "'", this);
  82. }
  83. }
  84. // A runtime assignment may not have been generated if it's the initial global declaration,
  85. // since these are hoisted out and handled specially in Story.ExportRuntime.
  86. if( _runtimeAssignment != null )
  87. _runtimeAssignment.isGlobal = resolvedVarAssignment.isGlobal;
  88. }
  89. }
  90. public override string typeName {
  91. get {
  92. if (isNewTemporaryDeclaration) return "temp";
  93. else if (isGlobalDeclaration) return "VAR";
  94. else return "variable assignment";
  95. }
  96. }
  97. Runtime.VariableAssignment _runtimeAssignment;
  98. }
  99. }