pcode.c

Description du code

Génération de p-code Compilateur LSD010

Code source ou contenu du fichier

  1. /*
  2.  * pcode.c : generation of p-code
  3.  * Part of the compiler project for LSD10 language
  4.  * Gaudry Stéphane
  5.  * More information on http://www.gaudry.be/langages-pcode.html
  6.  */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #if(VERBOSE_LEVEL<=DEB_E)
  10. #include <errno.h>
  11. #endif
  12.  
  13. #include "common.h"
  14. #include "y.tab.h"
  15.  
  16. /*
  17.  * **********************************************************
  18.  * Internal business implementations
  19.  * **********************************************************
  20.  */
  21.  
  22. extern int num_lines;
  23. extern char* yytext;
  24. extern int *yylineno;
  25.  
  26. extern AstNode *rootNode;
  27.  
  28. FILE* pcodeFile;
  29. #define RESERVED_MEM 5
  30. int pcodeGenValue(AstNode *node);
  31. /**
  32.  * Wrapper function to get location
  33.  * This calls table of symbols method, and compute shift for reserved memory
  34.  * Internal business
  35.  */
  36. int getShiftedMemoryLocation(AstNode *node)
  37. {
  38. if (node == NULL || !isSymbolsTableAvailable())
  39. {
  40. onError("AST node and Table of Symbols must not be NULL", __FILE__, __LINE__, node);
  41. //Failure of the compiler behavior, independent of the parsed code
  42. exit(EXIT_FAILURE);
  43. }
  44.  
  45. int location=INITIAL_INT;
  46. switch(node->type)
  47. {
  48. case LEXICAL_RETURN_STMT:
  49. location=RESERVED_MEM;
  50. break;
  51. case NODE_TYPE_FUNCTION_CALL:
  52. location = getDeclarationMemoryLocation(node)+RESERVED_MEM;
  53. location += node->info->scopeDepth>1?RESERVED_MEM:1;
  54. break;
  55. default:
  56. location = getDeclarationMemoryLocation(node);
  57. if(location<0)location=0;
  58. //if( node->info->scopeDepth>=1)location += RESERVED_MEM;
  59. break;
  60. }
  61. return location;
  62. }
  63. /**
  64.  * Returns the depth difference between the call node and the declaration node
  65.  * @see IHDCB332 séance 1.pdf "Laboratoire LSD010" slide 40
  66.  */
  67. int getDepthDiff(AstNode *node)
  68. {
  69. AstNode *declaration = getDeclaration(node);
  70. // printPCode(
  71. // pcodeFile,
  72. // ";\t%s depth %d, declaration depth=%d\n",
  73. // node->info->name,
  74. // node->info->scopeDepth,
  75. // declaration->info->scopeDepth
  76. // );
  77. int locationDiff = (node->info->scopeDepth - declaration->info->scopeDepth)-1;
  78.  
  79. return locationDiff<0?0:locationDiff;
  80. }
  81. void printLoad(int type, int depthDiff, int location)
  82. {
  83. switch(type)
  84. {
  85. case AST_INTEGER_VAR_TYPE:
  86. printPCode(pcodeFile, "lda i %d %d\n", depthDiff, location);
  87. break;
  88. case AST_BOOLEAN_VAR_TYPE:
  89. printPCode(pcodeFile, "lda b %d %d\n", depthDiff, location);
  90. break;
  91. case AST_INSTACK_VAR_TYPE:
  92. //@todo: by val, by address
  93. //printPCode(pcodeFile, "lda a %d %d\n", getDepthDiff(node), location+RESERVED_MEM);
  94. break;
  95. }
  96. }
  97. int pcodeGenAddress(AstNode *node)
  98. {
  99.  
  100. if (node == NULL)
  101. {
  102. return 0;
  103. }
  104. if(!isSymbolsTableAvailable())
  105. {
  106. onError("Table of Symbols must not be NULL", __FILE__, __LINE__, node);
  107. //Failure of the compiler behavior, independent of the parsed code
  108. exit(EXIT_FAILURE);
  109. }
  110.  
  111. // printPCode(pcodeFile, ";\tGenerate address for node %s\n", node->info->name);
  112.  
  113. int location;
  114. int depthDiff = 0;
  115. switch (node->type)
  116. {
  117. case NODE_TYPE_ID:
  118. location = getShiftedMemoryLocation(node);
  119. depthDiff=getDepthDiff(node);
  120. printPCode(pcodeFile, ";\tGenerate address for %s variable\n",node->info->name);
  121. printLoad(node->info->computedType, depthDiff, location+RESERVED_MEM);
  122. break;
  123. // case LEXICAL_RETURN_STMT:
  124. // printPCode(pcodeFile, ";\tStart generate address for return statement\n");
  125. // location = getShiftedMemoryLocation(node);
  126. // printLoad(node->info->computedType, depthDiff, location);
  127. // switch(node->info->computedType)
  128. // {
  129. // case AST_INTEGER_VAR_TYPE:
  130. // printPCode(pcodeFile, "ind i\n");
  131. // printPCode(pcodeFile, "sto i\n");
  132. // break;
  133. // case AST_BOOLEAN_VAR_TYPE:
  134. // printPCode(pcodeFile, "ind b\n");
  135. // printPCode(pcodeFile, "sto b\n");
  136. // break;
  137. // }
  138. // printPCode(pcodeFile, ";\tEnd generate address for return statement\n");
  139. // break;
  140. }
  141.  
  142. return 0;
  143. }
  144. /**
  145.  *
  146.  */
  147. void pcodeGenParam(AstNode *node)
  148. {
  149. // printPCode(
  150. // pcodeFile,
  151. // ";\tGenerate %s Parameter (compiler %s, %d)\n",
  152. // node->info->name,
  153. // __FILE__,
  154. // __LINE__
  155. // );
  156. switch(node->subtype)
  157. {
  158. case LEXICAL_VAR://NODE_DECL_PADR:
  159. pcodeGenAddress(node);
  160. break;
  161. default://case NODE_DECL_PVAL:
  162. pcodeGenValue(node);
  163. break;
  164. /*
  165. * case stack by val :
  166. * pcodeGenValue(node);
  167. * printPCode(pcodeFile, "ind a");
  168. */
  169. }
  170. }
  171. /**
  172.  * Recursive method to produce p-code from AST
  173.  */
  174. int pcodeGenValue(AstNode *node)
  175. {
  176. int location = INITIAL_INT;
  177. static int staticLabel = 0;
  178. int label = staticLabel;
  179. int rightLabel = INITIAL_INT;
  180. int leftLabel = INITIAL_INT;
  181.  
  182. staticLabel++;
  183.  
  184. if (node == NULL){
  185. return EXIT_SUCCESS;
  186. }
  187. if(!isSymbolsTableAvailable())
  188. {
  189. onError("Table of Symbols must not be NULL", __FILE__, __LINE__, NULL);
  190. //Failure of the compiler behavior, independent of the parsed code
  191. exit(EXIT_FAILURE);
  192. }
  193. char str[1024];//todo: minimize length
  194. #if(VERBOSE_LEVEL<=DEB_P)
  195. str,
  196. "pcodeGenValue %s (%d) (%s, line %d)",
  197. typeToString(node->type),
  198. node->type,
  199. node->debug->file,
  200. node->debug->line
  201. );
  202. printMsg(DEB_P, str, __FILE__, __LINE__);
  203. #endif
  204. // printPCode(pcodeFile, ";\tGenerate value for node %s\n", node->info->name);
  205.  
  206. // printf(
  207. // ";\n;\tp-code : %s (%s, %s) line %d col %d (compiler %s, %d)\n",
  208. // node->info->name,
  209. // typeToString(node->type),
  210. // typeToString(node->subtype),
  211. // node->debug->line,
  212. // node->debug->linePsn,
  213. // __FILE__,
  214. // __LINE__
  215. // );
  216. switch (node->type)
  217. {
  218. case NUMBER:
  219. printPCode(pcodeFile, ";\t---Generate value for %d integer constant\n",node->info->value);
  220. printPCode(pcodeFile, "ldc i %d\n", node->info->value);
  221. break;
  222. case LEXICAL_TRUE_VAL:
  223. printPCode(pcodeFile, ";\t---Generate value for true boolean constant\n");
  224. printPCode(pcodeFile, "ldc b 1\n");
  225. break;
  226. case LEXICAL_FALSE_VAL:
  227. printPCode(pcodeFile, ";\t---Generate value for false boolean constant\n",node->info->value);
  228. printPCode(pcodeFile, "ldc b 0\n");
  229. break;
  230. case NODE_TYPE_FUNCTIONS:
  231. //function
  232. pcodeGenValue(node->right);
  233. //functions
  234. pcodeGenValue(node->left);
  235. break;
  236.  
  237. case NODE_TYPE_FUNCTION:
  238. printPCode(pcodeFile, ";\tStart of %s function\n",node->info->name);
  239. location = getShiftedMemoryLocation(node);
  240.  
  241. printPCode(pcodeFile, "define @fct_%s_%d\n",node->info->name,location);
  242.  
  243. //int varsCount=getDeclarationsMemoryUpperBound();
  244. AstNode *arg = node->left;
  245. int varsCount=0;
  246. //get params count
  247. while(arg!=NULL)
  248. {
  249. switch(arg->type)
  250. {
  251. case NODE_TYPE_PARAM_LIST:
  252. varsCount++;
  253. arg=arg->right;
  254. break;
  255. case NODE_TYPE_PARAM:
  256. varsCount++;
  257. arg=NULL;
  258. break;
  259. default:
  260. arg=NULL;
  261. }
  262. }
  263. arg=node->right;
  264. //get declarations count
  265. while(arg!=NULL)
  266. {
  267. switch(arg->type)
  268. {
  269. case NODE_TYPE_CONTAINER:
  270. if(
  271. arg->left!=NULL &&
  272. (arg->left->type==NODE_TYPE_DECLARATIONS||arg->left->type==NODE_TYPE_VAR_DECL)
  273. )
  274. {
  275. arg=arg->left;
  276. }
  277. else
  278. {
  279. arg=NULL;
  280. }
  281. break;
  282. case NODE_TYPE_DECLARATIONS:
  283. if(arg->left!=NULL && arg->left->type==NODE_TYPE_VAR_DECL)
  284. {
  285. varsCount++;
  286. }
  287. arg=arg->right;
  288. break;
  289. case NODE_TYPE_VAR_DECL:
  290. varsCount++;
  291. arg=NULL;
  292. break;
  293. default:
  294. arg=NULL;
  295. }
  296. }
  297. printPCode(pcodeFile, "ssp %d\n",varsCount+RESERVED_MEM);
  298.  
  299. printPCode(pcodeFile, "ujp @fct_body_%s_%d\n",node->info->name, location);
  300. pcodeGenValue(node->left);
  301. printPCode(pcodeFile, "define @fct_body_%s_%d\n",node->info->name,location);
  302. printPCode(pcodeFile, "lda i %d %d\n", 0, 0);//args= {diff, rel addr} ??
  303. pcodeGenValue(node->right);
  304. if(node->info->returnStatement!=NULL)
  305. {
  306. printPCode(pcodeFile, ";\tReturn\n");
  307. // pcodeGenAddress(node->info->returnStatement);
  308. switch (node->info->returnStatement->info->computedType)
  309. {
  310. case AST_INTEGER_VAR_TYPE: printPCode(pcodeFile, "sto i\n"); break;
  311. case AST_BOOLEAN_VAR_TYPE: printPCode(pcodeFile, "sto b\n"); break;
  312. case AST_INSTACK_VAR_TYPE: printPCode(pcodeFile, "sto a\n"); break;
  313. default: onNotIntegerNotBooleanTypeError(node, __FILE__, __LINE__); break;
  314. }
  315. printPCode(pcodeFile, "retf\n");
  316. }
  317. printPCode(pcodeFile, "retf\n");
  318. printPCode(pcodeFile, ";\tEnd of %s function\n",node->info->name);
  319. break;
  320.  
  321. case NODE_TYPE_FUNCTION_CALL:
  322. {
  323. printPCode(pcodeFile, ";\t---%s function call\n",node->info->name);
  324. printPCode(pcodeFile, "mst %d\n", getDepthDiff(node));
  325.  
  326. AstNode *arg = node->left;
  327. int paramsCount=0;
  328. while(arg!=NULL)
  329. {
  330. switch(arg->type)
  331. {
  332. case NODE_TYPE_PARAM_LIST:
  333. pcodeGenParam(arg->left);
  334. paramsCount++;
  335. arg=arg->right;
  336. break;
  337. case NODE_TYPE_PARAM:
  338. pcodeGenParam(arg);
  339. paramsCount++;
  340. arg=NULL;
  341. break;
  342. default:
  343. // These types are the only allowed types for parameters
  344. // Must trigger an error here?
  345. arg=NULL;
  346. }
  347. }
  348. //
  349. printPCode(
  350. pcodeFile,
  351. "cup %d @fct_%s_%d\n",
  352. paramsCount,
  353. node->info->name,
  354. getShiftedMemoryLocation(node->info->declarationNode)
  355. );
  356. }
  357. break;
  358. case NODE_TYPE_REXP:
  359. // printf(
  360. // ";\n;\t*************tp-code %s =>%s=> %sline %d col %d (compiler %s, %d)\n",
  361. // node->left==NULL?"NULL":node->left->info->name,
  362. // typeToString(node->subtype),
  363. // node->right==NULL?"NULL":node->right->info->name,
  364. // node->debug->line,
  365. // node->debug->linePsn,
  366. // __FILE__,
  367. // __LINE__
  368. // );
  369. switch(node->subtype)
  370. {
  371. //Integer operations
  372. case LEXICAL_PLUS:
  373. printPCode(pcodeFile, ";\t---Start + operation\n");
  374. pcodeGenValue(node->left);
  375. pcodeGenValue(node->right);
  376. printPCode(pcodeFile, "add i\n");
  377. printPCode(pcodeFile, ";\t---Start + operation\n");
  378. break;
  379. case LEXICAL_MINUS:
  380. printPCode(pcodeFile, ";\t---Start - operation\n");
  381. pcodeGenValue(node->left);
  382. pcodeGenValue(node->right);
  383. printPCode(pcodeFile, "sub i\n");
  384. printPCode(pcodeFile, ";\t---Start - operation\n");
  385. break;
  386. case LEXICAL_MULT:
  387. printPCode(pcodeFile, ";\t---Start * operation\n");
  388. pcodeGenValue(node->left);
  389. pcodeGenValue(node->right);
  390. printPCode(pcodeFile, "mul i\n");
  391. printPCode(pcodeFile, ";\t---Start * operation\n");
  392. break;
  393. case LEXICAL_DIV:
  394. printPCode(pcodeFile, ";\t---Start DIV operation\n");
  395. pcodeGenValue(node->left);
  396. pcodeGenValue(node->right);
  397. printPCode(pcodeFile, "ldc i 0\n");
  398. printPCode(pcodeFile, "equ i\n");
  399. printPCode(pcodeFile, "fjp @div_%d\n", label);
  400. /* here left == 0 */
  401. printPCode(pcodeFile, ";\tdiv division by 0 !!\n");
  402. printPCode(pcodeFile, "stp\n");
  403. /* else left != 0 */
  404. printPCode(pcodeFile, ";\tbegin of div\n");
  405. printPCode(pcodeFile, "define @div_%d\n",label);
  406. label++;
  407. pcodeGenValue(node->right);
  408. printPCode(pcodeFile, "div i\n");
  409. printPCode(pcodeFile, ";\t---Start DIV operation\n");
  410. break;
  411. case LEXICAL_MOD:
  412. {
  413. printPCode(pcodeFile, ";\t---Start mod operation (b mod a)\n");
  414. int modLeft=5;
  415. int modRight=6;
  416.  
  417. printPCode(pcodeFile, "lda i 0 %d\n",modLeft);
  418. pcodeGenValue(node->right);
  419. printPCode(pcodeFile, "sto i\n");
  420. printPCode(pcodeFile, "lda i 0 %d\n",modRight);
  421. pcodeGenValue(node->left);
  422. printPCode(pcodeFile, "sto i\n");
  423.  
  424. printPCode(pcodeFile, ";\tchecks if b == 0\n");
  425. printPCode(pcodeFile, "lda i 0 %d\n",modLeft);
  426. printPCode(pcodeFile, "ind i\n");
  427. printPCode(pcodeFile, "ldc i 0\n");
  428. printPCode(pcodeFile, "equ i\n");
  429. printPCode(pcodeFile, "fjp @mod_%d\n", label);
  430. /* here left == 0 */
  431. printPCode(pcodeFile, ";\tmod division by 0 !!\n");
  432. printPCode(pcodeFile, "stp\n");
  433. /* else left != 0 */
  434. printPCode(pcodeFile, "define @mod_%d\n",label);
  435. label++;
  436.  
  437. //load left
  438. printPCode(pcodeFile, "lda i 0 %d\n",modRight);
  439. printPCode(pcodeFile, "ind i\n");
  440.  
  441. printPCode(pcodeFile, "lda i 0 %d\n",modRight);
  442. printPCode(pcodeFile, "ind i\n");
  443.  
  444. printPCode(pcodeFile, "lda i 0 %d\n",modLeft);
  445. printPCode(pcodeFile, "ind i\n");
  446. printPCode(pcodeFile, "div i\n");
  447.  
  448. printPCode(pcodeFile, "lda i 0 %d\n",modLeft);
  449. printPCode(pcodeFile, "ind i\n");
  450. printPCode(pcodeFile, "mul i\n");
  451. printPCode(pcodeFile, "sub i\n");
  452. printPCode(pcodeFile, ";\t---Start MOD operation\n");
  453. }
  454. break;
  455. //Boolean operations
  456. case LEXICAL_EQUALS:
  457. printPCode(pcodeFile, ";\t---Start == operation\n");
  458. pcodeGenValue(node->left);
  459. pcodeGenValue(node->right);
  460. printPCode(pcodeFile, "equ b\n");
  461. printPCode(pcodeFile, ";\t---Start == operation\n");
  462. break;
  463. case LEXICAL_LESS_EQUALS:
  464. printPCode(pcodeFile, ";\t---Start <= operation\n");
  465. pcodeGenValue(node->left);
  466. pcodeGenValue(node->right);
  467. printPCode(pcodeFile, "leq b\n");
  468. printPCode(pcodeFile, ";\t---Start <= operation\n");
  469. break;
  470. case LEXICAL_LESS:
  471. printPCode(pcodeFile, ";\t---Start < operation\n");
  472. pcodeGenValue(node->left);
  473. pcodeGenValue(node->right);
  474. printPCode(pcodeFile, "les b\n");
  475. printPCode(pcodeFile, ";\t---Start < operation\n");
  476. break;
  477. case LEXICAL_ANDLAZY:
  478. printPCode(pcodeFile, ";\t---Start & operation\n");
  479. leftLabel = staticLabel++;
  480. rightLabel = staticLabel++;
  481.  
  482. pcodeGenValue(node->left);
  483.  
  484. //set condition for the false jump(exp_1)
  485. pcodeGenValue(node->left);
  486.  
  487. char andLazy[7+1] = "andLazy";
  488.  
  489. printPCode(pcodeFile, "fjp @%s%d\n", andLazy, leftLabel);
  490. pcodeGenValue(node->right);
  491. printPCode(pcodeFile, "and b\n");
  492.  
  493. printPCode(pcodeFile, "define @%s%d\n", andLazy, leftLabel);
  494. printPCode(pcodeFile, ";\t---Start & operation\n");
  495. break;
  496. case LEXICAL_AND:
  497. printPCode(pcodeFile, ";\t---Start && operation\n");
  498. pcodeGenValue(node->right);
  499. pcodeGenValue(node->left);
  500. printPCode(pcodeFile, "and b\n");
  501. printPCode(pcodeFile, ";\t---Start && operation\n");
  502. break;
  503. case LEXICAL_ORLAZY:
  504. printPCode(pcodeFile, ";\t---Start | operation\n");
  505. leftLabel = staticLabel++;
  506. rightLabel = staticLabel++;
  507.  
  508. pcodeGenValue(node->left);
  509.  
  510. //set condition for the false jump(exp_1)
  511. pcodeGenValue(node->left);
  512. printPCode(pcodeFile, "not b\n");
  513.  
  514. char orLazy[6+1] = "orLazy";
  515.  
  516. printPCode(pcodeFile, "fjp @%s%d\n", orLazy, leftLabel);
  517. pcodeGenValue(node->right);
  518. printPCode(pcodeFile, "or b\n");
  519.  
  520. printPCode(pcodeFile, "define @%s%d\n", orLazy, leftLabel);
  521. printPCode(pcodeFile, ";\t---Start | operation\n");
  522. break;
  523. case LEXICAL_OR:
  524. printPCode(pcodeFile, ";\t---Start || operation\n");
  525. pcodeGenValue(node->right);
  526. pcodeGenValue(node->left);
  527. printPCode(pcodeFile, "or b\n");
  528. printPCode(pcodeFile, ";\t---Start || operation\n");
  529. break;
  530. case LEXICAL_NOT:
  531. printPCode(pcodeFile, ";\t---NOT operation\n");
  532. pcodeGenValue(node->right);
  533. printPCode(pcodeFile, "not b\n");
  534. break;
  535. case LEXICAL_ISEMPTY_OPS :
  536. printPCode(pcodeFile, "ldc b 1\n");
  537. break;
  538. default:
  539. pcodeGenValue(node->right);
  540. pcodeGenValue(node->left);
  541. break;
  542. }
  543. break;
  544. case NODE_TYPE_PARAM_DECL:
  545. {
  546. printPCode(pcodeFile, ";\t---Start %s param declaration\n",node->info->name);
  547. char nodeArgType[1+1];//because I have some problems with %c on printPCode
  548. char *pnodeArgType = nodeArgType;
  549. switch(node->info->computedType)
  550. {
  551. case AST_INTEGER_VAR_TYPE:
  552. pnodeArgType="i";
  553. break;
  554. case AST_BOOLEAN_VAR_TYPE:
  555. pnodeArgType="b";
  556. break;
  557. case AST_INSTACK_VAR_TYPE:
  558. pnodeArgType="a";
  559. break;
  560. default:
  561. onNotIntegerNotBooleanTypeError(node, __FILE__, __LINE__);
  562. break;
  563. }
  564. char varInst[3+1];
  565. char *varInstp=varInst;
  566. if( node->subtype==LEXICAL_VAR)
  567. {
  568. varInstp="lda";
  569. }
  570. else if( node->subtype==ID)
  571. {
  572. varInstp="lod";
  573. pnodeArgType="a";
  574. }
  575. else
  576. {
  577. str,
  578. "Unsupported subtype %s (%d) for %s, only %s or %s are allowed (%s, line %d)",
  579. typeToString(node->subtype),
  580. node->type,
  581. node->info->name,
  582. typeToString(LEXICAL_VAR),
  583. typeToString(ID),
  584. node->debug->file,
  585. node->debug->line
  586. );
  587. onError(str, __FILE__, __LINE__, node);
  588. //Failure of the compiler behavior, independent of the parsed code
  589. exit(EXIT_FAILURE);
  590. }
  591. printPCode(pcodeFile, "%s %s %d %d\n", varInstp, pnodeArgType, getDepthDiff(node), getShiftedMemoryLocation(node));
  592. printPCode(pcodeFile, "ind %s\n", pnodeArgType);
  593. printPCode(pcodeFile, ";\t---End of %s param declaration\n",node->info->name);
  594. }
  595. break;
  596. case NODE_TYPE_ID:
  597. printPCode(pcodeFile, ";\t---%s id\n",node->info->name);
  598.  
  599. pcodeGenAddress(node);
  600. switch (node->info->computedType)
  601. {
  602. case AST_INTEGER_VAR_TYPE: printPCode(pcodeFile, "ind i\n"); break;
  603. case AST_BOOLEAN_VAR_TYPE: printPCode(pcodeFile, "ind b\n"); break;
  604. case AST_INSTACK_VAR_TYPE: printPCode(pcodeFile, "ind a\n"); break;
  605. default: onNotIntegerNotBooleanTypeError(node, __FILE__, __LINE__); break;
  606. }
  607. break;
  608. // case LEXICAL_RETURN_STMT:
  609. // break;
  610. case NODE_TYPE_STATEMENT:
  611. switch(node->subtype)
  612. {
  613. case LEXICAL_AFFECTATION:
  614. printPCode(pcodeFile, ";\t---Start affectation\n");
  615. pcodeGenAddress(node->left);
  616.  
  617. //printPCode(pcodeFile, ";\tAFFECT right %d--%d\n",node->right->type,node->right->subtype);
  618. pcodeGenValue(node->right);
  619.  
  620. switch (node->right->info->computedType)
  621. {
  622. case AST_INTEGER_VAR_TYPE: printPCode(pcodeFile, "sto i\n"); break;
  623. case AST_BOOLEAN_VAR_TYPE: printPCode(pcodeFile, "sto b\n"); break;
  624. case AST_INSTACK_VAR_TYPE: printPCode(pcodeFile, "sto a\n"); break;
  625. default: onNotIntegerNotBooleanTypeError(node, __FILE__, __LINE__); break;
  626. }
  627.  
  628. printPCode(pcodeFile, ";\tEnd of affectation\n");
  629. break;
  630. //Flow control operations
  631. case LEXICAL_IF_STMT:
  632. printPCode(pcodeFile, ";\t---Start if statement\n");
  633. leftLabel = staticLabel++;
  634. rightLabel = staticLabel++;
  635.  
  636. //set condition for the false jump
  637. pcodeGenValue(node->left);
  638. printPCode(pcodeFile, "fjp @endif_%d\n", leftLabel);
  639.  
  640. pcodeGenValue(node->right);
  641. printPCode(pcodeFile, "define @endif_%d\n", leftLabel);
  642. printPCode(pcodeFile, ";\t---End of if statement\n");
  643. break;
  644. case AST_IF_ELSE_STMT:
  645. printPCode(pcodeFile, ";\t---Start if...else... statement\n");
  646. leftLabel = staticLabel++;
  647. rightLabel = staticLabel++;
  648.  
  649. //set condition for the false jump
  650. pcodeGenValue(node->left);
  651. printPCode(pcodeFile, "fjp @then_%d\n", leftLabel);
  652.  
  653. pcodeGenValue(node->right->left);
  654. printPCode(pcodeFile, "ujp @endif_%d\n", rightLabel);
  655.  
  656. printPCode(pcodeFile, "define @then_%d\n", leftLabel);
  657. pcodeGenValue(node->right->right);
  658. printPCode(pcodeFile, "define @endif_%d\n", rightLabel);
  659. printPCode(pcodeFile, ";\t---End of if...else... statement\n");
  660. break;
  661. case LEXICAL_FOR_STMT:
  662. printPCode(pcodeFile, ";\t---Start for statement\n");
  663. // for(pre_instructions:condition:post_instructions_loop){instructions_loop}
  664. // is translated into
  665. // pre_instructions; while(condition){instructions_loop;post_instructions_loop}
  666.  
  667. leftLabel = staticLabel++;
  668. rightLabel = staticLabel++;
  669.  
  670. // pre_instructions
  671. if(node->right!=NULL && node->right->left!=NULL)
  672. {
  673. //printf("\n; FLEXICAL_OR statement pre_instructions (compiler %s, %d)",__FILE__,__LINE__);
  674. pcodeGenValue(node->right->left->left);
  675. }
  676.  
  677. // while
  678. printPCode(pcodeFile, "define @for_%d\n", leftLabel);
  679.  
  680. //set condition for the false jump
  681. pcodeGenValue(node->left);
  682. printPCode(pcodeFile, "fjp @endfor_%d\n", rightLabel);
  683.  
  684. // instructions_loop
  685. if(node->right!=NULL)
  686. {
  687. //printf("\n; FLEXICAL_OR statement instructions_loop (compiler %s, %d)",__FILE__,__LINE__);
  688. pcodeGenValue(node->right->right);
  689. }
  690. // post_instructions_loop
  691. if(node->right!=NULL && node->right->left!=NULL)
  692. {
  693. //printf("\n; FLEXICAL_OR statement post_instructions_loop (compiler %s, %d)",__FILE__,__LINE__);
  694. pcodeGenValue(node->right->left->right);
  695. }
  696. printPCode(pcodeFile, "ujp @for_%d\n", leftLabel);
  697. printPCode(pcodeFile, "define @endfor_%d\n", rightLabel);
  698. printPCode(pcodeFile, ";\t---End of for statement\n");
  699. break;
  700. case LEXICAL_WHILE_STMT:
  701. printPCode(pcodeFile, ";\t---Start while statement\n");
  702. leftLabel = staticLabel++;
  703. rightLabel = staticLabel++;
  704.  
  705. printPCode(pcodeFile, "define @while_%d\n", leftLabel);
  706.  
  707. //set condition for the false jump
  708. pcodeGenValue(node->left);
  709. printPCode(pcodeFile, "fjp @endwhile_%d\n", rightLabel);
  710.  
  711. pcodeGenValue(node->right);
  712. printPCode(pcodeFile, "ujp @while_%d\n", leftLabel);
  713. printPCode(pcodeFile, "define @endwhile_%d\n", rightLabel);
  714. printPCode(pcodeFile, ";\t---End of while statement\n");
  715. break;
  716. default:
  717. pcodeGenValue(node->right);
  718. pcodeGenValue(node->left);
  719. break;
  720. }
  721. break;
  722. case LEXICAL_READ_OPS:
  723. printPCode(pcodeFile, ";\t---Start read operation\n");
  724. pcodeGenAddress(node->right);
  725. printPCode(pcodeFile, "read\n");
  726. //Only integer argument allowed for read (Spec. 6.2)
  727. printPCode(pcodeFile, "sto i\n");
  728. printPCode(pcodeFile, ";\t---End of read operation\n");
  729. break;
  730. case LEXICAL_WRITE_OPS:
  731. printPCode(pcodeFile, ";\t---Start write operation\n");
  732. pcodeGenValue(node->right);
  733. printPCode(pcodeFile, "prin\n");
  734. printPCode(pcodeFile, ";\t---End of write operation\n");
  735. break;
  736.  
  737. // case NODE_TYPE_CONTAINER:
  738. // case NODE_TYPE_FUNCTION_BODY:
  739. // case NODE_TYPE_DECLARATIONS:
  740. // pcodeGenValue(node->left);
  741. // pcodeGenValue(node->right);
  742. // break;
  743. default:
  744. pcodeGenValue(node->left);
  745. pcodeGenValue(node->right);
  746. //onUnrecognizedTypeError(node->type, __FILE__, __LINE__);
  747. break;
  748. }
  749.  
  750. return EXIT_SUCCESS;
  751. }
  752.  
  753. /*
  754.  * **********************************************************
  755.  * Implementation of the header exposed items
  756.  * See pcode.h for these functions comments
  757.  * **********************************************************
  758.  */
  759.  
  760. int generatePCode()
  761. {
  762. if(rootNode==NULL)
  763. {
  764. //To check : Meaning of a null node, is it an error or only a warning?
  765. onError("Root node may not be null", __FILE__, __LINE__, NULL);
  766. return EXIT_FAILURE;
  767. }
  768. if(!isSymbolsTableAvailable())
  769. {
  770. onError("Table of Symbols must not be NULL", __FILE__, __LINE__, NULL);
  771. //Failure of the compiler behavior, independent of the parsed code
  772. exit(EXIT_FAILURE);
  773. }
  774.  
  775.  
  776. #if(PCODE_FILE_REQUESTED)
  777. if(!(pcodeFile = fopen(PCODE_FILE, "w")))
  778. {
  779. #if(VERBOSE_LEVEL<=DEB_EXEC)
  780. printMsg(DEB_EXEC,"Open p-code file...ERRLEXICAL_OR", __FILE__, __LINE__);
  781. printMsg(DEB_E, (char *)strerror(errno), __FILE__, __LINE__);
  782. #endif
  783. }else
  784. {
  785. #if(VERBOSE_LEVEL<=DEB_EXEC)
  786. "\n; Open %s p-code file...OK\n",
  787. PCODE_FILE,
  788. __FILE__,
  789. __LINE__
  790. );
  791. #endif
  792. }
  793.  
  794. #endif
  795.  
  796. printPCode(pcodeFile, ";\tStart program\n");
  797. // int maxMem = getDeclarationsMemoryUpperBound();
  798. // printPCode(pcodeFile, "ssp %d\n", (maxMem<= 0) ? 0 : maxMem );
  799. printPCode(pcodeFile, "ssp 0\n");
  800.  
  801. printPCode(pcodeFile, "mst 0\n");
  802.  
  803. int mainMemLoc = getShiftedMemoryLocation(getMain());
  804. printPCode(pcodeFile, "cup 0 @fct_%s_%d\n", getMain()->info->name, mainMemLoc);
  805. printPCode(pcodeFile, "ujp @program_end\n");
  806. int ret = pcodeGenValue(rootNode);
  807.  
  808. printPCode(pcodeFile, "define @program_end\n");
  809. printPCode(pcodeFile, "stp\n");
  810. printPCode(pcodeFile, ";\tEnd of program\n");
  811.  
  812. if(PCODE_FILE_REQUESTED && pcodeFile!=NULL)
  813. {
  814. fclose(pcodeFile);
  815. }
  816. #if(VERBOSE_LEVEL<=DEB_P)
  817. printSymbolsTableDebug(__FILE__,__LINE__);
  818. #endif
  819. return ret;
  820. }

Autres extraits de codes en c

  • DisquetteDispo Vérifier la disponibilité du lecteur de disquette
  • Suite de Fibonacci Exemple d'itération en C
  • Suite de Fibonacci Exemple de récursion en C
  • astDataRepresentation.h Représentation de données de l'arbre syntaxique abstrait Compilateur LSD010
  • ast.h Arbre syntaxique abstrait Compilateur LSD010
  • ast.c Arbre syntaxique abstrait Compilateur LSD010
  • symbolsTableDataRepresentation.h Représentation de données de la table des symboles Compilateur LSD010
  • symbolsTable.h Fonctions de gestion de la table des symboles Compilateur LSD010
  • symbolsTable.c Fonctions de gestion de la table des symboles Compilateur LSD010
  • hashCode.h Fonctions de hachage Compilateur LSD010
  • hashCode.c Fonctions de hachage Compilateur LSD010
  • scopeStack.h Fonctions de gestion d'une pile de portées Compilateur LSD010
  • scopeStack.c Fonctions de gestion d'une pile de portées Compilateur LSD010
  • scopeHelper.h Fonctions de gestion de la portée courante Compilateur LSD010
  • console.h Fonctions d'affichage Compilateur LSD010
  • console.c Fonctions d'affichage Compilateur LSD010
  • graphVizHelper.h Génération d'une image d'un arbre syntaxique abstrait.
    Classe d'intégration de l'outil GraphViz. Compilateur LSD010
  • graphVizHelper.c Génération d'une image d'un arbre syntaxique abstrait.
    Classe d'intégration de l'outil GraphViz. Compilateur LSD010
  • common.h Définition des constantes et variables communes Compilateur LSD010
  • pcode.c Génération de p-code Compilateur LSD010
  • pcode.h Génération de p-code Compilateur LSD010
  • Tous les extraits

Document créé le 05/10/2009, dernière modification le 28/10/2018
Source du document imprimé : https://www.gaudry.be/sniplet-rf-lsd010/project/source/pcode.c.html

L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.