PageRenderTime 365ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/grammary.y

https://gitlab.com/gcmc/gcmc
Happy | 1117 lines | 1016 code | 101 blank | 0 comment | 0 complexity | e19d02ae292eff4f822b62e118f87b8a MD5 | raw file
Possible License(s): GPL-3.0
  1. /*
  2. * G-code meta compiler
  3. *
  4. * Copyright (C) 2013 B. Stultiens
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. %{
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <assert.h>
  23. #include "utils.h"
  24. #include "grammartypes.h"
  25. #include "builtin.h"
  26. #include "interpreter.h"
  27. #define myassert(x) do { \
  28. if(!(x)) { \
  29. yyfatal("Assertion failed:(%s:%d): %s", __FILE__, __LINE__, #x); \
  30. } \
  31. } while(0);
  32. int yylex(void);
  33. static char *funcname;
  34. static node_t *newnode(int type);
  35. static node_t *alist_new(char *id, int isref, node_t *e);
  36. static node_t *alist_add(node_t *l, char *id, int isref, node_t *e);
  37. static node_t *lvar_new(char *id, node_t *e);
  38. static node_t *cvar_new(char *id, node_t *e);
  39. static node_t *elist_new(node_t *e);
  40. static node_t *elist_add(node_t *l, node_t *e);
  41. static node_t *vlist_new(node_t *v);
  42. static node_t *vlist_add(node_t *l, node_t *v);
  43. static node_t *vec_new(node_t *e, int allownull);
  44. static node_t *vec_add(node_t *v, node_t *e);
  45. static node_t *node_new_assign(node_t *lv, int op, node_t *rv);
  46. static node_t *node_new(int op, node_t *e);
  47. static node_t *node_add(node_t *tailnode, node_t *newnode);
  48. static node_t *expr_new(node_t *l, node_t *r, int op);
  49. static node_t *expr_new_unary(node_t *id, int op);
  50. static node_t *expr_new_tern(node_t *c, node_t *l, node_t *r, int op);
  51. static node_t *expr_new_call(char *id, node_t *e);
  52. static node_t *expr_new_id(char *id);
  53. static node_t *expr_new_idx(node_t *d, node_t *e);
  54. static node_t *expr_new_idxid(node_t *d, char *id);
  55. static node_t *expr_new_int(int i, int unit);
  56. static node_t *expr_new_flt(double d, int unit);
  57. static node_t *expr_new_str(char *str);
  58. static node_t *pushtag(node_t *n);
  59. static node_t *poptag(void);
  60. static node_t *gethead(node_t *n);
  61. static void checkfuncname(const char *fn);
  62. static void check_useless(const node_t *n);
  63. static void check_const_expr(const node_t *n);
  64. static void check_boolean_expr(const node_t *n);
  65. node_t *scripthead;
  66. %}
  67. %union{
  68. char *str;
  69. double d;
  70. int i;
  71. node_t *node;
  72. }
  73. /* Explicit tokens */
  74. %token FUNCTION FOR FOREACH DO WHILE IF ELIF ELSE BREAK CONTINUE RETURN INCLUDE LOCAL REPEAT CONST
  75. %token TOPEN TCLOSE MM MIL IN DEG RAD
  76. %token <str> IDENT STRING
  77. %token <i> NUMBER
  78. %token <d> FLOAT
  79. %right '=' SUBASSIGN ADDASSIGN MULASSIGN DIVASSIGN MODASSIGN SHLASSIGN SHRASSIGN ADDORASSIGN SUBORASSIGN BORASSIGN BANDASSIGN BXORASSIGN
  80. %right '?' ':'
  81. %left LOR
  82. %left LAND
  83. %left '|'
  84. %left '^'
  85. %left '&'
  86. %left EQ NE
  87. %left LT GT LE GE
  88. %left SHL SHR
  89. %left '+' '-' ADDOR SUBOR
  90. %left '*' '/' '%'
  91. %left INC DEC
  92. %right '!' '~' UPM
  93. %right '[' '.' UID
  94. %type <i> optunit optref
  95. %type <str> function
  96. %type <node> lines line compound optstmts stmt optstmt
  97. %type <node> optelif elif
  98. %type <node> arglist optv optarglist locals local optassgn
  99. %type <node> optargs args
  100. %type <node> expr boolexpr call anynum
  101. %type <node> nums vector
  102. %type <node> vlist veclist
  103. %type <node> cvars cvar
  104. %%
  105. file : /* Empty */ { ; }
  106. | lines { scripthead = gethead($1); }
  107. | lines error { yyerror("Syntax error"); }
  108. ;
  109. lines : line { $$ = $1; }
  110. | lines line { $$ = node_add($1, $2); }
  111. ;
  112. line : compound { $$ = $1; }
  113. | INCLUDE '(' STRING ')' ';' {
  114. /* Include files is a language construct */
  115. /* We should get here without a lookahead symbol */
  116. assert(yychar == YYEMPTY);
  117. handle_include($3); /* Setup flex */
  118. $$ = NULL;
  119. }
  120. | INCLUDE '(' STRING ')' error { $$ = NULL; yyerror("';' expected"); }
  121. | INCLUDE '(' STRING error { $$ = NULL; yyerror("')' expected"); }
  122. | INCLUDE '(' error { $$ = NULL; yyerror("String with include filename expected"); }
  123. | INCLUDE error { $$ = NULL; yyerror("'(' expected"); }
  124. | stmt ';' { $$ = $1; }
  125. | stmt error { $$ = NULL; yyerror("';' expected"); }
  126. | LOCAL locals ';' { $$ = $2; }
  127. | CONST cvars ';' { $$ = $2; }
  128. | ';' { $$ = NULL; }
  129. ;
  130. cvars : cvar { $$ = $1; }
  131. | cvars ',' cvar { $$ = node_add($1, $3); }
  132. ;
  133. cvar : IDENT '=' expr { $$ = cvar_new($1, $3); }
  134. | IDENT '=' error { $$ = NULL; yyerror("Expression expected"); }
  135. | IDENT error { $$ = NULL; yyerror("'=' expected"); }
  136. | error { $$ = NULL; yyerror("Identifier expected"); }
  137. ;
  138. optarglist: /* Empty */ { $$ = NULL; }
  139. | arglist { $$ = $1; }
  140. ;
  141. arglist : optref IDENT optv { $$ = alist_new($2, $1, $3); }
  142. | arglist ',' optref IDENT optv { $$ = alist_add($1, $4, $3, $5); }
  143. | arglist ',' error { $$ = NULL; yyerror("Identifier expected"); }
  144. ;
  145. optv : /* Empty */ { $$ = NULL; }
  146. | '=' expr { $$ = $2; }
  147. | '=' error { $$ = NULL; yyerror("Constant expression expected"); }
  148. ;
  149. optref : /* Empty */ { $$ = 0; }
  150. | '&' { $$ = 1; }
  151. ;
  152. locals : local { $$ = $1; }
  153. | locals ',' local { $$ = node_add($1, $3); }
  154. | locals ',' error { $$ = NULL; yyerror("Identifier expected"); }
  155. ;
  156. local : IDENT optassgn { $$ = lvar_new($1, $2); }
  157. | IDENT error { $$ = NULL; yyerror("Assignment expected"); }
  158. ;
  159. optassgn: /* Empty */ { $$ = NULL; }
  160. | '=' expr { $$ = $2; }
  161. ;
  162. optstmts: /* Empty */ { $$ = NULL; }
  163. | lines { $$ = gethead($1); }
  164. ;
  165. stmt : expr { $$ = $1; check_const_expr($1); }
  166. ;
  167. optstmt : /* Empty */ { $$ = NULL; }
  168. | stmt { $$ = $1; }
  169. ;
  170. foreach : FOREACH { pushtag(newnode(NT_FOREACH)); }
  171. ;
  172. repeat : REPEAT { pushtag(newnode(NT_REPEAT)); }
  173. ;
  174. for : FOR { pushtag(newnode(NT_FOR)); }
  175. ;
  176. while : WHILE { pushtag(newnode(NT_WHILE)); }
  177. ;
  178. do : DO { pushtag(newnode(NT_DOWHILE)); }
  179. ;
  180. function: FUNCTION IDENT {
  181. if(funcname)
  182. yyerror("Function in functions not supported");
  183. checkfuncname($2);
  184. $$ = funcname = $2;
  185. }
  186. | FUNCTION error { $$ = NULL; yyerror("Function name expected"); }
  187. ;
  188. boolexpr: expr { $$ = $1; check_boolean_expr($$); }
  189. ;
  190. compound: foreach '(' expr ';' IDENT ')' TOPEN optstmts TCLOSE {
  191. $$ = poptag();
  192. $$->lfe.src = $3;
  193. $$->lfe.dst = $5;
  194. $$->lfe.stmts = $8;
  195. }
  196. | foreach '(' expr ';' IDENT ')' TOPEN optstmts error { $$ = NULL; yyerror("'}' expected"); }
  197. | foreach '(' expr ';' IDENT ')' error { $$ = NULL; yyerror("'{' expected"); }
  198. | foreach '(' expr ';' IDENT error { $$ = NULL; yyerror("')' expected"); }
  199. | foreach '(' expr ';' error { $$ = NULL; yyerror("Identifier expected"); }
  200. | foreach '(' expr error { $$ = NULL; yyerror("';' expected"); }
  201. | foreach '(' error { $$ = NULL; yyerror("Vectorlist expression expected"); }
  202. | foreach error { $$ = NULL; yyerror("'(' expected"); }
  203. | repeat '(' expr ';' IDENT ')' TOPEN optstmts TCLOSE {
  204. $$ = poptag();
  205. $$->lfe.src = $3;
  206. $$->lfe.dst = $5;
  207. $$->lfe.stmts = $8;
  208. }
  209. | repeat '(' expr ')' TOPEN optstmts TCLOSE {
  210. $$ = poptag();
  211. $$->lfe.src = $3;
  212. $$->lfe.dst = NULL;
  213. $$->lfe.stmts = $6;
  214. }
  215. | repeat '(' expr ';' IDENT ')' TOPEN optstmts error { $$ = NULL; yyerror("'}' expected"); }
  216. | repeat '(' expr ';' IDENT ')' error { $$ = NULL; yyerror("'{' expected"); }
  217. | repeat '(' expr ';' IDENT error { $$ = NULL; yyerror("')' expected"); }
  218. | repeat '(' expr ';' error { $$ = NULL; yyerror("Identifier expected"); }
  219. | repeat '(' expr error { $$ = NULL; yyerror("';' or ')' expected"); }
  220. | repeat '(' error { $$ = NULL; yyerror("Integer expression expected"); }
  221. | repeat error { $$ = NULL; yyerror("'(' expected"); }
  222. | for '(' optstmt ';' boolexpr ';' optstmt ')' TOPEN optstmts TCLOSE {
  223. $$ = poptag();
  224. $$->lfor.init = $3;
  225. $$->lfor.cond = $5;
  226. $$->lfor.inc = $7;
  227. $$->lfor.stmts = $10;
  228. }
  229. | for '(' optstmt ';' boolexpr ';' optstmt ')' TOPEN optstmts error { $$ = NULL; yyerror("'}' expected"); }
  230. | for '(' optstmt ';' boolexpr ';' optstmt ')' error { $$ = NULL; yyerror("'{' expected"); }
  231. | for '(' optstmt ';' boolexpr ';' optstmt error { $$ = NULL; yyerror("')' expected"); }
  232. | for '(' optstmt ';' boolexpr error { $$ = NULL; yyerror("';' expected"); }
  233. | for '(' optstmt ';' error { $$ = NULL; yyerror("Conditional expression expected"); }
  234. | for '(' optstmt error { $$ = NULL; yyerror("';' expected"); }
  235. | for error { $$ = NULL; yyerror("'(' expected"); }
  236. | while '(' boolexpr ')' TOPEN optstmts TCLOSE {
  237. $$ = poptag();
  238. $$->lfor.cond = $3;
  239. $$->lfor.stmts = $6;
  240. }
  241. | while '(' boolexpr ')' TOPEN optstmts error { $$ = NULL; yyerror("'}' expected"); }
  242. | while '(' boolexpr ')' error { $$ = NULL; yyerror("'{' expected"); }
  243. | while '(' boolexpr error { $$ = NULL; yyerror("')' expected"); }
  244. | while '(' error { $$ = NULL; yyerror("Conditional expression expected"); }
  245. | while error { $$ = NULL; yyerror("'(' expected"); }
  246. | do TOPEN optstmts TCLOSE WHILE '(' boolexpr ')' ';' {
  247. $$ = poptag();
  248. $$->lfor.cond = $7;
  249. $$->lfor.stmts = $3;
  250. }
  251. | do TOPEN optstmts TCLOSE WHILE '(' boolexpr ')' error { $$ = NULL; yyerror("';' expected"); }
  252. | do TOPEN optstmts TCLOSE WHILE '(' boolexpr error { $$ = NULL; yyerror("')' expected"); }
  253. | do TOPEN optstmts TCLOSE WHILE '(' error { $$ = NULL; yyerror("Conditional expression expected"); }
  254. | do TOPEN optstmts TCLOSE WHILE error { $$ = NULL; yyerror("'(' expected"); }
  255. | do TOPEN optstmts TCLOSE error { $$ = NULL; yyerror("'while' expected"); }
  256. | do TOPEN optstmts error { $$ = NULL; yyerror("'}' expected"); }
  257. | do error { $$ = NULL; yyerror("'{' expected"); }
  258. | function '(' optarglist ')' TOPEN optstmts TCLOSE {
  259. $$ = newnode(NT_FUNCTION);
  260. $$->func.id = $1;
  261. $$->func.args = $3;
  262. $$->func.body = $6;
  263. funcname = NULL;
  264. }
  265. | function '(' optarglist ')' TOPEN optstmts error { $$ = NULL; yyerror("'}' expected"); funcname = NULL; }
  266. | function '(' optarglist ')' error { $$ = NULL; yyerror("'{' expected"); funcname = NULL; }
  267. | function '(' optarglist error { $$ = NULL; yyerror("')' expected"); funcname = NULL; }
  268. | function error { $$ = NULL; yyerror("'(' expected"); funcname = NULL; }
  269. | IF '(' boolexpr ')' TOPEN optstmts TCLOSE optelif {
  270. $$ = newnode(NT_IF);
  271. $$->cond.cond = $3;
  272. $$->cond.ifclause = $6;
  273. $$->cond.elifclauses = gethead($8);
  274. }
  275. | IF '(' boolexpr ')' TOPEN optstmts TCLOSE optelif ELSE TOPEN optstmts TCLOSE {
  276. $$ = newnode(NT_IF);
  277. $$->cond.cond = $3;
  278. $$->cond.ifclause = $6;
  279. $$->cond.elifclauses = gethead($8);
  280. $$->cond.elseclause = $11;
  281. }
  282. | IF '(' boolexpr ')' TOPEN optstmts TCLOSE optelif ELSE TOPEN optstmts error { $$ = NULL; yyerror("'}' expected"); }
  283. | IF '(' boolexpr ')' TOPEN optstmts TCLOSE optelif ELSE error { $$ = NULL; yyerror("'{' expected"); }
  284. | IF '(' boolexpr ')' TOPEN optstmts error { $$ = NULL; yyerror("'}' expected"); }
  285. | IF '(' boolexpr ')' error { $$ = NULL; yyerror("'{' expected"); }
  286. | IF '(' boolexpr error { $$ = NULL; yyerror("')' expected"); }
  287. | IF '(' error { $$ = NULL; yyerror("Conditional expression expected"); }
  288. | IF error { $$ = NULL; yyerror("'(' expected"); }
  289. | RETURN expr ';' { $$ = node_new(NT_RETURN, $2); }
  290. | RETURN ';' { $$ = node_new(NT_RETURN, NULL); }
  291. | RETURN error { $$ = NULL; yyerror("Expression or ';' expected"); }
  292. | RETURN expr error { $$ = NULL; yyerror("';' expected"); }
  293. | BREAK ';' { $$ = node_new(NT_BREAK, NULL); }
  294. | BREAK error { $$ = NULL; yyerror("';' expected"); }
  295. | CONTINUE ';' { $$ = node_new(NT_CONTINUE, NULL); }
  296. | CONTINUE error { $$ = NULL; yyerror("';' expected"); }
  297. ;
  298. optelif : /* Empty */ { $$ = NULL; }
  299. | optelif elif { $$ = $2; if($1) { $1->next = $2; $2->prev = $1;} }
  300. ;
  301. elif : ELIF '(' boolexpr ')' TOPEN optstmts TCLOSE { $$ = newnode(NT_ELIF); $$->cond.cond = $3; $$->cond.ifclause = $6; }
  302. | ELIF '(' boolexpr ')' TOPEN optstmts error { $$ = NULL; yyerror("'}' expected"); }
  303. | ELIF '(' boolexpr ')' error { $$ = NULL; yyerror("'{' expected"); }
  304. | ELIF '(' boolexpr error { $$ = NULL; yyerror("')' expected"); }
  305. | ELIF '(' error { $$ = NULL; yyerror("Conditional expression expected"); }
  306. | ELIF error { $$ = NULL; yyerror("'(' expected"); }
  307. ;
  308. call : IDENT '(' optargs ')' { $$ = expr_new_call($1, $3); }
  309. ;
  310. optargs : /* Empty */ { $$ = NULL; }
  311. | args { $$ = $1; }
  312. ;
  313. args : expr { $$ = elist_new($1); }
  314. | args ',' expr { $$ = elist_add($1, $3); }
  315. | args ',' error { $$ = $1; yyerror("Expression expected after ','"); }
  316. | args error { $$ = $1; yyerror("',' expected"); }
  317. ;
  318. expr : '+' expr %prec UPM { $$ = $2; }
  319. | '-' expr %prec UPM { $$ = expr_new($2, expr_new_int(-1, UNIT_NONE), OP_MUL); }
  320. | '!' expr { $$ = expr_new($2, NULL, OP_NOT); }
  321. | '~' expr { $$ = expr_new($2, NULL, OP_BNOT); }
  322. | '(' expr ')' { $$ = $2; $$->expr.inparen = 1; }
  323. | expr '+' expr { $$ = expr_new($1, $3, OP_ADD); }
  324. | expr ADDOR expr { $$ = expr_new($1, $3, OP_ADDOR); }
  325. | expr '-' expr { $$ = expr_new($1, $3, OP_SUB); }
  326. | expr SUBOR expr { $$ = expr_new($1, $3, OP_SUBOR); }
  327. | expr '*' expr { $$ = expr_new($1, $3, OP_MUL); }
  328. | expr '/' expr { $$ = expr_new($1, $3, OP_DIV); }
  329. | expr '%' expr { $$ = expr_new($1, $3, OP_MOD); }
  330. | expr EQ expr { $$ = expr_new($1, $3, OP_EQ); }
  331. | expr NE expr { $$ = expr_new($1, $3, OP_NE); }
  332. | expr GT expr { $$ = expr_new($1, $3, OP_GT); }
  333. | expr LT expr { $$ = expr_new($1, $3, OP_LT); }
  334. | expr GE expr { $$ = expr_new($1, $3, OP_GE); }
  335. | expr LE expr { $$ = expr_new($1, $3, OP_LE); }
  336. | expr LAND expr { $$ = expr_new($1, $3, OP_LAND); }
  337. | expr LOR expr { $$ = expr_new($1, $3, OP_LOR); }
  338. | expr SHL expr { $$ = expr_new($1, $3, OP_SHL); }
  339. | expr SHR expr { $$ = expr_new($1, $3, OP_SHR); }
  340. | expr '&' expr { $$ = expr_new($1, $3, OP_BAND); }
  341. | expr '|' expr { $$ = expr_new($1, $3, OP_BOR); }
  342. | expr '^' expr { $$ = expr_new($1, $3, OP_BXOR); }
  343. | expr '?' expr ':' expr {$$ = expr_new_tern($1, $3, $5, OP_CONDEXPR); }
  344. | call { $$ = $1; }
  345. | expr '[' expr ']' { $$ = expr_new_idx($1, $3); }
  346. | expr '.' IDENT { $$ = expr_new_idxid($1, $3); }
  347. | IDENT { $$ = expr_new_id($1); }
  348. | NUMBER optunit { $$ = expr_new_int($1, $2); }
  349. | FLOAT optunit { $$ = expr_new_flt($1, $2); }
  350. | STRING { $$ = expr_new_str($1); }
  351. | vector { $$ = $1; }
  352. | veclist { $$ = $1; }
  353. | INC expr %prec UPM { $$ = expr_new_unary($2, OP_PREINC); }
  354. | DEC expr %prec UPM { $$ = expr_new_unary($2, OP_PREDEC); }
  355. | expr INC %prec UID { $$ = expr_new_unary($1, OP_POSTINC); check_useless($$); }
  356. | expr DEC %prec UID { $$ = expr_new_unary($1, OP_POSTDEC); check_useless($$); }
  357. | expr '=' expr { $$ = node_new_assign($1, OP_ASSIGN, $3); }
  358. | expr ADDASSIGN expr { $$ = node_new_assign($1, OP_ADDASSIGN, $3); }
  359. | expr ADDORASSIGN expr { $$ = node_new_assign($1, OP_ADDORASSIGN, $3); }
  360. | expr SUBASSIGN expr { $$ = node_new_assign($1, OP_SUBASSIGN, $3); }
  361. | expr SUBORASSIGN expr { $$ = node_new_assign($1, OP_SUBORASSIGN, $3); }
  362. | expr MULASSIGN expr { $$ = node_new_assign($1, OP_MULASSIGN, $3); }
  363. | expr DIVASSIGN expr { $$ = node_new_assign($1, OP_DIVASSIGN, $3); }
  364. | expr MODASSIGN expr { $$ = node_new_assign($1, OP_MODASSIGN, $3); }
  365. | expr SHLASSIGN expr { $$ = node_new_assign($1, OP_SHLASSIGN, $3); }
  366. | expr SHRASSIGN expr { $$ = node_new_assign($1, OP_SHRASSIGN, $3); }
  367. | expr BORASSIGN expr { $$ = node_new_assign($1, OP_BORASSIGN, $3); }
  368. | expr BANDASSIGN expr { $$ = node_new_assign($1, OP_BANDASSIGN, $3); }
  369. | expr BXORASSIGN expr { $$ = node_new_assign($1, OP_BXORASSIGN, $3); }
  370. | expr '=' error { $$ = $1; yyerror("Expression expected after '='"); }
  371. | expr ADDASSIGN error { $$ = $1; yyerror("Expression expected after '+='"); }
  372. | expr ADDORASSIGN error{ $$ = $1; yyerror("Expression expected after '+|='"); }
  373. | expr SUBASSIGN error { $$ = $1; yyerror("Expression expected after '-='"); }
  374. | expr SUBORASSIGN error{ $$ = $1; yyerror("Expression expected after '-|='"); }
  375. | expr MULASSIGN error { $$ = $1; yyerror("Expression expected after '*='"); }
  376. | expr DIVASSIGN error { $$ = $1; yyerror("Expression expected after '/='"); }
  377. | expr MODASSIGN error { $$ = $1; yyerror("Expression expected after '%%='"); }
  378. | expr SHLASSIGN error { $$ = $1; yyerror("Expression expected after '<<='"); }
  379. | expr SHRASSIGN error { $$ = $1; yyerror("Expression expected after '>>='"); }
  380. | expr BORASSIGN error { $$ = $1; yyerror("Expression expected after '|='"); }
  381. | expr BANDASSIGN error { $$ = $1; yyerror("Expression expected after '&='"); }
  382. | expr BXORASSIGN error { $$ = $1; yyerror("Expression expected after '^='"); }
  383. ;
  384. optunit : /* Empty */ { $$ = UNIT_NONE; }
  385. | MM { $$ = UNIT_MM; }
  386. | MIL { $$ = _UNIT_MIL; }
  387. | IN { $$ = UNIT_IN; }
  388. | DEG { $$ = UNIT_DEG; }
  389. | RAD { $$ = UNIT_RAD; }
  390. ;
  391. optcomma: /* Empty */
  392. | ','
  393. ;
  394. veclist : TOPEN vlist optcomma TCLOSE { $$ = $2; }
  395. | TOPEN TCLOSE { $$ = vlist_new(NULL); }
  396. | TOPEN error { $$ = NULL; yyerror("'}' expected"); }
  397. | TOPEN vlist optcomma error { $$ = $2; yyerror("'}' expected"); }
  398. ;
  399. vlist : expr { $$ = vlist_new($1); }
  400. | vlist ',' expr { $$ = vlist_add($1, $3); }
  401. ;
  402. vector : '[' ']' { $$ = vec_new(NULL, 0); }
  403. | '[' nums ']' { $$ = $2; }
  404. | '[' nums error { $$ = $2; yyerror("']' expected"); }
  405. ;
  406. nums : anynum { $$ = vec_new($1, 1); }
  407. | nums ',' anynum { $$ = vec_add($1, $3); }
  408. | nums ',' error { $$ = $1; yyerror("Scalar expression or '-' expected"); }
  409. ;
  410. anynum : '-' { $$ = NULL; }
  411. | expr { $$ = $1; }
  412. ;
  413. %%
  414. static node_t *newnode(int type)
  415. {
  416. node_t *n = calloc(1, sizeof(node_t));
  417. myassert(n != NULL);
  418. n->type = type;
  419. n->linenr = prevlinenr;
  420. n->charnr = prevcharnr;
  421. n->filename = filename;
  422. return n;
  423. }
  424. static node_t *newnlist(node_t *n, int i)
  425. {
  426. n->nlist.na = i;
  427. n->nlist.nodes = calloc(i, sizeof(n->nlist.nodes[0]));
  428. myassert(n->nlist.nodes != NULL);
  429. return n;
  430. }
  431. static node_t *newalist(node_t *n, int i)
  432. {
  433. n->alist.na = i;
  434. n->alist.args = calloc(i, sizeof(n->alist.args[0]));
  435. myassert(n->alist.args != NULL);
  436. return n;
  437. }
  438. static node_t *alist_new(char *id, int isref, node_t *e)
  439. {
  440. node_t *n = newnode(NT_ARGLIST);
  441. myassert(!e || (e && !isref));
  442. newalist(n, 4);
  443. n->alist.n = 1;
  444. n->alist.args[0].id = id;
  445. n->alist.args[0].isref = isref;
  446. n->alist.args[0].expr = e;
  447. return n;
  448. }
  449. static node_t *alist_add(node_t *l, char *id, int isref, node_t *e)
  450. {
  451. int i;
  452. int havedef = 0;
  453. myassert(l->type == NT_ARGLIST);
  454. myassert(!e || (e && !isref));
  455. testalloc((void **)&l->alist.args, l->alist.n, &l->alist.na, sizeof(l->alist.args[0]));
  456. for(i = 0; i < l->alist.n; i++) {
  457. if(!strcmp(id, l->alist.args[i].id)) {
  458. yyerror("Argument %d's name '%s' already used in argument %d", l->alist.n+1, id, i+1);
  459. return l;
  460. }
  461. if(l->alist.args[i].expr)
  462. havedef = 1;
  463. }
  464. if(!e && havedef)
  465. yyerror("Argument %d (%s) must include default value", l->alist.n+1, id);
  466. if(e && isref)
  467. yyerror("Argument %d (%s) cannot be both a reference and have a default value", l->alist.n+1, id);
  468. l->alist.args[l->alist.n].id = id;
  469. l->alist.args[l->alist.n].isref = isref;
  470. l->alist.args[l->alist.n].expr = e;
  471. l->alist.n++;
  472. return l;
  473. }
  474. static node_t *lvar_new(char *id, node_t *e)
  475. {
  476. node_t *n = newnode(NT_LOCAL);
  477. n->lvar.id = id;
  478. n->lvar.init = e;
  479. return n;
  480. }
  481. static node_t *cvar_new(char *id, node_t *e)
  482. {
  483. node_t *n = newnode(NT_CONST);
  484. n->cvar.id = id;
  485. n->cvar.init = e;
  486. return n;
  487. }
  488. static node_t *elist_new(node_t *e)
  489. {
  490. node_t *n = newnode(NT_EXPRLIST);
  491. newnlist(n, 4);
  492. n->nlist.n = 1;
  493. n->nlist.nodes[0] = e;
  494. return n;
  495. }
  496. static node_t *elist_add(node_t *l, node_t *e)
  497. {
  498. myassert(e->type == NT_EXPR);
  499. myassert(l->type == NT_EXPRLIST);
  500. testalloc((void **)&l->nlist.nodes, l->nlist.n, &l->nlist.na, sizeof(l->nlist.nodes[0]));
  501. l->nlist.nodes[l->nlist.n] = e;
  502. l->nlist.n++;
  503. return l;
  504. }
  505. static node_t *vlist_new(node_t *v)
  506. {
  507. myassert(v == NULL || v->type == NT_EXPR);
  508. node_t *n = newnode(NT_EXPR);
  509. n->expr.op = OP_VECTORLIST;
  510. n->expr.nlist.na = 4;
  511. n->expr.nlist.nodes = calloc(4, sizeof(n->expr.nlist.nodes[0]));
  512. myassert(n->expr.nlist.nodes != NULL);
  513. if(v) {
  514. n->expr.nlist.n = 1;
  515. n->expr.nlist.nodes[0] = v;
  516. }
  517. return n;
  518. }
  519. static node_t *vlist_add(node_t *l, node_t *v)
  520. {
  521. myassert(l->type == NT_EXPR);
  522. myassert(l->expr.op == OP_VECTORLIST);
  523. myassert(v->type == NT_EXPR);
  524. testalloc((void **)&l->expr.nlist.nodes, l->expr.nlist.n, &l->expr.nlist.na, sizeof(l->expr.nlist.nodes[0]));
  525. l->expr.nlist.nodes[l->expr.nlist.n] = v;
  526. l->expr.nlist.n++;
  527. return l;
  528. }
  529. static node_t *vec_new(node_t *e, int allownull)
  530. {
  531. node_t *n = newnode(NT_EXPR);
  532. n->expr.op = OP_VECTOR;
  533. n->expr.nlist.na = 4;
  534. n->expr.nlist.nodes = calloc(4, sizeof(n->expr.nlist.nodes[0]));
  535. myassert(n->expr.nlist.nodes != NULL);
  536. if(allownull || e) {
  537. n->expr.nlist.n = 1;
  538. n->expr.nlist.nodes[0] = e;
  539. }
  540. return n;
  541. }
  542. static node_t *vec_add(node_t *v, node_t *e)
  543. {
  544. myassert(v->type == NT_EXPR);
  545. myassert(v->expr.op == OP_VECTOR);
  546. testalloc((void **)&v->expr.nlist.nodes, v->expr.nlist.n, &v->expr.nlist.na, sizeof(v->expr.nlist.nodes[0]));
  547. v->expr.nlist.nodes[v->expr.nlist.n] = e;
  548. v->expr.nlist.n++;
  549. return v;
  550. }
  551. static node_t *node_new_assign(node_t *lv, int op, node_t *rv)
  552. {
  553. node_t *n = newnode(NT_EXPR);
  554. n->expr.op = op;
  555. n->expr.left = lv;
  556. n->expr.right = rv;
  557. check_useless(n);
  558. return n;
  559. }
  560. static node_t *node_new(int nt, node_t *e)
  561. {
  562. node_t *n = newnode(nt);
  563. n->eref = e;
  564. return n;
  565. }
  566. static node_t *node_add(node_t *tailnode, node_t *newnode)
  567. {
  568. node_t *nnhead = newnode;
  569. node_t *nntail = newnode;
  570. /* Find real head and tail of the new node(s) */
  571. if(newnode) {
  572. while(nnhead->prev)
  573. nnhead = nnhead->prev;
  574. while(nntail->next)
  575. nntail = nntail->next;
  576. }
  577. if(!tailnode)
  578. return nntail; /* Always return the real tail */
  579. /* Find the tail's real tail */
  580. while(tailnode->next)
  581. tailnode = tailnode->next;
  582. if(!newnode)
  583. return tailnode;
  584. /* Crosslink to append new nodes */
  585. tailnode->next = nnhead;
  586. nnhead->prev = tailnode;
  587. return nntail; /* Return the real tail of the combined list */
  588. }
  589. static node_t *expr_new(node_t *l, node_t *r, int op)
  590. {
  591. node_t *n = newnode(NT_EXPR);
  592. myassert(l != NULL);
  593. n->expr.op = op;
  594. n->expr.left = l;
  595. n->expr.right = r;
  596. return n;
  597. }
  598. static node_t *expr_new_unary(node_t *id, int op)
  599. {
  600. node_t *n = newnode(NT_EXPR);
  601. n->expr.op = op;
  602. n->expr.left = id;
  603. return n;
  604. }
  605. static node_t *expr_new_tern(node_t *c, node_t *l, node_t *r, int op)
  606. {
  607. node_t *n = newnode(NT_EXPR);
  608. myassert(c != NULL);
  609. myassert(l != NULL);
  610. myassert(r != NULL);
  611. n->expr.op = op;
  612. n->expr.cond = c;
  613. n->expr.left = l;
  614. n->expr.right = r;
  615. return n;
  616. }
  617. static node_t *expr_new_call(char *id, node_t *e)
  618. {
  619. node_t *n = newnode(NT_EXPR);
  620. myassert(e == NULL || e->type == NT_EXPRLIST);
  621. n->expr.id = id;
  622. n->expr.args = e;
  623. n->expr.op = OP_CALL;
  624. return n;
  625. }
  626. static node_t *expr_new_id(char *id)
  627. {
  628. node_t *n = newnode(NT_EXPR);
  629. n->expr.op = OP_DEREF;
  630. n->expr.id = id;
  631. if(!strcmp("__global_offset", n->expr.id) || !strcmp("__global_position", n->expr.id))
  632. rtwarning(n, "Using internal variable '%s' strongly discouraged", n->expr.id);
  633. return n;
  634. }
  635. static node_t *expr_new_idx(node_t *d, node_t *e)
  636. {
  637. node_t *n = newnode(NT_EXPR);
  638. n->expr.op = OP_INDEX;
  639. n->expr.left = d;
  640. n->expr.right = e;
  641. return n;
  642. }
  643. static const char axisnames[] = "xyzabcuvw";
  644. static node_t *expr_new_idxid(node_t *d, char *id)
  645. {
  646. node_t *n = newnode(NT_EXPR);
  647. assert(id != NULL);
  648. n->expr.op = OP_INDEXID;
  649. n->expr.left = d;
  650. char *cptr = strchr(axisnames, id[0]);
  651. if(!cptr || 1 != strlen(id))
  652. yyerror("Index can only be an axis name");
  653. n->expr.right = expr_new_int(cptr - axisnames, UNIT_NONE);
  654. return n;
  655. }
  656. static node_t *expr_new_int(int i, int unit)
  657. {
  658. node_t *n = newnode(NT_EXPR);
  659. if(unit == _UNIT_MIL) {
  660. n->expr.op = OP_FLOAT;
  661. n->expr.d = (double)i / 1000.0;
  662. n->expr.unit = UNIT_IN;
  663. } else {
  664. n->expr.op = OP_INT;
  665. n->expr.i = i;
  666. n->expr.unit = unit;
  667. }
  668. return n;
  669. }
  670. static node_t *expr_new_flt(double d, int unit)
  671. {
  672. node_t *n = newnode(NT_EXPR);
  673. n->expr.op = OP_FLOAT;
  674. if(unit == _UNIT_MIL) {
  675. d /= 1000.0;
  676. unit = UNIT_IN;
  677. }
  678. n->expr.d = d;
  679. n->expr.unit = unit;
  680. return n;
  681. }
  682. static node_t *expr_new_str(char *str)
  683. {
  684. node_t *n = newnode(NT_EXPR);
  685. n->expr.op = OP_STRING;
  686. n->expr.id = str;
  687. return n;
  688. }
  689. static node_t **nodestack;
  690. static int nnodestack;
  691. static int nanodestack;
  692. static node_t *pushtag(node_t *n)
  693. {
  694. if(!nodestack) {
  695. nodestack = calloc(16, sizeof(*nodestack));
  696. assert(nodestack != NULL);
  697. nnodestack = 0;
  698. nanodestack = 16;
  699. } else if(nnodestack >= nanodestack) {
  700. nodestack = realloc(nodestack, nanodestack * 2 * sizeof(*nodestack));
  701. assert(nodestack != NULL);
  702. nanodestack *= 2;
  703. }
  704. nodestack[nnodestack] = n;
  705. nnodestack++;
  706. return n;
  707. }
  708. static node_t *poptag(void)
  709. {
  710. assert(nnodestack > 0);
  711. nnodestack--;
  712. return nodestack[nnodestack];
  713. }
  714. static node_t *gethead(node_t *n)
  715. {
  716. if(!n)
  717. return NULL;
  718. while(n->prev)
  719. n = n->prev;
  720. return n;
  721. }
  722. void node_delete(node_t *head)
  723. {
  724. node_t *n, *next;
  725. int i;
  726. if(nodestack) {
  727. free(nodestack);
  728. nodestack = NULL;
  729. }
  730. if(!head)
  731. return;
  732. for(n = head; n; n = next) {
  733. next = n->next;
  734. switch(n->type) {
  735. case NT_EXPRLIST:
  736. for(i = 0; i < n->nlist.n; i++)
  737. node_delete(n->nlist.nodes[i]);
  738. free(n->nlist.nodes);
  739. break;
  740. case NT_ARGLIST:
  741. for(i = 0; i < n->alist.n; i++)
  742. free(n->alist.args[i].id);
  743. free(n->alist.args);
  744. break;
  745. case NT_RETURN:
  746. case NT_LOCAL:
  747. node_delete(n->lvar.init);
  748. free(n->lvar.id);
  749. break;
  750. case NT_CONST:
  751. node_delete(n->cvar.init);
  752. free(n->cvar.id);
  753. break;
  754. case NT_BREAK:
  755. case NT_CONTINUE:
  756. case NT_INVALID:
  757. break;
  758. case NT_EXPR:
  759. node_delete(n->expr.left);
  760. node_delete(n->expr.right);
  761. switch(n->expr.op) {
  762. case OP_NULL:
  763. break;
  764. case OP_ADD:
  765. case OP_ADDOR:
  766. case OP_SUB:
  767. case OP_SUBOR:
  768. case OP_MUL:
  769. case OP_DIV:
  770. case OP_MOD:
  771. case OP_LOR:
  772. case OP_LAND:
  773. case OP_BOR:
  774. case OP_BXOR:
  775. case OP_BAND:
  776. case OP_BNOT:
  777. case OP_EQ:
  778. case OP_NE:
  779. case OP_GT:
  780. case OP_LT:
  781. case OP_GE:
  782. case OP_LE:
  783. case OP_SHL:
  784. case OP_SHR:
  785. case OP_NOT:
  786. case OP_INT:
  787. case OP_FLOAT:
  788. break;
  789. case OP_CONDEXPR:
  790. node_delete(n->expr.cond);
  791. break;
  792. case OP_CALL:
  793. node_delete(n->expr.args);
  794. free(n->expr.id);
  795. break;
  796. case OP_ASSIGN:
  797. case OP_ADDASSIGN:
  798. case OP_ADDORASSIGN:
  799. case OP_SUBASSIGN:
  800. case OP_SUBORASSIGN:
  801. case OP_MULASSIGN:
  802. case OP_DIVASSIGN:
  803. case OP_MODASSIGN:
  804. case OP_SHLASSIGN:
  805. case OP_SHRASSIGN:
  806. case OP_BORASSIGN:
  807. case OP_BANDASSIGN:
  808. case OP_BXORASSIGN:
  809. case OP_INDEX:
  810. case OP_INDEXID:
  811. break;
  812. case OP_STRING:
  813. case OP_DEREF:
  814. free(n->expr.id);
  815. break;
  816. case OP_PREINC:
  817. case OP_PREDEC:
  818. case OP_POSTINC:
  819. case OP_POSTDEC:
  820. break;
  821. case OP_VECTOR:
  822. case OP_VECTORLIST:
  823. for(i = 0; i < n->expr.nlist.n; i++)
  824. node_delete(n->expr.nlist.nodes[i]);
  825. free(n->expr.nlist.nodes);
  826. break;
  827. }
  828. break;
  829. case NT_IF:
  830. node_delete(n->cond.cond);
  831. node_delete(n->cond.ifclause);
  832. node_delete(n->cond.elifclauses);
  833. node_delete(n->cond.elseclause);
  834. break;
  835. case NT_ELIF:
  836. node_delete(n->cond.cond);
  837. node_delete(n->cond.ifclause);
  838. break;
  839. case NT_FOR:
  840. case NT_WHILE:
  841. case NT_DOWHILE:
  842. node_delete(n->lfor.stmts);
  843. node_delete(n->lfor.init);
  844. node_delete(n->lfor.cond);
  845. node_delete(n->lfor.inc);
  846. break;
  847. case NT_FOREACH:
  848. case NT_REPEAT:
  849. node_delete(n->lfe.stmts);
  850. node_delete(n->lfe.src);
  851. if(n->lfe.dst)
  852. free(n->lfe.dst);
  853. break;
  854. case NT_FUNCTION:
  855. node_delete(n->func.args);
  856. node_delete(n->func.body);
  857. free(n->func.id);
  858. break;
  859. }
  860. free(n);
  861. }
  862. }
  863. static const char **funcs;
  864. static int nfuncs;
  865. static int nafuncs;
  866. const builtins_t *find_builtin(const char *s);
  867. static void checkfuncname(const char *fn)
  868. {
  869. int i;
  870. if(find_builtin(fn)) {
  871. yyerror("Function name '%s' reserved as built-in function", fn);
  872. return;
  873. }
  874. for(i = 0; i < nfuncs; i++) {
  875. if(!strcmp(fn , funcs[i])) {
  876. yyerror("Function name '%s' is already defined", fn);
  877. return;
  878. }
  879. }
  880. testalloc((void **)&funcs, nfuncs, &nafuncs, sizeof(*funcs));
  881. funcs[nfuncs] = fn;
  882. nfuncs++;
  883. }
  884. void parser_cleanup(void)
  885. {
  886. if(funcs) {
  887. free(funcs);
  888. funcs = NULL;
  889. nafuncs = nfuncs = 0;
  890. }
  891. }
  892. static int findderef(const node_t *n)
  893. {
  894. const node_t *lv;
  895. /* Check if lvalue (left) is dereference-able */
  896. assert(n->expr.left != NULL);
  897. if(n->expr.inparen)
  898. return -1;
  899. for(lv = n->expr.left; lv; lv = lv->expr.left) {
  900. myassert(n->type == NT_EXPR);
  901. if(lv->expr.inparen)
  902. return -1;
  903. if(!lv->expr.left)
  904. break;
  905. }
  906. assert(lv != NULL);
  907. if(lv->expr.op == OP_DEREF) {
  908. if(!strcmp("__global_offset", lv->expr.id) || !strcmp("__global_position", lv->expr.id))
  909. yyerror("Assigning to read-only variable '%s' not allowed", lv->expr.id);
  910. return 1; /* Deref operation works on IDENT --> OK */
  911. }
  912. return -1;
  913. }
  914. static void check_useless(const node_t *n)
  915. {
  916. assert(n != NULL);
  917. myassert(n->type == NT_EXPR);
  918. switch(n->expr.op) {
  919. case OP_CALL:
  920. /* Calls are fine */
  921. return;
  922. case OP_POSTINC:
  923. case OP_POSTDEC:
  924. /* Post inc/dec on a constant has no effect */
  925. if(findderef(n) >= 0)
  926. return;
  927. yyerror("Statement post-%s on a constant has no effect", n->expr.op == OP_POSTINC ? "increment" : "decrement");
  928. break;
  929. case OP_ASSIGN:
  930. case OP_ADDASSIGN:
  931. case OP_ADDORASSIGN:
  932. case OP_SUBASSIGN:
  933. case OP_SUBORASSIGN:
  934. case OP_MULASSIGN:
  935. case OP_DIVASSIGN:
  936. case OP_MODASSIGN:
  937. case OP_SHLASSIGN:
  938. case OP_SHRASSIGN:
  939. case OP_BORASSIGN:
  940. case OP_BANDASSIGN:
  941. case OP_BXORASSIGN:
  942. if(findderef(n) >= 0 && !n->expr.inparen)
  943. return;
  944. /* Fallthrough */
  945. default:
  946. yyerror("Lvalue not a variable, cannot be dereferenced");
  947. return;
  948. }
  949. }
  950. static void check_const_expr(const node_t *n)
  951. {
  952. if(!n)
  953. return;
  954. myassert(n->type == NT_EXPR);
  955. switch(n->expr.op) {
  956. case OP_CALL:
  957. /* Calls are fine */
  958. return;
  959. case OP_ASSIGN:
  960. case OP_ADDASSIGN:
  961. case OP_ADDORASSIGN:
  962. case OP_SUBASSIGN:
  963. case OP_SUBORASSIGN:
  964. case OP_MULASSIGN:
  965. case OP_DIVASSIGN:
  966. case OP_MODASSIGN:
  967. case OP_SHLASSIGN:
  968. case OP_SHRASSIGN:
  969. case OP_BORASSIGN:
  970. case OP_BANDASSIGN:
  971. case OP_BXORASSIGN:
  972. /* We already check assignments */
  973. return;
  974. case OP_PREINC:
  975. case OP_PREDEC:
  976. case OP_POSTINC:
  977. case OP_POSTDEC:
  978. if(findderef(n) >= 0)
  979. return;
  980. /* Fallthrough */
  981. default:
  982. yyerror("Statement has no effect");
  983. return;
  984. }
  985. }
  986. static void check_boolean_expr(const node_t *n)
  987. {
  988. assert(n != NULL);
  989. myassert(n->type == NT_EXPR);
  990. switch(n->expr.op) {
  991. case OP_CALL:
  992. return;
  993. case OP_ASSIGN:
  994. case OP_ADDASSIGN:
  995. case OP_ADDORASSIGN:
  996. case OP_SUBASSIGN:
  997. case OP_SUBORASSIGN:
  998. case OP_MULASSIGN:
  999. case OP_DIVASSIGN:
  1000. case OP_MODASSIGN:
  1001. case OP_SHLASSIGN:
  1002. case OP_SHRASSIGN:
  1003. case OP_BORASSIGN:
  1004. case OP_BANDASSIGN:
  1005. case OP_BXORASSIGN:
  1006. if(!n->expr.inparen) {
  1007. rtwarning(n, "Assignment in boolean expression may be an inadvertent error, use () to force");
  1008. return;
  1009. }
  1010. default:
  1011. if(n->expr.left)
  1012. check_boolean_expr(n->expr.left);
  1013. if(n->expr.right)
  1014. check_boolean_expr(n->expr.right);
  1015. }
  1016. }