parser_cglut.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. #include "parser.h"
  2. #include "stdlib.h"
  3. #include "stdio.h"
  4. #include "symtable.h"
  5. #include "struct_table.h"
  6. #include <string.h>
  7. #include "file_op.h"
  8. #include <errno.h>
  9. #include "agc_commands.h"
  10. static void print_command_definition(FILE *fd, struct ast_node *n);
  11. static void print_command_definitionClassFunction(FILE *fd, struct ast_node *n, const char *classname);
  12. static void print_command_functionArguments(FILE *fd, struct ast_node *n, int beginWithSemicolon);
  13. static void print_command_class(FILE *fd, struct ast_node *n);
  14. static void print_command_native(FILE *fd, struct ast_node *n);
  15. static void print_command_classFunction(FILE *fd, struct ast_node *n);
  16. static void print_command_function(FILE *fd, struct ast_node *n);
  17. static void print_command_custom(FILE *fd, struct ast_node *n);
  18. static void print_command_echo(FILE *fd, struct ast_node *n);
  19. static void print_command_if(FILE *fd, struct ast_node *n);
  20. static void print_command_for(FILE *fd, struct ast_node *n);
  21. static void print_command_multistring(FILE *fd, struct ast_node *n);
  22. static void print_command_return(FILE *fd, struct ast_node *n);
  23. static void print_command_groupStatements(FILE *fd, struct ast_node *n);
  24. static void print_binaryOperation(FILE *fd, struct ast_node *n);
  25. static void print_identifierReference(FILE *fd, struct ast_node *n, int skipLast);
  26. static void print_identifier(FILE *fd, struct ast_node *n, int skipLast);
  27. static void print_number(FILE *fd, struct ast_node *n);
  28. static void print_float(FILE *fd, struct ast_node *n);
  29. static void print_node(FILE *fd, struct ast_node *n);
  30. static int getIdentifierChainCount(struct ast_node *n);
  31. static struct ast_node *getIdentifierLast(struct ast_node *n);
  32. static struct ast_node *getIdentifierInChain(struct ast_node *n, int position);
  33. static struct ast_node *getIdentifierInChain(struct ast_node *n, int position) {
  34. if (position == 0) {
  35. return n;
  36. }
  37. for (int i = 0; i < n->children.elements; i++) {
  38. struct ast_node *child = dd_da_get(&n->children, i);
  39. if (child->node_type == AST_IDENTIFIER) {
  40. return getIdentifierInChain(child, position-1);
  41. }
  42. }
  43. return n;
  44. }
  45. static void print_command_groupStatements(FILE *fd, struct ast_node *n) {
  46. if (n->node_type == AST_COMMAND_NATIVE && strcmp(n->lex, "group") == 0) {
  47. for (unsigned int i = 0; i < n->children.elements; i++) {
  48. print_node(fd, dd_da_get(&n->children, i));
  49. fprintf(fd, ";\n");
  50. }
  51. }
  52. else {
  53. print_node(fd, n);
  54. fprintf(fd, ";\n");
  55. }
  56. }
  57. static void print_command_return(FILE *fd, struct ast_node *n) {
  58. fprintf(fd, "return ");
  59. for (int i = 0; i < n->children.elements; i++) {
  60. struct ast_node *child = dd_da_get(&n->children, i);
  61. print_node(fd, child);
  62. }
  63. }
  64. static void print_command_multistring(FILE *fd, struct ast_node *n) {
  65. for (int i = 0; i < n->children.elements; i++) {
  66. struct ast_node *string = dd_da_get(&n->children, i);
  67. print_node(fd, string);
  68. }
  69. }
  70. static void print_command_for(FILE *fd, struct ast_node *n) {
  71. struct ast_node *definition = dd_da_get(&n->children, 0);
  72. struct ast_node *condition = dd_da_get(&n->children, 1);
  73. struct ast_node *step = dd_da_get(&n->children, 2);
  74. struct ast_node *statements = dd_da_get(&n->children, 3);
  75. fprintf(fd, "for (");
  76. print_node(fd, definition);
  77. print_node(fd, condition);
  78. fprintf(fd, ";");
  79. print_node(fd, step);
  80. fprintf(fd, ") {\n");
  81. print_command_groupStatements(fd, statements);
  82. fprintf(fd, "}");
  83. }
  84. static void print_command_if(FILE *fd, struct ast_node *n) {
  85. for (int i = 0; i < n->children.elements; i += 2) {
  86. struct ast_node *child1 = dd_da_get(&n->children, i);
  87. struct ast_node *child2 = 0;
  88. if (i+1 < n->children.elements) {
  89. child2 = dd_da_get(&n->children, i+1);
  90. }
  91. if (i != 0) {
  92. fprintf(fd, "else\n");
  93. }
  94. if (child2) {
  95. fprintf(fd, "if (");
  96. print_node(fd, child1);
  97. fprintf(fd, ") {\n");
  98. print_command_groupStatements(fd, child2);
  99. fprintf(fd, "}\n");
  100. }
  101. else {
  102. fprintf(fd, "{\n");
  103. print_command_groupStatements(fd, child1);
  104. fprintf(fd, "}\n");
  105. }
  106. }
  107. }
  108. static void print_command_echo(FILE *fd, struct ast_node *n) {
  109. fprintf(fd, "printf(\"");
  110. for (int i = 0; i < n->children.elements; i++) {
  111. struct ast_node *child = dd_da_get(&n->children, i);
  112. if (child->node_type == AST_STRING) {
  113. fprintf(fd, "%%s");
  114. }
  115. else
  116. if (child->node_type == AST_NUMBER) {
  117. fprintf(fd, "%%d");
  118. }
  119. else
  120. if (child->node_type == AST_FLOAT) {
  121. fprintf(fd, "%%f");
  122. }
  123. else
  124. if (child->node_type == AST_IDENTIFIER
  125. && child->value == DD_VARIABLE_TYPE_INT) {
  126. fprintf(fd, "%%d");
  127. }
  128. else
  129. if (child->node_type == AST_IDENTIFIER
  130. && child->value == DD_VARIABLE_TYPE_FLOAT) {
  131. fprintf(fd, "%%f");
  132. }
  133. else {
  134. printf("unable to parse argument in echo '%s(%d)', no rule to parse it (1)\n",
  135. child->lex, child->value);
  136. exit(-1);
  137. }
  138. }
  139. fprintf(fd, "\\n\"");
  140. for (int i = 0; i < n->children.elements; i++) {
  141. struct ast_node *child = dd_da_get(&n->children, i);
  142. fprintf(fd, ", ");
  143. if (child->node_type == AST_STRING) {
  144. fprintf(fd, "\"%s\"", child->lex);
  145. }
  146. else
  147. if (child->node_type == AST_NUMBER) {
  148. fprintf(fd, "%d", child->value);
  149. }
  150. else
  151. if (child->node_type == AST_FLOAT) {
  152. fprintf(fd, "%f", child->fvalue);
  153. }
  154. else
  155. if (child->node_type == AST_IDENTIFIER
  156. && child->value == DD_VARIABLE_TYPE_INT) {
  157. fputs(child->lex, fd);
  158. }
  159. else
  160. if (child->node_type == AST_IDENTIFIER
  161. && child->value == DD_VARIABLE_TYPE_FLOAT) {
  162. fputs(child->lex, fd);
  163. }
  164. else {
  165. printf("unable to parse argument in echo '%s(%d)', no rule to parse it (2)\n",
  166. child->lex, child->value);
  167. exit(-1);
  168. }
  169. }
  170. fprintf(fd, ");\n");
  171. }
  172. static void print_binaryOperation(FILE *fd, struct ast_node *n) {
  173. struct ast_node *child1 = dd_da_get(&n->children, 0);
  174. if (strcmp(n->lex, "=") != 0) {
  175. fprintf(fd, "(");
  176. }
  177. if (strcmp(n->lex, "=") == 0) {
  178. print_identifier(fd, child1, 0);
  179. }
  180. else {
  181. print_node(fd, child1);
  182. }
  183. fprintf(fd, " ");
  184. for (int i = 1; i < n->children.elements; i++) {
  185. struct ast_node *child = dd_da_get(&n->children, i);
  186. fprintf(fd, "%s ", n->lex);
  187. print_node(fd, child);
  188. }
  189. if (strcmp(n->lex, "=") != 0) {
  190. fprintf(fd, ")");
  191. }
  192. }
  193. static void print_command_custom(FILE *fd, struct ast_node *n) {
  194. struct ast_node *cmdname = dd_da_get(&n->children, 0);
  195. print_identifier(fd, cmdname, 0);
  196. fprintf(fd, "(");
  197. int hasArgs = 0;
  198. if (strcmp(cmdname->lex, "this") == 0) {
  199. int chainCount = getIdentifierChainCount(cmdname);
  200. struct ast_node *semilast = getIdentifierInChain(cmdname, chainCount-1);
  201. // not dereferencing "this" hack
  202. if (chainCount-1 > 0 && !semilast->isRef) {
  203. fprintf(fd, "&");
  204. }
  205. print_identifier(fd, cmdname, 1);
  206. hasArgs = 1;
  207. }
  208. for (int i = 1; i < n->children.elements; i++) {
  209. struct ast_node *child = dd_da_get(&n->children, i);
  210. if (hasArgs) {
  211. fprintf(fd, ", ");
  212. }
  213. hasArgs = 1;
  214. print_node(fd, child);
  215. }
  216. fprintf(fd, ")");
  217. }
  218. static void print_command_function(FILE *fd, struct ast_node *n) {
  219. struct ast_node *functype = dd_da_get(&n->children, 0);
  220. struct ast_node *funcname = dd_da_get(&n->children, 1);
  221. struct ast_node *funcargs = dd_da_get(&n->children, 2);
  222. struct ast_node *funcstatements = 0;
  223. if (n->children.elements == 4) {
  224. funcstatements = dd_da_get(&n->children, 3);
  225. }
  226. // print function signature and args
  227. fprintf(fd, "%s %s(", functype->lex, funcname->lex);
  228. print_command_functionArguments(fd, funcargs, 1);
  229. fprintf(fd, ") {\n");
  230. if (funcstatements) {
  231. print_command_groupStatements(fd, funcstatements);
  232. }
  233. fprintf(fd, "}\n");
  234. // `dd_gameInit` is the "main" function, where everything begins
  235. if (strcmp(funcname->lex, "dd_gameInit") == 0) {
  236. fprintf(fd, "int main(int argc, char *argv[]) {dd_main(argc, argv);}\n");
  237. }
  238. }
  239. static void print_command_classFunction(FILE *fd, struct ast_node *n) {
  240. struct ast_node *classname = dd_da_get(&n->children, 0);
  241. struct ast_node *function = dd_da_get(&n->children, 1);
  242. struct ast_node *functype = dd_da_get(&function->children, 0);
  243. struct ast_node *funcname = dd_da_get(&function->children, 1);
  244. struct ast_node *funcargs = dd_da_get(&function->children, 2);
  245. struct ast_node *funcstatements = dd_da_get(&function->children, 3);
  246. int structIndex = struct_table_get_index(classname->lex);
  247. // print function signature and args
  248. fprintf(fd, "%s %s_%s(struct %s *this", functype->lex, classname->lex,
  249. funcname->lex, classname->lex);
  250. print_command_functionArguments(fd, funcargs, 1);
  251. fprintf(fd, ") {\n");
  252. // create functions are special
  253. if (strcmp(funcname->lex, "create") == 0) {
  254. // subclass init
  255. int subclassIndex = struct_table_get_parent(structIndex);
  256. if (subclassIndex >= 0) {
  257. fprintf(fd, "%s_%s(this);\n", struct_table_get_name(subclassIndex),
  258. funcname->lex);
  259. }
  260. // prepare functions
  261. for (int i = 0; i < struct_table_get_member_total(structIndex); i++) {
  262. if (struct_table_get_member_type(structIndex, i) == DD_VARIABLE_TYPE_FUNCTION) {
  263. const char *memberFuncname = struct_table_get_member_name(structIndex, i);
  264. int parentDepth = struct_table_is_member_parent(structIndex, memberFuncname);
  265. fprintf(fd, "this->");
  266. for (int j = 0; j < parentDepth; j++) {
  267. fprintf(fd, "parent.");
  268. }
  269. fprintf(fd, "%s = %s_%s;\n", memberFuncname, classname->lex, memberFuncname);
  270. }
  271. }
  272. // initialise structs
  273. for (int i = 0; i < struct_table_get_member_total(structIndex); i++) {
  274. if (struct_table_get_member_type(structIndex, i) == DD_VARIABLE_TYPE_STRUCT) {
  275. const char *memberName = struct_table_get_member_name(structIndex, i);
  276. char *memberType = struct_table_get_member_nametype(structIndex, i);
  277. int arrayCount = struct_table_getMemberArrayCount(structIndex, i);
  278. int isRef = struct_table_getMemberIsRef(structIndex, i);
  279. if (isRef) continue;
  280. if (arrayCount > 1) {
  281. fprintf(fd, "for (int i = 0; i < %d; i++) {\n", arrayCount);
  282. fprintf(fd, " %s_create(&this->%s[i]);\n", memberType, memberName);
  283. fprintf(fd, "}\n");
  284. }
  285. else {
  286. fprintf(fd, "%s_create(&this->%s);\n", memberType, memberName);
  287. }
  288. //int parentDepth = struct_table_is_member_parent(structIndex, memberName);
  289. }
  290. }
  291. }
  292. else
  293. // `clean` function cleans all structs
  294. if (strcmp(funcname->lex, "clean") == 0) {
  295. // initialise structs
  296. for (int i = 0; i < struct_table_get_member_total(structIndex); i++) {
  297. if (struct_table_get_member_type(structIndex, i) == DD_VARIABLE_TYPE_STRUCT) {
  298. const char *memberName = struct_table_get_member_name(structIndex, i);
  299. char *memberType = struct_table_get_member_nametype(structIndex, i);
  300. //int parentDepth = struct_table_is_member_parent(structIndex, memberName);
  301. int isRef = struct_table_getMemberIsRef(structIndex, i);
  302. if (isRef) continue;
  303. fprintf(fd, "%s_clean(&this->%s);\n", memberType, memberName);
  304. }
  305. }
  306. }
  307. // print function statements
  308. print_command_groupStatements(fd, funcstatements);
  309. fprintf(fd, "}\n");
  310. }
  311. static int getIdentifierChainCount(struct ast_node *n) {
  312. for (int i = 0; i < n->children.elements; i++) {
  313. struct ast_node *child = dd_da_get(&n->children, i);
  314. if (child->node_type == AST_IDENTIFIER) {
  315. return getIdentifierChainCount(child) +1;
  316. }
  317. }
  318. return 0;
  319. }
  320. static struct ast_node *getIdentifierLast(struct ast_node *n) {
  321. for (int i = 0; i < n->children.elements; i++) {
  322. struct ast_node *child = dd_da_get(&n->children, i);
  323. if (child->node_type == AST_IDENTIFIER) {
  324. return getIdentifierLast(child);
  325. }
  326. }
  327. return n;
  328. }
  329. static void print_identifierReference(FILE *fd, struct ast_node *n, int skipLast) {
  330. // check if reference is needed
  331. struct ast_node *last = getIdentifierLast(n);
  332. if (last->value == DD_VARIABLE_TYPE_STRUCT
  333. && !last->isRef) {
  334. fprintf(fd, "&");
  335. }
  336. // print identifier
  337. print_identifier(fd, n, skipLast);
  338. }
  339. static void print_identifier(FILE *fd, struct ast_node *n, int skipLast) {
  340. fprintf(fd, "%s", n->lex);
  341. for (int i = 0; i < n->children.elements; i++) {
  342. struct ast_node *child = dd_da_get(&n->children, i);
  343. // has array
  344. if (child->node_type == AST_GROUP) {
  345. fprintf(fd, "[");
  346. print_node(fd, child);
  347. fprintf(fd, "]");
  348. }
  349. if (getIdentifierChainCount(n) == 1 && skipLast) {
  350. break;
  351. }
  352. if (child->node_type == AST_IDENTIFIER) {
  353. if (n->isRef) {
  354. fprintf(fd, "->");
  355. }
  356. else {
  357. fprintf(fd, ".");
  358. }
  359. print_identifier(fd, child, skipLast);
  360. }
  361. }
  362. }
  363. static void print_command_functionArguments(FILE *fd, struct ast_node *n, int beginWithSemicolon) {
  364. for (int i = 1; i < n->children.elements; i += 2) {
  365. struct ast_node *argtype = dd_da_get(&n->children, i-1);
  366. struct ast_node *argname = dd_da_get(&n->children, i );
  367. if (i > 1 || beginWithSemicolon) {
  368. fprintf(fd, ", ");
  369. }
  370. if (!dd_variable_type_isPrimitiveType(argtype->lex)) {
  371. fprintf(fd, "struct ");
  372. }
  373. fprintf(fd, "%s ", argtype->lex);
  374. if (!dd_variable_type_isPrimitiveType(argtype->lex)) {
  375. fprintf(fd, "*");
  376. }
  377. fprintf(fd, "%s", argname->lex);
  378. }
  379. }
  380. static void print_command_definitionClassFunction(FILE *fd, struct ast_node *n, const char *classname) {
  381. struct ast_node *type = dd_da_get(&n->children, 0);
  382. struct ast_node *name = dd_da_get(&n->children, 1);
  383. struct ast_node *args = dd_da_get(&n->children, 2);
  384. fprintf(fd, "%s (*%s)(struct %s *", type->lex, name->lex, classname);
  385. print_command_functionArguments(fd, args, 1);
  386. fprintf(fd, ");\n");
  387. }
  388. static void print_command_definition(FILE *fd, struct ast_node *n) {
  389. struct ast_node *type = dd_da_get(&n->children, 0);
  390. struct ast_node *defname = dd_da_get(&n->children, 1);
  391. if (n->isExtern) {
  392. fprintf(fd, "extern ");
  393. }
  394. if (!dd_variable_type_isPrimitiveType(type->lex)) {
  395. fprintf(fd, "struct ");
  396. }
  397. fprintf(fd, "%s ", type->lex);
  398. if (n->isRef) {
  399. fprintf(fd, "*");
  400. }
  401. print_identifier(fd, defname, 0);
  402. if (n->children.elements >= 3) {
  403. struct ast_node *initValue = dd_da_get(&n->children, 2);
  404. fprintf(fd, " = ");
  405. print_node(fd, initValue);
  406. }
  407. fprintf(fd, ";\n");
  408. }
  409. static void print_command_class(FILE *fd, struct ast_node *n) {
  410. struct ast_node *classname = dd_da_get(&n->children, 0);
  411. struct ast_node *subclassname = dd_da_get(&n->children, 1);
  412. struct ast_node *definitions = dd_da_get(&n->children, 2);
  413. fprintf(fd, "struct %s {\n", classname->lex);
  414. // subclass
  415. if (subclassname->node_type == AST_IDENTIFIER) {
  416. fprintf(fd, "struct %s parent;\n", subclassname->lex);
  417. }
  418. // definitions in struct
  419. for (unsigned int i = 0; i < definitions->children.elements; i++) {
  420. struct ast_node *child = dd_da_get(&definitions->children, i);
  421. // definition of variable
  422. if (strcmp(child->lex, "def") == 0) {
  423. print_command_definition(fd, child);
  424. }
  425. // definition of function
  426. else {
  427. // function does not override another
  428. if (child->value == 0) {
  429. print_command_definitionClassFunction(fd, child, classname->lex);
  430. }
  431. }
  432. }
  433. fprintf(fd, "};\n");
  434. // pre-define functions, so they are visible to all functions regardless of order
  435. for (unsigned int i = 1; i < definitions->children.elements; i++) {
  436. // grab ast node and symbol table entry, ensure this is a function
  437. struct ast_node *child = dd_da_get(&definitions->children, i);
  438. if (child->node_type != AST_COMMAND_NATIVE
  439. || strcmp(child->lex, "function") != 0) continue;
  440. // function name
  441. struct ast_node *functype = dd_da_get(&child->children, 0);
  442. struct ast_node *funcname = dd_da_get(&child->children, 1);
  443. // print the function signature
  444. fprintf(fd, "%s %s_%s(struct %s *this", functype->lex, classname->lex, funcname->lex, classname->lex);
  445. struct ast_node *args = dd_da_get(&child->children, 2);
  446. print_command_functionArguments(fd, args, 1);
  447. fprintf(fd, ");\n");
  448. }
  449. } // print class definition
  450. static void print_command_native(FILE *fd, struct ast_node *n) {
  451. if (strcmp(n->lex, "class") == 0) {
  452. print_command_class(fd, n);
  453. }
  454. else
  455. if (strcmp(n->lex, "class_function") == 0) {
  456. print_command_classFunction(fd, n);
  457. }
  458. else
  459. if (strcmp(n->lex, "function") == 0) {
  460. print_command_function(fd, n);
  461. }
  462. else
  463. if (strcmp(n->lex, "group") == 0) {
  464. for (unsigned int i = 0; i < n->children.elements; i++) {
  465. print_node(fd, dd_da_get(&n->children, i));
  466. }
  467. }
  468. else
  469. if (strcmp(n->lex, "def") == 0) {
  470. print_command_definition(fd, n);
  471. }
  472. else
  473. if (strcmp(n->lex, "=") == 0
  474. || strcmp(n->lex, "+") == 0
  475. || strcmp(n->lex, "-") == 0
  476. || strcmp(n->lex, "*") == 0
  477. || strcmp(n->lex, "/") == 0
  478. || strcmp(n->lex, "%") == 0
  479. || strcmp(n->lex, "&&") == 0
  480. || strcmp(n->lex, "||") == 0
  481. || strcmp(n->lex, "==") == 0
  482. || strcmp(n->lex, ">=") == 0
  483. || strcmp(n->lex, "<=") == 0
  484. || strcmp(n->lex, ">") == 0
  485. || strcmp(n->lex, "<") == 0) {
  486. print_binaryOperation(fd, n);
  487. }
  488. else
  489. if (strcmp(n->lex, "echo") == 0) {
  490. print_command_echo(fd, n);
  491. }
  492. else
  493. if (strcmp(n->lex, "if") == 0) {
  494. print_command_if(fd, n);
  495. }
  496. else
  497. if (strcmp(n->lex, "for") == 0) {
  498. print_command_for(fd, n);
  499. }
  500. else
  501. if (strcmp(n->lex, "multistring") == 0) {
  502. print_command_multistring(fd, n);
  503. }
  504. else
  505. if (strcmp(n->lex, "return") == 0) {
  506. print_command_return(fd, n);
  507. }
  508. else {
  509. printf("unable to parse command '%s': no parsing rule\n", n->lex);
  510. exit(-1);
  511. }
  512. }
  513. static void print_number(FILE *fd, struct ast_node *n) {
  514. fprintf(fd, "%d", n->value);
  515. }
  516. static void print_float(FILE *fd, struct ast_node *n) {
  517. fprintf(fd, "%f", n->fvalue);
  518. }
  519. static void print_node(FILE *fd, struct ast_node *n) {
  520. switch (n->node_type) {
  521. case AST_GAME:
  522. case AST_GROUP:
  523. for (unsigned int i = 0; i < n->children.elements; i++) {
  524. print_node(fd, dd_da_get(&n->children, i));
  525. }
  526. break;
  527. case AST_COMMAND_NATIVE: {
  528. print_command_native(fd, n);
  529. break;
  530. }
  531. case AST_COMMAND_CUSTOM: {
  532. print_command_custom(fd, n);
  533. break;
  534. }
  535. case AST_NUMBER: {
  536. print_number(fd, n);
  537. break;
  538. }
  539. case AST_IDENTIFIER: {
  540. print_identifierReference(fd, n, 0);
  541. break;
  542. }
  543. case AST_FLOAT: {
  544. print_float(fd, n);
  545. break;
  546. }
  547. case AST_STRING: {
  548. fprintf(fd, "\"%s\"", n->lex);
  549. break;
  550. }
  551. case AST_INCLUDE:
  552. case AST_EMPTY:
  553. break;
  554. }
  555. }
  556. // responsible for creating a file and translating ast to target language
  557. int transpile_cglut(const char *filename, struct ast_node *n) {
  558. /*
  559. * make sure given filename and node
  560. * have a value
  561. */
  562. if (!filename) {
  563. printf("avdl: transpile_cglut: no filename given to transpile to\n");
  564. return -1;
  565. }
  566. if (!n) {
  567. printf("avdl: transpile_cglut: no node given to transpile\n");
  568. return -1;
  569. }
  570. // open given file to write to
  571. FILE *fd_global = fopen(filename, "w");
  572. if (!fd_global) {
  573. printf("avdl: transpile_cglut: unable to open '%s': %s\n", filename, strerror(errno));
  574. return -1;
  575. }
  576. // print node to file
  577. fprintf(fd_global, "#include \"avdl_cengine.h\"\n");
  578. print_node(fd_global, n);
  579. // clean up
  580. if (fclose(fd_global) != 0) {
  581. printf("avdl: transpile_cglut: unable to close '%s': %s\n", filename, strerror(errno));
  582. return -1;
  583. }
  584. // everything OK
  585. return 0;
  586. } // transpile_cglut