LanguageContext.ob 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. MODULE LanguageContext;
  2. IMPORT Chars, CodeGenerator, Context, Designator, Errors, Expression, OberonRtl, Record, Symbols, T := Types, Variable;
  3. TYPE
  4. PType* = POINTER TO Type;
  5. CastOp* = RECORD
  6. PROCEDURE make*(cx: PType; e: Expression.PType): Expression.PType;
  7. PROCEDURE assign*(cx: PType; info: T.PVariable; right: Expression.PType): STRING;
  8. PROCEDURE clone*(cx: PType; e: Expression.PType): STRING;
  9. END;
  10. PCastOp* = POINTER TO CastOp;
  11. Types* = RECORD
  12. PROCEDURE implicitCast*(from, to: T.PType; toVar: BOOLEAN; VAR op: PCastOp): INTEGER;
  13. PROCEDURE typeInfo*(type: T.PType): STRING;
  14. PROCEDURE isRecursive*(type, base: T.PType): BOOLEAN;
  15. PROCEDURE makeOpenArray*(type: T.PType): T.PStorageType;
  16. PROCEDURE makeStaticArray*(type: T.PType; init: STRING; length: INTEGER): T.PStorageType;
  17. END;
  18. PTypes* = POINTER TO Types;
  19. ModuleGenerator* = RECORD
  20. PROCEDURE prolog*(): STRING;
  21. PROCEDURE epilog*(exports: Symbols.Map): STRING;
  22. END;
  23. PModuleGenerator* = POINTER TO ModuleGenerator;
  24. CodeTraits* = RECORD
  25. PROCEDURE CodeTraits*(code: CodeGenerator.PIGenerator; rtl: OberonRtl.PType; checkIndexes: BOOLEAN);
  26. PROCEDURE generator*(): CodeGenerator.PIGenerator;
  27. PROCEDURE getAt*(e, index: STRING; type: T.PStorageType): STRING;
  28. PROCEDURE putAt*(where, index, what: STRING): STRING;
  29. PROCEDURE referenceCode*(VAR info: T.Id): STRING;
  30. PROCEDURE assign*(VAR info: T.Id; right: Expression.PType): STRING;
  31. code: CodeGenerator.PIGenerator;
  32. rtl: OberonRtl.PType;
  33. checkIndexes: BOOLEAN;
  34. END;
  35. Imports = MAP OF STRING;
  36. Language* = RECORD
  37. moduleResolver-: PROCEDURE(name: STRING): T.PModule;
  38. PROCEDURE moduleGenerator*(name: STRING; imports: Imports): PModuleGenerator;
  39. rtl-: OberonRtl.PType;
  40. codeTraits-: POINTER TO CodeTraits;
  41. types-: PTypes;
  42. stdSymbols-: Symbols.Map;
  43. END;
  44. PLanguage* = POINTER TO Language;
  45. Type* = RECORD
  46. PROCEDURE Type*(language: PLanguage; cx: Context.PType);
  47. language-: PLanguage;
  48. cx-: Context.PType;
  49. END;
  50. PROCEDURE Type.Type(language: PLanguage; cx: Context.PType)
  51. | language(language),
  52. cx(cx);
  53. END;
  54. PROCEDURE CodeTraits.CodeTraits(code: CodeGenerator.PIGenerator; rtl: OberonRtl.PType; checkIndexes: BOOLEAN)
  55. | code(code),
  56. rtl(rtl),
  57. checkIndexes(checkIndexes);
  58. END;
  59. PROCEDURE CodeTraits.generator(): CodeGenerator.PIGenerator;
  60. RETURN SELF.code;
  61. END;
  62. PROCEDURE CodeTraits.getAt(e, index: STRING; type: T.PStorageType): STRING;
  63. VAR
  64. r: STRING;
  65. BEGIN
  66. IF ~SELF.checkIndexes THEN
  67. IF type = T.basic.ch THEN
  68. r := e + ".charCodeAt(" + index + ")";
  69. ELSE
  70. r := e + "[" + index + "]";
  71. END;
  72. ELSE
  73. IF type = T.basic.ch THEN
  74. r := SELF.rtl.charAt(e, index);
  75. ELSE
  76. r := SELF.rtl.getAt(e, index);
  77. END;
  78. END;
  79. RETURN r;
  80. END;
  81. PROCEDURE CodeTraits.putAt(where, index, what: STRING): STRING;
  82. VAR
  83. r: STRING;
  84. BEGIN
  85. IF ~SELF.checkIndexes THEN
  86. r := where + "[" + index + "] = " + what;
  87. ELSE
  88. r := SELF.rtl.putAt(where, index, what);
  89. END;
  90. RETURN r;
  91. END;
  92. PROCEDURE CodeTraits.referenceCode(VAR info: T.Id): STRING;
  93. VAR
  94. result: STRING;
  95. BEGIN
  96. IF info IS T.DeclaredVariable THEN
  97. result := CodeGenerator.mangleId(info.id());
  98. IF info.type().isScalar() & ~((info IS Variable.ArgumentVariable) & info.var) THEN
  99. result := "{set: function($v){" + result + " = $v;}, get: function(){return " + result + ";}}";
  100. END
  101. ELSIF info IS Variable.PropertyVariable THEN
  102. IF info.type().isScalar() THEN
  103. result := SELF.rtl.makeRef(info.leadCode, info.propCode);
  104. ELSE
  105. result := SELF.getAt(info.leadCode, info.propCode, info.type());
  106. END;
  107. ELSIF info IS Variable.DerefVariable THEN
  108. result := info.code;
  109. ELSIF info IS Record.FieldVariable THEN
  110. codeId <- Record.mangleField(info.field.id());
  111. IF info.type().isScalar() THEN
  112. result := SELF.rtl.makeRef(info.leadCode,
  113. Chars.doubleQuote + codeId + Chars.doubleQuote);
  114. ELSE
  115. result := info.leadCode + "." + codeId;
  116. END;
  117. ELSE
  118. Errors.raise("cannot reference " + info.idType());
  119. END;
  120. RETURN result;
  121. END;
  122. PROCEDURE CodeTraits.assign(VAR info: T.Id; right: Expression.PType): STRING;
  123. VAR
  124. result: STRING;
  125. BEGIN
  126. rightCode <- Expression.deref(right).code();
  127. IF info IS T.DeclaredVariable THEN
  128. idCode <- CodeGenerator.mangleId(info.id());
  129. IF (info IS Variable.ArgumentVariable) & info.var THEN
  130. result := idCode + ".set(" + rightCode + ")";
  131. ELSE
  132. result := idCode + " = " + rightCode;
  133. END;
  134. ELSIF info IS Variable.PropertyVariable THEN
  135. result := SELF.putAt(info.leadCode, info.propCode, rightCode);
  136. ELSIF info IS Record.FieldVariable THEN
  137. result := info.leadCode + "." + Record.mangleField(info.field.id()) + " = " + rightCode;
  138. END;
  139. RETURN result;
  140. END;
  141. END LanguageContext.