avdl_semantic_analyser.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdarg.h>
  5. #include "avdl_symtable.h"
  6. #include "avdl_struct_table.h"
  7. #include "avdl_commands.h"
  8. #include "avdl_semantic_analyser.h"
  9. #include "avdl_lexer.h"
  10. #include "avdl_platform.h"
  11. static struct ast_node *expect_command_definition();
  12. static struct ast_node *expect_command_classDefinition();
  13. static struct ast_node *expect_command_group();
  14. static struct ast_node *expect_command_functionDefinition();
  15. static struct ast_node *expect_command_classFunction();
  16. static struct ast_node *expect_identifier();
  17. static struct ast_node *expect_int();
  18. static struct ast_node *expect_float();
  19. static struct ast_node *expect_string();
  20. static struct ast_node *expect_command_binaryOperation();
  21. static struct ast_node *expect_command();
  22. static struct ast_node *expect_command_arg();
  23. static struct ast_node *expect_command_if();
  24. static struct ast_node *expect_command_include();
  25. static struct ast_node *expect_command_asset();
  26. static struct ast_node *expect_command_for();
  27. static struct ast_node *expect_command_multistring();
  28. static struct ast_node *expect_command_return();
  29. static void semantic_error(const char *msg, ...);
  30. static struct ast_node *expect_command_return() {
  31. struct ast_node *returncmd = ast_create(AST_COMMAND_NATIVE, 0);
  32. ast_addLex(returncmd, "return");
  33. if (lexer_peek() != LEXER_TOKEN_COMMANDEND) {
  34. ast_child_add(returncmd, expect_command_arg());
  35. }
  36. return returncmd;
  37. }
  38. static struct ast_node *expect_command_multistring() {
  39. struct ast_node *multistringcmd = ast_create(AST_COMMAND_NATIVE, 0);
  40. ast_addLex(multistringcmd, "multistring");
  41. while (lexer_peek() == LEXER_TOKEN_STRING) {
  42. ast_child_add(multistringcmd, expect_string());
  43. }
  44. return multistringcmd;
  45. }
  46. static struct ast_node *expect_command_for() {
  47. struct ast_node *definition = expect_command();
  48. struct ast_node *condition = expect_command();
  49. struct ast_node *step = expect_command();
  50. struct ast_node *statements = expect_command();
  51. struct ast_node *forcmd = ast_create(AST_COMMAND_NATIVE, 0);
  52. ast_addLex(forcmd, "for");
  53. ast_child_add(forcmd, definition);
  54. ast_child_add(forcmd, condition);
  55. ast_child_add(forcmd, step);
  56. ast_child_add(forcmd, statements);
  57. return forcmd;
  58. }
  59. extern char *installLocation;
  60. static struct ast_node *expect_command_asset() {
  61. struct ast_node *asset = expect_string();
  62. /*
  63. * on android, a path to a file is truncated to the filename
  64. * minus the ending.
  65. *
  66. * temporary solution
  67. */
  68. if (avdl_platform_get() == AVDL_PLATFORM_ANDROID) {
  69. char buffer[500];
  70. strcpy(buffer, asset->lex);
  71. char *lastSlash = buffer;
  72. char *p = buffer;
  73. while (p[0] != '\0') {
  74. if (p[0] == '/') {
  75. lastSlash = p+1;
  76. }
  77. p++;
  78. }
  79. char *lastDot = buffer;
  80. p = buffer;
  81. while (p[0] != '\0') {
  82. if (p[0] == '.') {
  83. lastDot = p;
  84. }
  85. p++;
  86. }
  87. lastDot[0] = '\0';
  88. strcpy(asset->lex, lastSlash);
  89. }
  90. else
  91. // on linux and windows, attach the custom install location as the asset's prefix
  92. if (avdl_platform_get() == AVDL_PLATFORM_LINUX
  93. || avdl_platform_get() == AVDL_PLATFORM_WINDOWS) {
  94. char buffer[500];
  95. strcpy(buffer, installLocation);
  96. strcat(buffer, asset->lex);
  97. strcpy(asset->lex, buffer);
  98. }
  99. // waste the type for now
  100. expect_identifier();
  101. return asset;
  102. }
  103. static struct ast_node *expect_command_include() {
  104. struct ast_node *include = ast_create(AST_INCLUDE, 0);
  105. struct ast_node *filename = expect_string();
  106. ast_delete(filename);
  107. ast_addLex(include, filename->lex);
  108. return include;
  109. }
  110. static struct ast_node *expect_command_if() {
  111. struct ast_node *ifcmd = ast_create(AST_COMMAND_NATIVE, 0);
  112. ast_addLex(ifcmd, "if");
  113. while (lexer_peek() != LEXER_TOKEN_COMMANDEND) {
  114. ast_child_add(ifcmd, expect_command_arg());
  115. }
  116. return ifcmd;
  117. }
  118. static struct ast_node *expect_command_classFunction() {
  119. struct ast_node *classFunc = ast_create(AST_COMMAND_NATIVE, 0);
  120. ast_addLex(classFunc, "class_function");
  121. struct ast_node *classname = expect_identifier();
  122. struct ast_node *function = expect_command_functionDefinition();
  123. symtable_push();
  124. struct entry *e = symtable_entryat(symtable_insert("this", DD_VARIABLE_TYPE_STRUCT));
  125. e->isRef = 1;
  126. e->value = struct_table_get_index(classname->lex);
  127. // function arguments
  128. struct ast_node *funcargs = dd_da_get(&function->children, 2);
  129. for (int i = 1; i < funcargs->children.elements; i += 2) {
  130. struct ast_node *type = dd_da_get(&funcargs->children, i-1);
  131. struct ast_node *name = dd_da_get(&funcargs->children, i);
  132. struct entry *symEntry = symtable_entryat(symtable_insert(name->lex, dd_variable_type_convert(type->lex)));
  133. if (!dd_variable_type_isPrimitiveType(type->lex)) {
  134. symEntry->isRef = 1;
  135. symEntry->value = struct_table_get_index(type->lex);
  136. }
  137. }
  138. //symtable_print();
  139. struct ast_node *functionStatements = expect_command();
  140. symtable_pop();
  141. ast_child_add(classFunc, classname);
  142. ast_child_add(function, functionStatements);
  143. ast_child_add(classFunc, function);
  144. return classFunc;
  145. }
  146. static struct ast_node *expect_command_functionDefinition() {
  147. struct ast_node *function = ast_create(AST_COMMAND_NATIVE, 0);
  148. ast_addLex(function, "function");
  149. struct ast_node *returnType = expect_identifier();
  150. struct ast_node *functionName = expect_identifier();
  151. struct ast_node *args = expect_command();
  152. ast_child_add(function, returnType);
  153. ast_child_add(function, functionName);
  154. ast_child_add(function, args);
  155. return function;
  156. }
  157. static struct ast_node *expect_command_group() {
  158. struct ast_node *group = ast_create(AST_COMMAND_NATIVE, 0);
  159. ast_addLex(group, "group");
  160. while (lexer_peek() != LEXER_TOKEN_COMMANDEND) {
  161. ast_child_add(group, expect_command_arg());
  162. }
  163. return group;
  164. }
  165. static struct ast_node *getIdentifierArrayNode(struct ast_node *n) {
  166. for (int i = 0; i < n->children.elements; i++) {
  167. struct ast_node *child = dd_da_get(&n->children, i);
  168. if (child->node_type == AST_GROUP) {
  169. return child;
  170. }
  171. }
  172. return 0;
  173. }
  174. static struct ast_node *expect_command_classDefinition() {
  175. struct ast_node *classname = expect_identifier();
  176. // subclass can be an identifier (name of the class) or `0` (no parent class)
  177. struct ast_node *subclassname;
  178. if (lexer_peek() == LEXER_TOKEN_IDENTIFIER) {
  179. subclassname = expect_identifier();
  180. }
  181. else {
  182. struct ast_node *n = expect_int();
  183. if (n->value != 0) {
  184. semantic_error("subclass can either be an identifier or '0'");
  185. }
  186. subclassname = 0;
  187. }
  188. symtable_push();
  189. struct ast_node *definitions = expect_command();
  190. int structIndex = struct_table_push(classname->lex, subclassname->lex);
  191. for (int i = 0; i < definitions->children.elements; i++) {
  192. struct ast_node *child = dd_da_get(&definitions->children, i);
  193. struct ast_node *type = dd_da_get(&child->children, 0);
  194. struct ast_node *name = dd_da_get(&child->children, 1);
  195. if (strcmp(child->lex, "def") == 0) {
  196. struct entry *e = symtable_entryat(symtable_lookup(name->lex));
  197. struct ast_node *arrayNode = getIdentifierArrayNode(name);
  198. //printf("variable: %s %s\n", type->lex, name->lex);
  199. if (arrayNode) {
  200. if (arrayNode->children.elements == 0) {
  201. semantic_error("array definition should have a value");
  202. }
  203. struct ast_node *arrayNum = dd_da_get(&arrayNode->children, 0);
  204. if (arrayNum->node_type != AST_NUMBER) {
  205. semantic_error("array definition should only be a number");
  206. }
  207. struct_table_push_member_array(name->lex, dd_variable_type_convert(type->lex), type->lex, arrayNum->value, e->isRef);
  208. }
  209. else {
  210. struct_table_push_member(name->lex, dd_variable_type_convert(type->lex), type->lex, e->isRef);
  211. }
  212. }
  213. else {
  214. //printf("function: %s %s\n", type->lex, name->lex);
  215. int parentDepth = struct_table_is_member_parent(structIndex, name->lex);
  216. //printf("var: %s %s\n", type->lex, name->lex);
  217. //printf("parent depth: %d\n", parentDepth);
  218. // override function
  219. if (parentDepth >= 0) {
  220. child->value = 1;
  221. }
  222. // new function
  223. else {
  224. }
  225. struct_table_push_member(name->lex, DD_VARIABLE_TYPE_FUNCTION, 0, 0);
  226. }
  227. }
  228. symtable_pop();
  229. /* scan definitions
  230. * if a function was defined in any of the subclasses, mark is
  231. * as an override
  232. */
  233. struct ast_node *classDefinition = ast_create(AST_COMMAND_NATIVE, 0);
  234. ast_addLex(classDefinition, "class");
  235. ast_child_add(classDefinition, classname);
  236. ast_child_add(classDefinition, subclassname);
  237. ast_child_add(classDefinition, definitions);
  238. return classDefinition;
  239. }
  240. static struct ast_node *expect_command_definition() {
  241. struct ast_node *definition = ast_create(AST_COMMAND_NATIVE, 0);
  242. ast_addLex(definition, "def");
  243. int isRef = 0;
  244. int isExtern = 0;
  245. // optional modifiers
  246. struct ast_node *optionalModifier = expect_identifier();
  247. do {
  248. if (strcmp(optionalModifier->lex, "ref") == 0) {
  249. // apply modifier
  250. isRef = 1;
  251. // get new optional modifier
  252. ast_delete(optionalModifier);
  253. optionalModifier = expect_identifier();
  254. }
  255. else
  256. if (strcmp(optionalModifier->lex, "extern") == 0) {
  257. // apply modifier
  258. isExtern = 1;
  259. // get new optional modifier
  260. ast_delete(optionalModifier);
  261. optionalModifier = expect_identifier();
  262. }
  263. else {
  264. break;
  265. }
  266. } while (1);
  267. definition->isExtern = isExtern;
  268. // get type
  269. struct ast_node *type = optionalModifier;
  270. // check if primitive or struct
  271. if (!dd_variable_type_isPrimitiveType(type->lex)
  272. && !struct_table_exists(type->lex)) {
  273. semantic_error("unrecognized type '%s'", type->lex);
  274. }
  275. // get variable name
  276. struct ast_node *varname = expect_identifier();
  277. // add newly defined variable to symbol table
  278. struct entry *e = symtable_entryat(symtable_insert(varname->lex, SYMTABLE_VARIABLE));
  279. e->value = dd_variable_type_convert(type->lex);
  280. e->isRef = isRef;
  281. definition->isRef = isRef;
  282. ast_child_add(definition, type);
  283. ast_child_add(definition, varname);
  284. if (lexer_peek() != LEXER_TOKEN_COMMANDEND) {
  285. struct ast_node *initialValue = expect_command_arg();
  286. ast_child_add(definition, initialValue);
  287. }
  288. return definition;
  289. }
  290. static struct ast_node *expect_int() {
  291. // confirm it's an integer
  292. if (lexer_getNextToken() != LEXER_TOKEN_INT) {
  293. semantic_error("expected integer instead of '%s'", lexer_getLexToken());
  294. }
  295. struct ast_node *integer = ast_create(AST_NUMBER, atoi(lexer_getLexToken()));
  296. return integer;
  297. }
  298. static struct ast_node *expect_float() {
  299. // confirm it's a float
  300. if (lexer_getNextToken() != LEXER_TOKEN_FLOAT) {
  301. semantic_error("expected float instead of '%s'", lexer_getLexToken());
  302. }
  303. struct ast_node *f = ast_create(AST_FLOAT, 0);
  304. f->fvalue = atof(lexer_getLexToken());
  305. return f;
  306. }
  307. static struct ast_node *expect_string() {
  308. // confirm it's a string
  309. if (lexer_getNextToken() != LEXER_TOKEN_STRING) {
  310. semantic_error("expected string instead of '%s'", lexer_getLexToken());
  311. }
  312. struct ast_node *str = ast_create(AST_STRING, 0);
  313. ast_addLex(str, lexer_getLexToken());
  314. return str;
  315. }
  316. static struct ast_node *expect_command_binaryOperation(const char *binaryOperationLex) {
  317. struct ast_node *binaryOperation = ast_create(AST_COMMAND_NATIVE, 0);
  318. ast_addLex(binaryOperation, binaryOperationLex);
  319. while (lexer_peek() != LEXER_TOKEN_COMMANDEND) {
  320. ast_child_add(binaryOperation, expect_command_arg());
  321. }
  322. return binaryOperation;
  323. }
  324. static struct ast_node *expect_identifier() {
  325. // confirm it's an identifier
  326. if (lexer_getNextToken() != LEXER_TOKEN_IDENTIFIER) {
  327. semantic_error("expected identifier instead of '%s'", lexer_getLexToken());
  328. }
  329. // generate ast node for it
  330. struct ast_node *identifier = ast_create(AST_IDENTIFIER, 0);
  331. ast_addLex(identifier, lexer_getLexToken());
  332. struct entry *symEntry = symtable_lookupEntry(identifier->lex);
  333. if (symEntry) {
  334. identifier->isRef = symEntry->isRef;
  335. identifier->value = symEntry->value;
  336. }
  337. // does it have an array modifier?
  338. if (lexer_peek() == LEXER_TOKEN_ARRAYSTART) {
  339. lexer_getNextToken();
  340. struct ast_node *array = ast_create(AST_GROUP, 0);
  341. int token = lexer_peek();
  342. // integer as array modifier
  343. if (token == LEXER_TOKEN_INT) {
  344. ast_child_add(array, expect_int());
  345. }
  346. else
  347. // identifier as array modifier
  348. if (token == LEXER_TOKEN_IDENTIFIER) {
  349. ast_child_add(array, expect_identifier());
  350. }
  351. else
  352. // calculation as array modifier
  353. if (token == LEXER_TOKEN_COMMANDSTART) {
  354. lexer_getNextToken();
  355. while (lexer_peek() == LEXER_TOKEN_COMMANDSTART) {
  356. ast_child_add(array, expect_command());
  357. }
  358. }
  359. ast_child_add(identifier, array);
  360. // end of array
  361. if (lexer_getNextToken() != LEXER_TOKEN_ARRAYEND) {
  362. semantic_error("expected end of array");
  363. }
  364. }
  365. // it has a period (myclass.myvar)
  366. if (lexer_peek() == LEXER_TOKEN_PERIOD) {
  367. lexer_getNextToken();
  368. //symtable_print();
  369. // identifiers that own objects have to be in the symbol table
  370. if (!symEntry) {
  371. semantic_error("identifier '%s' not a known symbol", identifier->lex);
  372. }
  373. // identifiers that own objects have to be structs
  374. if (symEntry->token != DD_VARIABLE_TYPE_STRUCT) {
  375. semantic_error("identifier '%s' not a struct, so it can't own objects", identifier->lex);
  376. }
  377. //printf("name of struct: %s\n", struct_table_get_name(e->value));
  378. // add struct's members to new symbol table
  379. symtable_push();
  380. for (unsigned int j = 0; j < struct_table_get_member_total(symEntry->value); j++) {
  381. /*
  382. printf(" member: %s %d %s\n",
  383. struct_table_get_member_name(e->value, j),
  384. struct_table_get_member_type(e->value, j),
  385. struct_table_get_member_nametype(e->value, j)
  386. );
  387. */
  388. struct entry *e2 = symtable_entryat(symtable_insert(
  389. struct_table_get_member_name(symEntry->value, j),
  390. struct_table_get_member_type(symEntry->value, j))
  391. );
  392. if (struct_table_get_member_type(symEntry->value, j) == DD_VARIABLE_TYPE_STRUCT) {
  393. e2->value = struct_table_get_index(struct_table_get_member_nametype(symEntry->value, j));
  394. }
  395. e2->isRef = struct_table_getMemberIsRef(symEntry->value, j);
  396. }
  397. // get the owned object's name
  398. struct ast_node *child = expect_identifier();
  399. // child not inside current symbol table - possibly belongs to a parent class
  400. int childSymId = symtable_lookup(child->lex);
  401. if (childSymId < 0) {
  402. int parentDepth = struct_table_is_member_parent(symEntry->value, child->lex);
  403. // child not part of that struct, or any of its parent classes
  404. if (parentDepth < 0) {
  405. semantic_error("variable '%s' of class '%s' does not own object '%s'",
  406. identifier->lex, struct_table_get_name(symEntry->value), child->lex
  407. );
  408. }
  409. else
  410. // child direct child of that class, but not in symbol table, this should never happen
  411. if (parentDepth == 0) {
  412. semantic_error("variable '%s' of class '%s' owns object '%s', but couldn't be found in the symbol table",
  413. identifier->lex, struct_table_get_name(symEntry->value), child->lex
  414. );
  415. }
  416. // add "parent" children in ast, for each parent class depth level
  417. struct ast_node *lastChild = identifier;
  418. for (int i = 0; i < parentDepth; i++) {
  419. struct ast_node *parentChild = ast_create(AST_IDENTIFIER, 0);
  420. ast_addLex(parentChild, "parent");
  421. int childIndex = ast_child_add(lastChild, parentChild);
  422. lastChild = dd_da_get(&lastChild->children, childIndex);
  423. }
  424. // finally add the found child on the last "parent" node added
  425. ast_child_add(lastChild, child);
  426. }
  427. // child is directly owned by this struct, just add it as child
  428. else {
  429. if (struct_table_get_member_type(symEntry->value, struct_table_get_member(symEntry->value, child->lex)) == DD_VARIABLE_TYPE_STRUCT) {
  430. child->value = DD_VARIABLE_TYPE_STRUCT;
  431. }
  432. ast_child_add(identifier, child);
  433. }
  434. symtable_pop();
  435. }
  436. return identifier;
  437. }
  438. static struct ast_node *expect_command_arg() {
  439. int token = lexer_peek();
  440. if (token == LEXER_TOKEN_INT) {
  441. return expect_int();
  442. }
  443. else
  444. if (token == LEXER_TOKEN_FLOAT) {
  445. return expect_float();
  446. }
  447. else
  448. if (token == LEXER_TOKEN_STRING) {
  449. return expect_string();
  450. }
  451. else
  452. if (token == LEXER_TOKEN_COMMANDSTART) {
  453. return expect_command();
  454. }
  455. else
  456. if (token == LEXER_TOKEN_IDENTIFIER) {
  457. return expect_identifier();
  458. }
  459. else {
  460. lexer_getNextToken();
  461. semantic_error("expected command argument instead of '%s'", lexer_getLexToken());
  462. }
  463. return 0;
  464. }
  465. // looks for the structure of a command: (cmdname arg1 arg2 .. argN)
  466. static struct ast_node *expect_command() {
  467. // confirm that a command is expected
  468. if (lexer_getNextToken() != LEXER_TOKEN_COMMANDSTART) {
  469. semantic_error("expected the start of a command '(', instead of '%s'", lexer_getLexToken());
  470. }
  471. // get the command's name
  472. struct ast_node *cmd;
  473. struct ast_node *cmdname = expect_identifier();
  474. // native command, special rules
  475. if (agc_commands_isNative(cmdname->lex)) {
  476. // native command can only be a name, no array modifiers or owning data
  477. if (cmdname->children.elements > 0) {
  478. semantic_error("native command name cannot have an array modifier, or own other data\n");
  479. }
  480. // based on the command, expect different data
  481. if (strcmp(cmdname->lex, "def") == 0) {
  482. cmd = expect_command_definition();
  483. }
  484. else
  485. if (strcmp(cmdname->lex, "class") == 0) {
  486. cmd = expect_command_classDefinition();
  487. }
  488. else
  489. if (strcmp(cmdname->lex, "group") == 0) {
  490. cmd = expect_command_group();
  491. }
  492. else
  493. if (strcmp(cmdname->lex, "function") == 0) {
  494. cmd = expect_command_functionDefinition();
  495. if (lexer_peek() == LEXER_TOKEN_COMMANDSTART) {
  496. // function statements
  497. ast_child_add(cmd, expect_command());
  498. }
  499. }
  500. else
  501. if (strcmp(cmdname->lex, "class_function") == 0) {
  502. cmd = expect_command_classFunction();
  503. }
  504. else
  505. if (strcmp(cmdname->lex, "=") == 0
  506. || strcmp(cmdname->lex, "+") == 0
  507. || strcmp(cmdname->lex, "-") == 0
  508. || strcmp(cmdname->lex, "*") == 0
  509. || strcmp(cmdname->lex, "/") == 0
  510. || strcmp(cmdname->lex, "%") == 0
  511. || strcmp(cmdname->lex, "&&") == 0
  512. || strcmp(cmdname->lex, "||") == 0
  513. || strcmp(cmdname->lex, "==") == 0
  514. || strcmp(cmdname->lex, ">=") == 0
  515. || strcmp(cmdname->lex, "<=") == 0
  516. || strcmp(cmdname->lex, ">") == 0
  517. || strcmp(cmdname->lex, "<") == 0) {
  518. cmd = expect_command_binaryOperation(cmdname->lex);
  519. }
  520. else
  521. if (strcmp(cmdname->lex, "echo") == 0) {
  522. cmd = expect_command_group();
  523. ast_addLex(cmd, "echo");
  524. }
  525. else
  526. if (strcmp(cmdname->lex, "if") == 0) {
  527. cmd = expect_command_if();
  528. }
  529. else
  530. if (strcmp(cmdname->lex, "include") == 0) {
  531. cmd = expect_command_include();
  532. }
  533. else
  534. if (strcmp(cmdname->lex, "asset") == 0) {
  535. cmd = expect_command_asset();
  536. }
  537. else
  538. if (strcmp(cmdname->lex, "for") == 0) {
  539. cmd = expect_command_for();
  540. }
  541. else
  542. if (strcmp(cmdname->lex, "multistring") == 0) {
  543. cmd = expect_command_multistring();
  544. }
  545. else
  546. if (strcmp(cmdname->lex, "return") == 0) {
  547. cmd = expect_command_return();
  548. }
  549. else {
  550. semantic_error("no rule to parse command '%s'", cmdname->lex);
  551. }
  552. }
  553. // custom command, make sure it exists
  554. else {
  555. /*
  556. if (symtable_lookup(cmdname->lex) == -1) {
  557. printf("unrecognized identifier: %s\n", cmdname->lex);
  558. exit(-1);
  559. }
  560. */
  561. cmd = ast_create(0, 0);
  562. cmd->node_type = AST_COMMAND_CUSTOM;
  563. ast_child_add(cmd, cmdname);
  564. while (lexer_peek() != LEXER_TOKEN_COMMANDEND) {
  565. ast_child_add(cmd, expect_command_arg());
  566. }
  567. }
  568. // get the command's children
  569. if (lexer_getNextToken() != LEXER_TOKEN_COMMANDEND) {
  570. semantic_error("expected command end ')'");
  571. }
  572. return cmd;
  573. }
  574. void semanticAnalyser_convertToAst(struct ast_node *node, const char *filename) {
  575. struct_table_init();
  576. symtable_init();
  577. lexer_prepare(filename);
  578. struct ast_node *cmd;
  579. while (lexer_peek() == LEXER_TOKEN_COMMANDSTART) {
  580. cmd = expect_command();
  581. if (cmd->node_type == AST_INCLUDE) {
  582. lexer_addIncludedFile(cmd->lex);
  583. }
  584. else {
  585. ast_child_add(node, cmd);
  586. }
  587. }
  588. lexer_clean();
  589. }
  590. static void semantic_error(const char *msg, ...) {
  591. va_list args;
  592. va_start(args, msg);
  593. printf("avdl syntax error:\n");
  594. printf("%s:%d: ", lexer_getCurrentFilename(), lexer_getCurrentLinenumber());
  595. vprintf(msg, args);
  596. printf("\n");
  597. lexer_printCurrentLine();
  598. exit(-1);
  599. }