CMDgram.y 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. %{
  2. // Make sure we don't get gram.h twice.
  3. #define _CMDGRAM_H_
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include "console/console.h"
  7. #include "console/compiler.h"
  8. #include "console/consoleInternal.h"
  9. #ifndef YYDEBUG
  10. #define YYDEBUG 0
  11. #endif
  12. #define YYSSIZE 350
  13. int outtext(char *fmt, ...);
  14. extern int serrors;
  15. #define nil 0
  16. #undef YY_ARGS
  17. #define YY_ARGS(x) x
  18. int CMDlex();
  19. void CMDerror(char *, ...);
  20. #define alloca dMalloc
  21. %}
  22. %{
  23. /* Reserved Word Definitions */
  24. %}
  25. %token <i> rwDEFINE rwENDDEF rwDECLARE
  26. %token <i> rwBREAK rwELSE rwCONTINUE rwGLOBAL
  27. %token <i> rwIF rwNIL rwRETURN rwWHILE rwDO
  28. %token <i> rwENDIF rwENDWHILE rwENDFOR rwDEFAULT
  29. %token <i> rwFOR rwDATABLOCK rwSWITCH rwCASE rwSWITCHSTR
  30. %token <i> rwCASEOR rwPACKAGE rwNAMESPACE rwCLASS rwMESSAGE
  31. %token ILLEGAL_TOKEN
  32. %{
  33. /* Constants and Identifier Definitions */
  34. %}
  35. %token <c> CHRCONST
  36. %token <i> INTCONST
  37. %token <s> TTAG
  38. %token <s> VAR
  39. %token <s> IDENT
  40. %token <str> DOCBLOCK
  41. %token <str> STRATOM
  42. %token <str> TAGATOM
  43. %token <f> FLTCONST
  44. %{
  45. /* Operator Definitions */
  46. %}
  47. %token <i> '+' '-' '*' '/' '<' '>' '=' '.' '|' '&' '%'
  48. %token <i> '(' ')' ',' ':' ';' '{' '}' '^' '~' '!' '@'
  49. %token <i> opINTNAME opINTNAMER
  50. %token <i> opMINUSMINUS opPLUSPLUS
  51. %token <i> STMT_SEP
  52. %token <i> opSHL opSHR opPLASN opMIASN opMLASN opDVASN opMODASN opANDASN
  53. %token <i> opXORASN opORASN opSLASN opSRASN opCAT
  54. %token <i> opEQ opNE opGE opLE opAND opOR opSTREQ
  55. %token <i> opCOLONCOLON
  56. %union {
  57. char c;
  58. int i;
  59. const char * s;
  60. char * str;
  61. double f;
  62. StmtNode * stmt;
  63. ExprNode * expr;
  64. SlotAssignNode * slist;
  65. VarNode * var;
  66. SlotDecl slot;
  67. InternalSlotDecl intslot;
  68. ObjectBlockDecl odcl;
  69. ObjectDeclNode * od;
  70. AssignDecl asn;
  71. IfStmtNode * ifnode;
  72. }
  73. %type <s> parent_block
  74. %type <ifnode> case_block
  75. %type <stmt> switch_stmt
  76. %type <stmt> decl
  77. %type <stmt> decl_list
  78. %type <stmt> package_decl
  79. %type <stmt> fn_decl_stmt
  80. %type <stmt> fn_decl_list
  81. %type <stmt> statement_list
  82. %type <stmt> stmt
  83. %type <expr> expr_list
  84. %type <expr> expr_list_decl
  85. %type <expr> aidx_expr
  86. %type <expr> funcall_expr
  87. %type <expr> object_name
  88. %type <expr> object_args
  89. %type <expr> stmt_expr
  90. %type <expr> case_expr
  91. %type <expr> class_name_expr
  92. %type <stmt> if_stmt
  93. %type <stmt> while_stmt
  94. %type <stmt> for_stmt
  95. %type <stmt> stmt_block
  96. %type <stmt> datablock_decl
  97. %type <od> message_decl
  98. %type <od> object_decl
  99. %type <od> object_decl_list
  100. %type <odcl> object_declare_block
  101. %type <odcl> message_declare_block
  102. %type <expr> expr
  103. %type <slist> slot_assign_list
  104. %type <slist> slot_assign
  105. %type <slot> slot_acc
  106. %type <intslot> intslot_acc
  107. %type <stmt> expression_stmt
  108. %type <var> var_list
  109. %type <var> var_list_decl
  110. %type <asn> assign_op_struct
  111. %left '['
  112. %right opMODASN opANDASN opXORASN opPLASN opMIASN opMLASN opDVASN opMDASN opNDASN opNTASN opORASN opSLASN opSRASN '='
  113. %left '?' ':'
  114. %left opOR
  115. %left opAND
  116. %left '|'
  117. %left '^'
  118. %left '&'
  119. %left opEQ opNE
  120. %left '<' opLE '>' opGE
  121. %left '@' opCAT opSTREQ opSTRNE
  122. %left opSHL opSHR
  123. %left '+' '-'
  124. %left '*' '/' '%'
  125. %right '!' '~' opPLUSPLUS opMINUSMINUS UNARY
  126. %left '.'
  127. %left opINTNAME opINTNAMER
  128. %%
  129. start
  130. : decl_list
  131. { }
  132. ;
  133. decl_list
  134. :
  135. { $$ = nil; }
  136. | decl_list decl
  137. { if(!statementList) { statementList = $2; } else { statementList->append($2); } }
  138. ;
  139. decl
  140. : stmt
  141. { $$ = $1; }
  142. | fn_decl_stmt
  143. { $$ = $1; }
  144. | package_decl
  145. { $$ = $1; }
  146. ;
  147. package_decl
  148. : rwPACKAGE IDENT '{' fn_decl_list '}' ';'
  149. { $$ = $4; for(StmtNode *walk = ($4);walk;walk = walk->getNext() ) walk->setPackage($2); }
  150. ;
  151. fn_decl_list
  152. : fn_decl_stmt
  153. { $$ = $1; }
  154. | fn_decl_list fn_decl_stmt
  155. { $$ = $1; ($1)->append($2); }
  156. ;
  157. statement_list
  158. :
  159. { $$ = nil; }
  160. | statement_list stmt
  161. { if(!$1) { $$ = $2; } else { ($1)->append($2); $$ = $1; } }
  162. ;
  163. stmt
  164. : if_stmt
  165. | while_stmt
  166. | for_stmt
  167. | datablock_decl
  168. | switch_stmt
  169. | rwBREAK ';'
  170. { $$ = BreakStmtNode::alloc(); }
  171. | rwCONTINUE ';'
  172. { $$ = ContinueStmtNode::alloc(); }
  173. | rwRETURN ';'
  174. { $$ = ReturnStmtNode::alloc(NULL); }
  175. | rwRETURN expr ';'
  176. { $$ = ReturnStmtNode::alloc($2); }
  177. | expression_stmt ';'
  178. { $$ = $1; }
  179. | TTAG '=' expr ';'
  180. { $$ = TTagSetStmtNode::alloc($1, $3, NULL); }
  181. | TTAG '=' expr ',' expr ';'
  182. { $$ = TTagSetStmtNode::alloc($1, $3, $5); }
  183. | DOCBLOCK
  184. { $$ = StrConstNode::alloc($1, false, true); }
  185. ;
  186. fn_decl_stmt
  187. : rwDEFINE IDENT '(' var_list_decl ')' '{' statement_list '}'
  188. { $$ = FunctionDeclStmtNode::alloc($2, NULL, $4, $7); }
  189. | rwDEFINE IDENT opCOLONCOLON IDENT '(' var_list_decl ')' '{' statement_list '}'
  190. { $$ = FunctionDeclStmtNode::alloc($4, $2, $6, $9); }
  191. ;
  192. var_list_decl
  193. :
  194. { $$ = NULL; }
  195. | var_list
  196. { $$ = $1; }
  197. ;
  198. var_list
  199. : VAR
  200. { $$ = VarNode::alloc($1, NULL); }
  201. | var_list ',' VAR
  202. { $$ = $1; ((StmtNode*)($1))->append((StmtNode*)VarNode::alloc($3, NULL)); }
  203. ;
  204. datablock_decl
  205. : rwDATABLOCK IDENT '(' IDENT parent_block ')' '{' slot_assign_list '}' ';'
  206. { $$ = ObjectDeclNode::alloc(ConstantNode::alloc($2), ConstantNode::alloc($4), NULL, $5, $8, NULL, true, false, false); }
  207. ;
  208. message_decl
  209. : rwMESSAGE class_name_expr '(' object_name parent_block')' '{' message_declare_block '}'
  210. { $$ = ObjectDeclNode::alloc($2, $4, NULL, $5, $8.slots, $8.decls, false, false, true); }
  211. | rwMESSAGE class_name_expr '(' object_name parent_block ')'
  212. { $$ = ObjectDeclNode::alloc($2, $4, NULL, $5, NULL, NULL, false, false, true); }
  213. ;
  214. object_decl
  215. : rwDECLARE class_name_expr '(' object_name parent_block object_args ')' '{' object_declare_block '}'
  216. { $$ = ObjectDeclNode::alloc($2, $4, $6, $5, $9.slots, $9.decls, false, false, false); }
  217. | rwDECLARE class_name_expr '(' object_name parent_block object_args ')'
  218. { $$ = ObjectDeclNode::alloc($2, $4, $6, $5, NULL, NULL, false, false, false); }
  219. | rwDECLARE class_name_expr '(' '[' object_name ']' parent_block object_args ')' '{' object_declare_block '}'
  220. { $$ = ObjectDeclNode::alloc($2, $5, $8, $7, $11.slots, $11.decls, false, true, false); }
  221. | rwDECLARE class_name_expr '(' '[' object_name ']' parent_block object_args ')'
  222. { $$ = ObjectDeclNode::alloc($2, $5, $8, $7, NULL, NULL, false, true, false); }
  223. ;
  224. parent_block
  225. :
  226. { $$ = NULL; }
  227. | ':' IDENT
  228. { $$ = $2; }
  229. ;
  230. object_name
  231. :
  232. { $$ = StrConstNode::alloc("", false); }
  233. | expr
  234. { $$ = $1; }
  235. ;
  236. object_args
  237. :
  238. { $$ = NULL; }
  239. | ',' expr_list
  240. { $$ = $2; }
  241. ;
  242. message_declare_block
  243. :
  244. { $$.slots = NULL; $$.decls = NULL; }
  245. | slot_assign_list
  246. { $$.slots = $1; $$.decls = NULL; }
  247. ;
  248. object_declare_block
  249. :
  250. { $$.slots = NULL; $$.decls = NULL; }
  251. | slot_assign_list
  252. { $$.slots = $1; $$.decls = NULL; }
  253. | object_decl_list
  254. { $$.slots = NULL; $$.decls = $1; }
  255. | slot_assign_list object_decl_list
  256. { $$.slots = $1; $$.decls = $2; }
  257. ;
  258. object_decl_list
  259. : object_decl ';'
  260. { $$ = $1; }
  261. | object_decl_list object_decl ';'
  262. { $1->append($2); $$ = $1; }
  263. ;
  264. stmt_block
  265. : '{' statement_list '}'
  266. { $$ = $2; }
  267. | stmt
  268. { $$ = $1; }
  269. ;
  270. switch_stmt
  271. : rwSWITCH '(' expr ')' '{' case_block '}'
  272. { $$ = $6; $6->propagateSwitchExpr($3, false); }
  273. | rwSWITCHSTR '(' expr ')' '{' case_block '}'
  274. { $$ = $6; $6->propagateSwitchExpr($3, true); }
  275. ;
  276. case_block
  277. : rwCASE case_expr ':' statement_list
  278. { $$ = IfStmtNode::alloc($1, $2, $4, NULL, false); }
  279. | rwCASE case_expr ':' statement_list rwDEFAULT ':' statement_list
  280. { $$ = IfStmtNode::alloc($1, $2, $4, $7, false); }
  281. | rwCASE case_expr ':' statement_list case_block
  282. { $$ = IfStmtNode::alloc($1, $2, $4, $5, true); }
  283. ;
  284. case_expr
  285. : expr
  286. { $$ = $1;}
  287. | case_expr rwCASEOR expr
  288. { ($1)->append($3); $$=$1; }
  289. ;
  290. if_stmt
  291. : rwIF '(' expr ')' stmt_block
  292. { $$ = IfStmtNode::alloc($1, $3, $5, NULL, false); }
  293. | rwIF '(' expr ')' stmt_block rwELSE stmt_block
  294. { $$ = IfStmtNode::alloc($1, $3, $5, $7, false); }
  295. ;
  296. while_stmt
  297. : rwWHILE '(' expr ')' stmt_block
  298. { $$ = LoopStmtNode::alloc($1, nil, $3, nil, $5, false); }
  299. | rwDO stmt_block rwWHILE '(' expr ')'
  300. { $$ = LoopStmtNode::alloc($3, nil, $5, nil, $2, true); }
  301. ;
  302. for_stmt
  303. : rwFOR '(' expr ';' expr ';' expr ')' stmt_block
  304. { $$ = LoopStmtNode::alloc($1, $3, $5, $7, $9, false); }
  305. | rwFOR '(' expr ';' expr ';' ')' stmt_block
  306. { $$ = LoopStmtNode::alloc($1, $3, $5, NULL, $8, false); }
  307. | rwFOR '(' expr ';' ';' expr ')' stmt_block
  308. { $$ = LoopStmtNode::alloc($1, $3, NULL, $6, $8, false); }
  309. | rwFOR '(' expr ';' ';' ')' stmt_block
  310. { $$ = LoopStmtNode::alloc($1, $3, NULL, NULL, $7, false); }
  311. | rwFOR '(' ';' expr ';' expr ')' stmt_block
  312. { $$ = LoopStmtNode::alloc($1, NULL, $4, $6, $8, false); }
  313. | rwFOR '(' ';' expr ';' ')' stmt_block
  314. { $$ = LoopStmtNode::alloc($1, NULL, $4, NULL, $7, false); }
  315. | rwFOR '(' ';' ';' expr ')' stmt_block
  316. { $$ = LoopStmtNode::alloc($1, NULL, NULL, $5, $7, false); }
  317. | rwFOR '(' ';' ';' ')' stmt_block
  318. { $$ = LoopStmtNode::alloc($1, NULL, NULL, NULL, $6, false); }
  319. ;
  320. expression_stmt
  321. : stmt_expr
  322. { $$ = $1; }
  323. ;
  324. expr
  325. : stmt_expr
  326. { $$ = $1; }
  327. | '(' expr ')'
  328. { $$ = $2; }
  329. | expr '^' expr
  330. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  331. | expr '%' expr
  332. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  333. | expr '&' expr
  334. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  335. | expr '|' expr
  336. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  337. | expr '+' expr
  338. { $$ = FloatBinaryExprNode::alloc($2, $1, $3); }
  339. | expr '-' expr
  340. { $$ = FloatBinaryExprNode::alloc($2, $1, $3); }
  341. | expr '*' expr
  342. { $$ = FloatBinaryExprNode::alloc($2, $1, $3); }
  343. | expr '/' expr
  344. { $$ = FloatBinaryExprNode::alloc($2, $1, $3); }
  345. | '-' expr %prec UNARY
  346. { $$ = FloatUnaryExprNode::alloc($1, $2); }
  347. | '*' expr %prec UNARY
  348. { $$ = TTagDerefNode::alloc($2); }
  349. | TTAG
  350. { $$ = TTagExprNode::alloc($1); }
  351. | expr '?' expr ':' expr
  352. { $$ = ConditionalExprNode::alloc($1, $3, $5); }
  353. | expr '<' expr
  354. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  355. | expr '>' expr
  356. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  357. | expr opGE expr
  358. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  359. | expr opLE expr
  360. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  361. | expr opEQ expr
  362. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  363. | expr opNE expr
  364. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  365. | expr opOR expr
  366. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  367. | expr opSHL expr
  368. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  369. | expr opSHR expr
  370. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  371. | expr opAND expr
  372. { $$ = IntBinaryExprNode::alloc($2, $1, $3); }
  373. | expr opSTREQ expr
  374. { $$ = StreqExprNode::alloc($1, $3, true); }
  375. | expr opSTRNE expr
  376. { $$ = StreqExprNode::alloc($1, $3, false); }
  377. | expr '@' expr
  378. { $$ = StrcatExprNode::alloc($1, $3, $2); }
  379. | '!' expr
  380. { $$ = IntUnaryExprNode::alloc($1, $2); }
  381. | '~' expr
  382. { $$ = IntUnaryExprNode::alloc($1, $2); }
  383. | TAGATOM
  384. { $$ = StrConstNode::alloc($1, true); }
  385. | FLTCONST
  386. { $$ = FloatNode::alloc($1); }
  387. | INTCONST
  388. { $$ = IntNode::alloc($1); }
  389. | rwBREAK
  390. { $$ = ConstantNode::alloc(StringTable->insert("break")); }
  391. | slot_acc
  392. { $$ = SlotAccessNode::alloc($1.object, $1.array, $1.slotName); }
  393. | intslot_acc
  394. { $$ = InternalSlotAccessNode::alloc($1.object, $1.slotExpr, $1.recurse); }
  395. | IDENT
  396. { $$ = ConstantNode::alloc($1); }
  397. | STRATOM
  398. { $$ = StrConstNode::alloc($1, false); }
  399. | VAR
  400. { $$ = (ExprNode*)VarNode::alloc($1, NULL); }
  401. | VAR '[' aidx_expr ']'
  402. { $$ = (ExprNode*)VarNode::alloc($1, $3); }
  403. ;
  404. slot_acc
  405. : expr '.' IDENT
  406. { $$.object = $1; $$.slotName = $3; $$.array = NULL; }
  407. | expr '.' IDENT '[' aidx_expr ']'
  408. { $$.object = $1; $$.slotName = $3; $$.array = $5; }
  409. ;
  410. intslot_acc
  411. : expr opINTNAME class_name_expr
  412. { $$.object = $1; $$.slotExpr = $3; $$.recurse = false; }
  413. | expr opINTNAMER class_name_expr
  414. { $$.object = $1; $$.slotExpr = $3; $$.recurse = true; }
  415. ;
  416. class_name_expr
  417. : IDENT
  418. { $$ = ConstantNode::alloc($1); }
  419. | '(' expr ')'
  420. { $$ = $2; }
  421. ;
  422. assign_op_struct
  423. : opPLUSPLUS
  424. { $$.token = '+'; $$.expr = FloatNode::alloc(1); }
  425. | opMINUSMINUS
  426. { $$.token = '-'; $$.expr = FloatNode::alloc(1); }
  427. | opPLASN expr
  428. { $$.token = '+'; $$.expr = $2; }
  429. | opMIASN expr
  430. { $$.token = '-'; $$.expr = $2; }
  431. | opMLASN expr
  432. { $$.token = '*'; $$.expr = $2; }
  433. | opDVASN expr
  434. { $$.token = '/'; $$.expr = $2; }
  435. | opMODASN expr
  436. { $$.token = '%'; $$.expr = $2; }
  437. | opANDASN expr
  438. { $$.token = '&'; $$.expr = $2; }
  439. | opXORASN expr
  440. { $$.token = '^'; $$.expr = $2; }
  441. | opORASN expr
  442. { $$.token = '|'; $$.expr = $2; }
  443. | opSLASN expr
  444. { $$.token = opSHL; $$.expr = $2; }
  445. | opSRASN expr
  446. { $$.token = opSHR; $$.expr = $2; }
  447. ;
  448. stmt_expr
  449. : funcall_expr
  450. { $$ = $1; }
  451. | object_decl
  452. { $$ = $1; }
  453. | message_decl
  454. { $$ = $1; }
  455. | VAR '=' expr
  456. { $$ = AssignExprNode::alloc($1, NULL, $3); }
  457. | VAR '[' aidx_expr ']' '=' expr
  458. { $$ = AssignExprNode::alloc($1, $3, $6); }
  459. | VAR assign_op_struct
  460. { $$ = AssignOpExprNode::alloc($1, NULL, $2.expr, $2.token); }
  461. | VAR '[' aidx_expr ']' assign_op_struct
  462. { $$ = AssignOpExprNode::alloc($1, $3, $5.expr, $5.token); }
  463. | slot_acc assign_op_struct
  464. { $$ = SlotAssignOpNode::alloc($1.object, $1.slotName, $1.array, $2.token, $2.expr); }
  465. | slot_acc '=' expr
  466. { $$ = SlotAssignNode::alloc($1.object, $1.array, $1.slotName, $3); }
  467. | slot_acc '=' '{' expr_list '}'
  468. { $$ = SlotAssignNode::alloc($1.object, $1.array, $1.slotName, $4); }
  469. ;
  470. funcall_expr
  471. : IDENT '(' expr_list_decl ')'
  472. { $$ = FuncCallExprNode::alloc($1, NULL, $3, false); }
  473. | IDENT opCOLONCOLON IDENT '(' expr_list_decl ')'
  474. { $$ = FuncCallExprNode::alloc($3, $1, $5, false); }
  475. | expr '.' IDENT '(' expr_list_decl ')'
  476. { $1->append($5); $$ = FuncCallExprNode::alloc($3, NULL, $1, true); }
  477. ;
  478. expr_list_decl
  479. :
  480. { $$ = NULL; }
  481. | expr_list
  482. { $$ = $1; }
  483. ;
  484. expr_list
  485. : expr
  486. { $$ = $1; }
  487. | expr_list ',' expr
  488. { ($1)->append($3); $$ = $1; }
  489. ;
  490. slot_assign_list
  491. : slot_assign
  492. { $$ = $1; }
  493. | slot_assign_list slot_assign
  494. { $1->append($2); $$ = $1; }
  495. ;
  496. slot_assign
  497. : IDENT '=' expr ';'
  498. { $$ = SlotAssignNode::alloc(NULL, NULL, $1, $3); }
  499. | rwDATABLOCK '=' expr ';'
  500. { $$ = SlotAssignNode::alloc(NULL, NULL, StringTable->insert("datablock"), $3); }
  501. | IDENT '[' aidx_expr ']' '=' expr ';'
  502. { $$ = SlotAssignNode::alloc(NULL, $3, $1, $6); }
  503. ;
  504. aidx_expr
  505. : expr
  506. { $$ = $1; }
  507. | aidx_expr ',' expr
  508. { $$ = CommaCatExprNode::alloc($1, $3); }
  509. ;
  510. %%