Synthesis.mod 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. IMPLEMENTATION MODULE Synthesis; (* gf 30.12.88 (pl0) *)
  2. FROM Storage IMPORT ALLOCATE;
  3. FROM InOut IMPORT WriteLn, WriteString;
  4. FROM Scanner IMPORT IDENT, STRING, POSITION,
  5. traceParser;
  6. FROM InternalTree IMPORT BLCK, DECL, STMT, EXPR,
  7. blckPtr, declPtr, stmtPtr, exprPtr,
  8. declKind, stmtKind, exprKind,
  9. monOperator, dyOperator, conType,
  10. NewDeclSequence,NewStmtSequence,NewExprSequence,
  11. NoDeclaration, NoStatement, NoExpression;
  12. FROM ErrorHandling IMPORT PrintError2;
  13. FROM Interpreter IMPORT Command;
  14. FROM Generator IMPORT InitGenerator,
  15. Gen, GenL, GenS, Gens,
  16. Label, GetNewLabel, SetLabel;
  17. FROM ObjectTable IMPORT Object, ObjKind, ObjType,
  18. Undefined, Integer,
  19. EnterDecl, FindDecl, GetObjType,
  20. EnterBlock, LeaveBlock,
  21. InitObjectTable;
  22. VAR currLevel : CARDINAL;
  23. PROCEDURE Trace (s : ARRAY OF CHAR);
  24. VAR i: CARDINAL;
  25. BEGIN
  26. IF traceParser THEN
  27. FOR i := 1 TO currLevel DO
  28. WriteString(' |');
  29. END;
  30. WriteString(s); WriteLn
  31. END
  32. END Trace;
  33. PROCEDURE Error(n : CARDINAL; p : POSITION);
  34. BEGIN
  35. SemanticError := TRUE;
  36. PrintError2(n, p)
  37. END Error;
  38. (* the following forward declaration is needed for the OSI M2 compiler
  39. ( *$nonstandard * )
  40. PROCEDURE expression(node: exprPtr); FORWARD;
  41. ( *$standard *)
  42. PROCEDURE LoadAddr(obj: Object);
  43. (* load addr of variable or parameter, return it's type *)
  44. BEGIN
  45. Trace("LoadAddr");
  46. Gen(LDA, currLevel - obj^.level, obj^.vAdr);
  47. END LoadAddr;
  48. PROCEDURE expression(node: exprPtr);
  49. VAR obj : Object;
  50. BEGIN (* expression *)
  51. Trace( "expression");
  52. CASE node^.kind OF
  53. identifier:
  54. Trace(" identifier");
  55. obj := FindDecl(node^.usedId, node^.position);
  56. WITH obj^ DO
  57. CASE obj^.kind OF
  58. constant :
  59. Trace(" constant");
  60. Gen(LDI, 0, CARDINAL(cVal));
  61. IF node^.usedInd^.kind # noexpression THEN
  62. Error(48, node^.usedInd^.position)
  63. END;
  64. | variable:
  65. Trace(" variable");
  66. LoadAddr(obj);
  67. Gens(LD);
  68. | procedure :
  69. Trace(" procedure");
  70. Error(21, node^.position)
  71. ELSE
  72. Error(202, node^.position)
  73. END
  74. END;
  75. | immediatevalue:
  76. Trace(" immediatevalue");
  77. Gen(LDI, 0, node^.immVal);
  78. | monadic:
  79. Trace(" monadic");
  80. CASE node^.monOpr OF
  81. odd:
  82. expression(node^.arg);
  83. Gens(ODDi)
  84. | neg:
  85. expression(node^.arg);
  86. Gens(NEGi)
  87. END
  88. | dyadic:
  89. Trace(" dyadic");
  90. expression(node^.leftArg);
  91. expression(node^.rightArg);
  92. CASE node^.dyOpr OF
  93. plus: Gens(ADDi)
  94. | minus: Gens(SUBi)
  95. | times: Gens(MULi)
  96. | divides: Gens(DIVi)
  97. | equal : Gens(EQ)
  98. | notequal: Gens(NE)
  99. | less: Gens(LT)
  100. | greaterequal: Gens(GE)
  101. | greater: Gens(GT)
  102. | lessequal: Gens(LE)
  103. | and: Gens(ANDb)
  104. | or: Gens(ORb)
  105. END;
  106. END;
  107. END expression;
  108. PROCEDURE statement(node: stmtPtr);
  109. VAR obj : Object;
  110. L0, L1 : Label;
  111. targ : exprPtr;
  112. strL : CARDINAL;
  113. str : STRING;
  114. BEGIN
  115. Trace("statement");
  116. CASE node^.kind OF
  117. nostatement: ;
  118. | assign:
  119. targ := node^.target;
  120. IF targ^.kind = identifier THEN
  121. obj := FindDecl(targ^.usedId, targ^.position);
  122. IF obj^.kind = variable THEN
  123. expression(node^.source);
  124. LoadAddr(obj);
  125. Gens(ST)
  126. ELSE
  127. Error(12, node^.position)
  128. END
  129. ELSE
  130. Error(110, targ^.position)
  131. END
  132. | call:
  133. obj := FindDecl(node^.callId, node^.position);
  134. IF obj^.kind = procedure THEN
  135. GenL(CALL, currLevel - obj^.level, obj^.procAdr)
  136. ELSE
  137. Error(15, node^.position)
  138. END;
  139. | stmtsequence:
  140. statement(node^.first);
  141. statement(node^.rest);
  142. | if:
  143. expression(node^.choice);
  144. L0 := GetNewLabel(); GenL(JMPC, 0, L0);
  145. statement(node^.thenPart);
  146. SetLabel(L0);
  147. | while:
  148. L0 := GetNewLabel(); SetLabel(L0);
  149. expression(node^.stop);
  150. L1 := GetNewLabel(); GenL(JMPC, 0, L1);
  151. statement(node^.doPart);
  152. GenL(JMP, 0, L0);
  153. SetLabel(L1)
  154. | read:
  155. IF node^.inVar^.kind = identifier THEN
  156. targ := node^.inVar;
  157. obj := FindDecl(targ^.usedId, targ^.position);
  158. IF obj^.kind = variable THEN
  159. Gens(INi);
  160. LoadAddr(obj);
  161. Gens(ST)
  162. ELSE
  163. Error(12, targ^.position)
  164. END
  165. ELSE
  166. Error(121, node^.position)
  167. END
  168. | write:
  169. IF node^.outVal^.kind = string THEN
  170. str := node^.outVal^.stringPtr;
  171. strL := 0;
  172. WHILE str^[strL] # 0C DO INC(strL) END;
  173. GenS(LDIs,strL, str);
  174. Gen (LDI, 0, strL);
  175. Gens(OUTc)
  176. ELSE
  177. expression(node^.outVal);
  178. Gens(OUTi)
  179. END
  180. ELSE
  181. Error(103, node^.position);
  182. END;
  183. END statement;
  184. PROCEDURE getTypeObject(tp: declPtr) : ObjType;
  185. VAR obj : Object;
  186. BEGIN
  187. Trace("getTypeObject");
  188. IF tp^.kind = typeident THEN
  189. obj := FindDecl(tp^.typeId, tp^.position);
  190. CASE obj^.kind OF
  191. simpleType:
  192. RETURN ObjType(obj)
  193. | undefined:
  194. Error(11, tp^.position);
  195. RETURN Undefined
  196. ELSE
  197. Error(37, tp^.position);
  198. RETURN Undefined
  199. END
  200. ELSE
  201. Error(104, tp^.position);
  202. RETURN Undefined
  203. END;
  204. END getTypeObject;
  205. PROCEDURE Block(root: blckPtr; L0: Label; currAddr: CARDINAL);
  206. (* L0 : label of first instruction of procedure body *)
  207. (* currAddr : data address (offset in current stack frame),
  208. the initial value contains the space for
  209. the block mark,
  210. that means: it is the address (offset) for the
  211. first local variable. *)
  212. PROCEDURE Declarations(node: declPtr);
  213. VAR obj : Object;
  214. BEGIN
  215. WITH node^ DO
  216. CASE kind OF
  217. nodeclaration: ;
  218. | declsequence:
  219. Trace('declsequence');
  220. Declarations(first);
  221. Declarations(rest);
  222. | constdecl:
  223. Trace('constdecl');
  224. obj := EnterDecl(constId, position);
  225. IF obj^.kind = newObject THEN
  226. obj^.kind := constant;
  227. obj^.cType := Integer;
  228. obj^.cVal := constVal
  229. END
  230. | vardecl:
  231. Trace('vardecl');
  232. obj := EnterDecl(varId, position);
  233. IF obj^.kind = newObject THEN
  234. obj^.kind := variable;
  235. obj^.vType := getTypeObject(varType);
  236. obj^.vAdr := currAddr;
  237. INC(currAddr)
  238. END
  239. | procdecl:
  240. Trace('procdecl');
  241. obj := EnterDecl(procId, position);
  242. IF obj^.kind = newObject THEN
  243. obj^.kind := procedure;
  244. obj^.procAdr := GetNewLabel();
  245. Block(node^.body, obj^.procAdr, 3)
  246. END
  247. END
  248. END
  249. END Declarations;
  250. BEGIN (* Block *)
  251. Trace( "Block");
  252. currLevel := EnterBlock();
  253. Trace('Declarations');
  254. Declarations (root^.declarations);
  255. SetLabel(L0);
  256. Gen(MSP, 0, currAddr); (* increment SP,
  257. skip space for block mark
  258. and local variables *)
  259. statement(root^.statements);
  260. Gens(RET);
  261. currLevel := LeaveBlock();
  262. END Block;
  263. PROCEDURE traverse(head: blckPtr);
  264. VAR L0 : Label;
  265. obj: Object;
  266. BEGIN
  267. SemanticError := FALSE;
  268. InitGenerator;
  269. currLevel := InitObjectTable();
  270. L0 := GetNewLabel(); GenL(JMP, 0, L0);
  271. Block(head, L0, 3);
  272. END traverse;
  273. BEGIN
  274. END Synthesis.