ContextType.ob 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. MODULE ContextType;
  2. IMPORT
  3. Chars, CodeGenerator, ConstValue, Context, ContextExpression, ContextHierarchy,
  4. Errors, Expression, ExpressionTree, Object, R := Record,
  5. Scope, ScopeBase, String, Symbols, TypeId, Types;
  6. TYPE
  7. HandleSymbolAsType* = RECORD(ContextHierarchy.Node)
  8. PROCEDURE handleQIdent*(q: ContextHierarchy.QIdent);
  9. PROCEDURE setType*(type: Types.PStorageType);
  10. END;
  11. PHandleSymbolAsType = POINTER TO HandleSymbolAsType;
  12. DeclarationHandle* = RECORD(HandleSymbolAsType)
  13. PROCEDURE typeName*(): STRING;
  14. PROCEDURE isAnonymousDeclaration*(): BOOLEAN;
  15. END;
  16. PDeclarationHandle* = POINTER TO DeclarationHandle;
  17. FormalType* = RECORD(HandleSymbolAsType)
  18. dimensionCount: INTEGER;
  19. END;
  20. Array* = RECORD(DeclarationHandle)
  21. PROCEDURE doMakeInit*(type: Types.PStorageType; dimensions: STRING; length: INTEGER): STRING;
  22. PROCEDURE doMakeType*(elementsType: Types.PStorageType; init: STRING; length: INTEGER): Types.PStorageType;
  23. dimensions: POINTER TO ArrayDimensions;
  24. END;
  25. ArrayDimensions* = RECORD(ContextExpression.ExpressionHandler)
  26. PROCEDURE doAddDimension*(size: INTEGER);
  27. dimensions: ARRAY * OF INTEGER;
  28. END;
  29. HavingFieldsDeclaration* = RECORD(DeclarationHandle)
  30. PROCEDURE exportField*(name: STRING);
  31. END;
  32. DeclarationAndIdentHandle* = RECORD(HavingFieldsDeclaration)
  33. PROCEDURE handleIdentdef*(id: Context.PIdentdefInfo);
  34. END;
  35. PDeclarationAndIdentHandle* = POINTER TO DeclarationAndIdentHandle;
  36. Declaration* = RECORD(DeclarationAndIdentHandle)
  37. id-: Context.PIdentdefInfo;
  38. symbol: Symbols.PSymbol;
  39. END;
  40. PDeclaration* = POINTER TO Declaration;
  41. RecordTypeFactory = PROCEDURE(name, cons: STRING; scope: ScopeBase.PType): R.PType;
  42. Record* = RECORD(ContextHierarchy.Node)
  43. PROCEDURE Record*(parent: PDeclaration; factory: RecordTypeFactory);
  44. PROCEDURE addField(field: Context.PIdentdefInfo; type: Types.PStorageType);
  45. PROCEDURE setBaseType(type: Types.PType);
  46. PROCEDURE generateInheritance*(): STRING;
  47. PROCEDURE qualifiedBaseConstructor*(): STRING;
  48. PROCEDURE doMakeField*(field: Context.PIdentdefInfo; type: Types.PStorageType): Types.PField;
  49. PROCEDURE doGenerateConstructor(): STRING;
  50. PROCEDURE doGenerateBaseConstructorCallCode*(): STRING;
  51. declaration-: PDeclaration;
  52. cons: STRING;
  53. type-: R.PType;
  54. END;
  55. PRecord = POINTER TO Record;
  56. RecordBase* = RECORD(ContextHierarchy.Node)
  57. PROCEDURE handleQIdent(q: ContextHierarchy.QIdent);
  58. END;
  59. FieldList* = RECORD(Declaration)
  60. idents: ARRAY * OF Context.PIdentdefInfo;
  61. type: Types.PStorageType;
  62. END;
  63. Pointer* = RECORD(HavingFieldsDeclaration)
  64. END;
  65. Section* = RECORD(ContextHierarchy.Node)
  66. END;
  67. ResolveClosure = RECORD(Object.Type)
  68. PROCEDURE ResolveClosure(root: ContextHierarchy.PRoot; id: STRING);
  69. root: ContextHierarchy.PRoot;
  70. id: STRING;
  71. END;
  72. PResolveClosure = POINTER TO ResolveClosure;
  73. ForwardTypeMsg* = RECORD(ContextHierarchy.Message)
  74. PROCEDURE ForwardTypeMsg(id: STRING);
  75. id-: STRING;
  76. END;
  77. ScopeInfo* = RECORD
  78. PROCEDURE ScopeInfo(id: STRING; depth: INTEGER);
  79. id: STRING;
  80. depth: INTEGER;
  81. END;
  82. PScopeInfo = POINTER TO ScopeInfo;
  83. ScopeInfoGenerator* = RECORD
  84. PROCEDURE ScopeInfoGenerator*(name: STRING; code: CodeGenerator.PIGenerator; parent: ContextHierarchy.PNode);
  85. name: STRING;
  86. code: CodeGenerator.PIGenerator;
  87. parent: ContextHierarchy.PNode;
  88. codeBegin: CodeGenerator.PInsertion;
  89. info: PScopeInfo;
  90. END;
  91. PScopeInfoGenerator* = POINTER TO ScopeInfoGenerator;
  92. DescribeScopeMsg* = RECORD(ContextHierarchy.Message)
  93. result: PScopeInfo;
  94. END;
  95. PROCEDURE HandleSymbolAsType.handleQIdent(q: ContextHierarchy.QIdent);
  96. BEGIN
  97. s <- ContextHierarchy.getQIdSymbolAndScope(SELF.root()^, q);
  98. SELF.setType(ExpressionTree.unwrapType(s.symbol().info()));
  99. END;
  100. PROCEDURE FormalType.setType(type: Types.PStorageType);
  101. BEGIN
  102. result <- type;
  103. types <- SELF.root().language().types;
  104. FOR i <- 0 TO SELF.dimensionCount - 1 DO
  105. result := types.makeOpenArray(result);
  106. END;
  107. SELF.parent()(PHandleSymbolAsType).setType(result);
  108. END;
  109. PROCEDURE FormalType.handleLiteral(s: STRING);
  110. BEGIN
  111. IF s = "ARRAY" THEN
  112. INC(SELF.dimensionCount);
  113. END;
  114. END;
  115. PROCEDURE Array.typeName(): STRING;
  116. RETURN "";
  117. END;
  118. PROCEDURE Array.setType(elementsType: Types.PStorageType);
  119. VAR
  120. dimensions: STRING;
  121. arrayInit: STRING;
  122. BEGIN
  123. type <- elementsType;
  124. FOR i <- LEN(SELF.dimensions.dimensions) - 1 TO 0 BY -1 DO
  125. IF LEN(dimensions) # 0 THEN
  126. dimensions := ", " + dimensions;
  127. END;
  128. length <- SELF.dimensions.dimensions[i];
  129. dimensions := String.fromInt(length) + dimensions;
  130. IF i = 0 THEN
  131. arrayInit := SELF.doMakeInit(elementsType, dimensions, length);
  132. END;
  133. type := SELF.doMakeType(type, arrayInit, length);
  134. END;
  135. SELF.parent()(PHandleSymbolAsType).setType(type);
  136. END;
  137. PROCEDURE Array.isAnonymousDeclaration(): BOOLEAN;
  138. RETURN TRUE;
  139. END;
  140. PROCEDURE Array.doMakeInit(type: Types.PStorageType; dimensions: STRING; length: INTEGER): STRING;
  141. VAR
  142. result: STRING;
  143. initializer: STRING;
  144. BEGIN
  145. rtl <- SELF.root().language().rtl;
  146. IF type = Types.basic.ch THEN
  147. result := rtl.makeCharArray(dimensions);
  148. ELSE
  149. IF (type IS Types.PArray) OR (type IS Types.PRecord) THEN
  150. initializer := "function(){return " + type.initializer(SELF) + ";}";
  151. ELSE
  152. initializer := type.initializer(SELF);
  153. END;
  154. result := rtl.makeArray(dimensions + ", " + initializer);
  155. END;
  156. RETURN result;
  157. END;
  158. PROCEDURE Array.doMakeType(elementsType: Types.PStorageType; init: STRING; length: INTEGER): Types.PStorageType;
  159. RETURN SELF.root().language().types.makeStaticArray(elementsType, init, length);
  160. END;
  161. PROCEDURE ArrayDimensions.handleExpression(e: Expression.PType);
  162. BEGIN
  163. type <- e.type();
  164. IF type # Types.basic.integer THEN
  165. Errors.raise("'INTEGER' constant expression expected, got '" + type.description() + "'");
  166. END;
  167. value <- e.constValue();
  168. IF value = NIL THEN
  169. Errors.raise("constant expression expected as ARRAY size");
  170. END;
  171. dimension <- value(ConstValue.PInt).value;
  172. IF dimension <= 0 THEN
  173. Errors.raise("array size must be greater than 0, got " + String.fromInt(dimension));
  174. END;
  175. SELF.doAddDimension(dimension);
  176. END;
  177. PROCEDURE ArrayDimensions.doAddDimension(size: INTEGER);
  178. BEGIN
  179. SELF.dimensions.add(size);
  180. END;
  181. PROCEDURE ArrayDimensions.codeGenerator(): CodeGenerator.PIGenerator;
  182. RETURN CodeGenerator.nullGenerator;
  183. END;
  184. PROCEDURE ArrayDimensions.endParse(): BOOLEAN;
  185. BEGIN
  186. SELF.parent()^(Array).dimensions := SELF(POINTER);
  187. RETURN TRUE;
  188. END;
  189. PROCEDURE isTypeRecursive*(type, base: Types.PType): BOOLEAN;
  190. BEGIN
  191. result <- FALSE;
  192. IF type = base THEN
  193. result := TRUE;
  194. ELSIF type IS R.PType THEN
  195. IF isTypeRecursive(type.base, base) THEN
  196. result := TRUE;
  197. ELSE
  198. FOR field IN type.fields DO
  199. IF ~result & isTypeRecursive(field.type(), base) THEN
  200. result := TRUE;
  201. END;
  202. END;
  203. END;
  204. ELSIF type IS Types.PArray THEN
  205. result := isTypeRecursive(type.elementsType, base);
  206. END;
  207. RETURN result;
  208. END;
  209. PROCEDURE stripTypeId(closure: Object.PType);
  210. BEGIN
  211. typeId <- closure(TypeId.PType);
  212. R.stripTypeId(typeId^);
  213. END;
  214. PROCEDURE checkIfFieldCanBeExported*(name: STRING; idents: ARRAY OF Context.PIdentdefInfo; hint: STRING);
  215. BEGIN
  216. FOR id IN idents DO
  217. IF ~id.exported() THEN
  218. Errors.raise(
  219. "field '" + name + "' can be exported only if " + hint + " '" +
  220. id.id() + "' itself is exported too");
  221. END;
  222. END;
  223. END;
  224. PROCEDURE Declaration.handleIdentdef(id: Context.PIdentdefInfo);
  225. BEGIN
  226. typeId <- NEW TypeId.Lazy();
  227. symbol <- NEW Symbols.Symbol(id.id(), typeId);
  228. scope <- SELF.root().currentScope();
  229. scope.addSymbol(symbol, id.exported());
  230. IF ~id.exported() THEN
  231. scope.addFinalizer(stripTypeId, typeId);
  232. END;
  233. SELF.id := id;
  234. SELF.symbol := symbol;
  235. END;
  236. PROCEDURE Declaration.setType(type: Types.PStorageType);
  237. BEGIN
  238. TypeId.define(SELF.symbol.info()^(TypeId.Lazy), type);
  239. Scope.resolve(SELF.root().currentScope()^, SELF.symbol);
  240. END;
  241. PROCEDURE Declaration.isAnonymousDeclaration(): BOOLEAN;
  242. RETURN FALSE;
  243. END;
  244. PROCEDURE Declaration.exportField(name: STRING);
  245. VAR
  246. idents: ARRAY 1 OF Context.PIdentdefInfo;
  247. BEGIN
  248. idents[0] := SELF.id;
  249. checkIfFieldCanBeExported(name, idents, "record");
  250. END;
  251. PROCEDURE Declaration.typeName(): STRING;
  252. RETURN SELF.id.id();
  253. END;
  254. PROCEDURE Declaration.genTypeName(): STRING;
  255. RETURN SELF.typeName();
  256. END;
  257. PROCEDURE Record.Record(parent: PDeclaration; factory: RecordTypeFactory)
  258. | SUPER(parent),
  259. declaration(parent);
  260. VAR
  261. name: STRING;
  262. BEGIN
  263. SELF.cons := parent.genTypeName();
  264. IF ~parent.isAnonymousDeclaration() THEN
  265. name := SELF.cons;
  266. END;
  267. SELF.type := factory(name, SELF.cons, parent.root().currentScope());
  268. parent.setType(SELF.type);
  269. END;
  270. PROCEDURE Record.addField(field: Context.PIdentdefInfo; type: Types.PStorageType);
  271. BEGIN
  272. IF SELF.root().language().types.isRecursive(type, SELF.type) THEN
  273. Errors.raise("recursive field definition: '" + field.id() + "'");
  274. END;
  275. SELF.type.addField(SELF.doMakeField(field, type));
  276. IF field.exported() THEN
  277. SELF.declaration.exportField(field.id());
  278. END;
  279. END;
  280. PROCEDURE Record.setBaseType(type: Types.PType);
  281. BEGIN
  282. IF ~(type IS R.PType) THEN
  283. Errors.raise(
  284. "RECORD type is expected as a base type, got '"
  285. + type.description()
  286. + "'");
  287. ELSE
  288. IF type = SELF.type THEN
  289. Errors.raise("recursive inheritance: '"
  290. + SELF.type.description() + "'");
  291. END;
  292. SELF.type.setBase(type);
  293. END;
  294. END;
  295. PROCEDURE Record.doMakeField(field: Context.PIdentdefInfo; type: Types.PStorageType): Types.PField;
  296. BEGIN
  297. RETURN NEW R.Field(field, type);
  298. END;
  299. PROCEDURE generateFieldsInitializationCode(r: Record): STRING;
  300. VAR
  301. result: STRING;
  302. BEGIN
  303. FOR f, t IN r.type.fields DO
  304. result := result + "this." + R.mangleField(f) + " = " + t.type().initializer(r) + ";" + Chars.ln;
  305. END;
  306. RETURN result;
  307. END;
  308. PROCEDURE Record.doGenerateConstructor(): STRING;
  309. BEGIN
  310. gen <- NEW CodeGenerator.Generator();
  311. gen.write("function " + SELF.cons + "()");
  312. gen.openScope();
  313. gen.write(SELF.doGenerateBaseConstructorCallCode()
  314. + generateFieldsInitializationCode(SELF));
  315. gen.closeScope("");
  316. RETURN gen.result();
  317. END;
  318. PROCEDURE Record.generateInheritance(): STRING;
  319. VAR
  320. result: STRING;
  321. BEGIN
  322. scopeMsg <- DescribeScopeMsg();
  323. void <- SELF.parent().handleMessage(scopeMsg);
  324. scope <- scopeMsg.result.id;
  325. base <- SELF.type.base;
  326. IF base = NIL THEN
  327. result := SELF.cons + ".prototype.$scope = " + scope + ";" + Chars.ln;
  328. ELSE
  329. qualifiedBase <- SELF.qualifyScope(base.scope) + base.name;
  330. result := SELF.root().language().rtl.extend(SELF.cons, qualifiedBase, scope) + ";" + Chars.ln;
  331. END;
  332. RETURN result;
  333. END;
  334. PROCEDURE Record.doGenerateBaseConstructorCallCode(): STRING;
  335. BEGIN
  336. result <- SELF.qualifiedBaseConstructor();
  337. IF LEN(result) # 0 THEN
  338. result := result + ".call(this);" + Chars.ln;
  339. END;
  340. RETURN result;
  341. END;
  342. PROCEDURE Record.qualifiedBaseConstructor(): STRING;
  343. VAR
  344. result: STRING;
  345. BEGIN
  346. baseType <- SELF.type.base;
  347. IF baseType # NIL THEN
  348. result := SELF.qualifyScope(baseType.scope) + baseType.name;
  349. END;
  350. RETURN result;
  351. END;
  352. PROCEDURE Record.endParse(): BOOLEAN;
  353. VAR
  354. scopeMsg: DescribeScopeMsg;
  355. BEGIN
  356. SELF.codeGenerator().write(
  357. SELF.doGenerateConstructor()
  358. + SELF.generateInheritance()
  359. );
  360. RETURN TRUE;
  361. END;
  362. PROCEDURE RecordBase.handleQIdent(q: ContextHierarchy.QIdent);
  363. BEGIN
  364. s <- ContextHierarchy.getQIdSymbolAndScope(SELF.root()^, q);
  365. base <- ExpressionTree.unwrapType(s.symbol().info());
  366. SELF.parent()^(Record).setBaseType(base);
  367. END;
  368. PROCEDURE FieldList.isAnonymousDeclaration(): BOOLEAN;
  369. RETURN TRUE;
  370. END;
  371. PROCEDURE FieldList.exportField(name: STRING);
  372. BEGIN
  373. checkIfFieldCanBeExported(name, SELF.idents, "field");
  374. END;
  375. PROCEDURE FieldList.setType(type: Types.PStorageType);
  376. BEGIN
  377. SELF.type := type;
  378. END;
  379. PROCEDURE FieldList.handleIdentdef(id: Context.PIdentdefInfo);
  380. BEGIN
  381. SELF.idents.add(id);
  382. END;
  383. PROCEDURE FieldList.typeName(): STRING;
  384. RETURN "";
  385. END;
  386. PROCEDURE FieldList.endParse(): BOOLEAN;
  387. BEGIN
  388. parent <- SELF.parent()(PRecord);
  389. FOR id IN SELF.idents DO
  390. parent.addField(id, SELF.type);
  391. END;
  392. RETURN TRUE;
  393. END;
  394. PROCEDURE setPointerTypeId(p: Pointer; typeId: TypeId.PType);
  395. VAR
  396. name: STRING;
  397. typeDesc: STRING;
  398. BEGIN
  399. IF ~(typeId^ IS TypeId.Forward) THEN
  400. type <- typeId.type();
  401. IF ~(type IS Types.PRecord) THEN
  402. IF type # NIL THEN
  403. typeDesc := ", got '" + type.description() + "'";
  404. END;
  405. Errors.raise("RECORD is expected as a POINTER base type" + typeDesc);
  406. END;
  407. END;
  408. parent <- p.parent()(PDeclarationHandle);
  409. IF ~parent.isAnonymousDeclaration() THEN
  410. name := parent.genTypeName();
  411. END;
  412. parent.setType(NEW R.Pointer(name, typeId));
  413. END;
  414. PROCEDURE Pointer.handleQIdent(q: ContextHierarchy.QIdent);
  415. VAR
  416. info: Types.PId;
  417. s: Symbols.PFoundSymbol;
  418. BEGIN
  419. id <- q.id;
  420. IF q.module # NIL THEN
  421. s := ContextHierarchy.getModuleSymbolAndScope(q.module^, id);
  422. ELSE
  423. s := SELF.root().findSymbol(id);
  424. END;
  425. IF s # NIL THEN
  426. info := s.symbol().info();
  427. ELSE
  428. msg <- NEW ForwardTypeMsg(id);
  429. info := SELF.parent().handleMessage(msg^)(Types.PId);
  430. END;
  431. setPointerTypeId(SELF, ExpressionTree.unwrapTypeId(info));
  432. END;
  433. PROCEDURE Pointer.setType(type: Types.PStorageType);
  434. BEGIN
  435. typeId <- NEW TypeId.Type(type);
  436. SELF.root().currentScope().addFinalizer(stripTypeId, typeId);
  437. setPointerTypeId(SELF, typeId);
  438. END;
  439. PROCEDURE Pointer.isAnonymousDeclaration(): BOOLEAN;
  440. RETURN TRUE;
  441. END;
  442. PROCEDURE Pointer.exportField(field: STRING);
  443. BEGIN
  444. Errors.raise("cannot export anonymous RECORD field: '" + field + "'");
  445. END;
  446. PROCEDURE ResolveClosure.ResolveClosure(root: ContextHierarchy.PRoot; id: STRING)
  447. | root(root),
  448. id(id);
  449. END;
  450. PROCEDURE resolve(closure: Object.PType): Types.PStorageType;
  451. BEGIN
  452. r <- closure(PResolveClosure);
  453. info <- ContextHierarchy.getSymbol(r.root^, r.id).info();
  454. RETURN info(TypeId.PType).type();
  455. END;
  456. PROCEDURE Section.handleMessage(VAR msg: ContextHierarchy.Message): Object.PType;
  457. VAR
  458. result: Object.PType;
  459. BEGIN
  460. IF msg IS ForwardTypeMsg THEN
  461. root <- SELF.root();
  462. scope <- root.currentScope();
  463. Scope.addUnresolved(scope^, msg.id);
  464. result := NEW TypeId.Forward(resolve, NEW ResolveClosure(root, msg.id));
  465. ELSE
  466. result := SUPER(msg);
  467. END;
  468. RETURN result;
  469. END;
  470. PROCEDURE Section.endParse(): BOOLEAN;
  471. BEGIN
  472. Scope.checkAllResolved(SELF.root().currentScope()^);
  473. RETURN TRUE;
  474. END;
  475. PROCEDURE ForwardTypeMsg.ForwardTypeMsg(id: STRING)
  476. | id(id);
  477. END;
  478. PROCEDURE ScopeInfo.ScopeInfo(id: STRING; depth: INTEGER)
  479. | id(id),
  480. depth(depth);
  481. END;
  482. PROCEDURE ScopeInfoGenerator.ScopeInfoGenerator(name: STRING; code: CodeGenerator.PIGenerator; parent: ContextHierarchy.PNode)
  483. | name(name),
  484. code(code),
  485. parent(parent),
  486. codeBegin(code.makeInsertion());
  487. BEGIN
  488. END;
  489. PROCEDURE makeScopeInfo(name: STRING; code: CodeGenerator.IGenerator; parent: ContextHierarchy.PNode): PScopeInfo;
  490. VAR
  491. id, description: STRING;
  492. BEGIN
  493. id := "$scope";
  494. depth <- 0;
  495. IF parent = NIL THEN
  496. description := Chars.doubleQuote + name + Chars.doubleQuote;
  497. ELSE
  498. msg <- DescribeScopeMsg();
  499. void <- parent.handleMessage(msg);
  500. depth := msg.result.depth + 1;
  501. description := msg.result.id + " + " + Chars.doubleQuote + "." + name + Chars.doubleQuote;
  502. id := id + String.fromInt(depth);
  503. END;
  504. code.write("var " + id + " = " + description + ";" + Chars.ln);
  505. RETURN NEW ScopeInfo(id, depth);
  506. END;
  507. PROCEDURE handleDescribeScopeMsg*(VAR msg: ContextHierarchy.Message; VAR s: ScopeInfoGenerator): BOOLEAN;
  508. BEGIN
  509. result <- FALSE;
  510. IF msg IS DescribeScopeMsg THEN
  511. IF s.info = NIL THEN
  512. code <- CodeGenerator.Generator();
  513. s.info := makeScopeInfo(s.name, code, s.parent);
  514. s.code.insert(s.codeBegin^, code.result());
  515. END;
  516. msg.result := s.info;
  517. result := TRUE;
  518. END;
  519. RETURN result;
  520. END;
  521. END ContextType.