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

Deutsche Übersetzung

Sie haben gebeten, diese Seite auf Deutsch zu besuchen. Momentan ist nur die Oberfläche übersetzt, aber noch nicht der gesamte Inhalt.

Wenn Sie mir bei Übersetzungen helfen wollen, ist Ihr Beitrag willkommen. Alles, was Sie tun müssen, ist, sich auf der Website zu registrieren und mir eine Nachricht zu schicken, in der Sie gebeten werden, Sie der Gruppe der Übersetzer hinzuzufügen, die Ihnen die Möglichkeit gibt, die gewünschten Seiten zu übersetzen. Ein Link am Ende jeder übersetzten Seite zeigt an, dass Sie der Übersetzer sind und einen Link zu Ihrem Profil haben.

Vielen Dank im Voraus.

Dokument erstellt 05/10/2009, zuletzt geändert 28/10/2018
Quelle des gedruckten Dokuments:https://www.gaudry.be/de/sniplet-rf-lsd010/project/source/pcode.c.html

Die Infobro ist eine persönliche Seite, deren Inhalt in meiner alleinigen Verantwortung liegt. Der Text ist unter der CreativeCommons-Lizenz (BY-NC-SA) verfügbar. Weitere Informationen auf die Nutzungsbedingungen und dem Autor.