PR_COMP.C 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. #include "qcc.h"
  2. pr_info_t pr;
  3. def_t *pr_global_defs[MAX_REGS]; // to find def for a global variable
  4. int pr_edict_size;
  5. //========================================
  6. def_t *pr_scope; // the function being parsed, or NULL
  7. qboolean pr_dumpasm;
  8. string_t s_file; // filename for function definition
  9. int locals_end; // for tracking local variables vs temps
  10. jmp_buf pr_parse_abort; // longjump with this on parse error
  11. void PR_ParseDefs (void);
  12. //========================================
  13. opcode_t pr_opcodes[] =
  14. {
  15. {"<DONE>", "DONE", -1, false, &def_entity, &def_field, &def_void},
  16. {"*", "MUL_F", 2, false, &def_float, &def_float, &def_float},
  17. {"*", "MUL_V", 2, false, &def_vector, &def_vector, &def_float},
  18. {"*", "MUL_FV", 2, false, &def_float, &def_vector, &def_vector},
  19. {"*", "MUL_VF", 2, false, &def_vector, &def_float, &def_vector},
  20. {"/", "DIV", 2, false, &def_float, &def_float, &def_float},
  21. {"+", "ADD_F", 3, false, &def_float, &def_float, &def_float},
  22. {"+", "ADD_V", 3, false, &def_vector, &def_vector, &def_vector},
  23. {"-", "SUB_F", 3, false, &def_float, &def_float, &def_float},
  24. {"-", "SUB_V", 3, false, &def_vector, &def_vector, &def_vector},
  25. {"==", "EQ_F", 4, false, &def_float, &def_float, &def_float},
  26. {"==", "EQ_V", 4, false, &def_vector, &def_vector, &def_float},
  27. {"==", "EQ_S", 4, false, &def_string, &def_string, &def_float},
  28. {"==", "EQ_E", 4, false, &def_entity, &def_entity, &def_float},
  29. {"==", "EQ_FNC", 4, false, &def_function, &def_function, &def_float},
  30. {"!=", "NE_F", 4, false, &def_float, &def_float, &def_float},
  31. {"!=", "NE_V", 4, false, &def_vector, &def_vector, &def_float},
  32. {"!=", "NE_S", 4, false, &def_string, &def_string, &def_float},
  33. {"!=", "NE_E", 4, false, &def_entity, &def_entity, &def_float},
  34. {"!=", "NE_FNC", 4, false, &def_function, &def_function, &def_float},
  35. {"<=", "LE", 4, false, &def_float, &def_float, &def_float},
  36. {">=", "GE", 4, false, &def_float, &def_float, &def_float},
  37. {"<", "LT", 4, false, &def_float, &def_float, &def_float},
  38. {">", "GT", 4, false, &def_float, &def_float, &def_float},
  39. {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_float},
  40. {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_vector},
  41. {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_string},
  42. {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_entity},
  43. {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_field},
  44. {".", "INDIRECT", 1, false, &def_entity, &def_field, &def_function},
  45. {".", "ADDRESS", 1, false, &def_entity, &def_field, &def_pointer},
  46. {"=", "STORE_F", 5, true, &def_float, &def_float, &def_float},
  47. {"=", "STORE_V", 5, true, &def_vector, &def_vector, &def_vector},
  48. {"=", "STORE_S", 5, true, &def_string, &def_string, &def_string},
  49. {"=", "STORE_ENT", 5, true, &def_entity, &def_entity, &def_entity},
  50. {"=", "STORE_FLD", 5, true, &def_field, &def_field, &def_field},
  51. {"=", "STORE_FNC", 5, true, &def_function, &def_function, &def_function},
  52. {"=", "STOREP_F", 5, true, &def_pointer, &def_float, &def_float},
  53. {"=", "STOREP_V", 5, true, &def_pointer, &def_vector, &def_vector},
  54. {"=", "STOREP_S", 5, true, &def_pointer, &def_string, &def_string},
  55. {"=", "STOREP_ENT", 5, true, &def_pointer, &def_entity, &def_entity},
  56. {"=", "STOREP_FLD", 5, true, &def_pointer, &def_field, &def_field},
  57. {"=", "STOREP_FNC", 5, true, &def_pointer, &def_function, &def_function},
  58. {"<RETURN>", "RETURN", -1, false, &def_void, &def_void, &def_void},
  59. {"!", "NOT_F", -1, false, &def_float, &def_void, &def_float},
  60. {"!", "NOT_V", -1, false, &def_vector, &def_void, &def_float},
  61. {"!", "NOT_S", -1, false, &def_vector, &def_void, &def_float},
  62. {"!", "NOT_ENT", -1, false, &def_entity, &def_void, &def_float},
  63. {"!", "NOT_FNC", -1, false, &def_function, &def_void, &def_float},
  64. {"<IF>", "IF", -1, false, &def_float, &def_float, &def_void},
  65. {"<IFNOT>", "IFNOT", -1, false, &def_float, &def_float, &def_void},
  66. // calls returns REG_RETURN
  67. {"<CALL0>", "CALL0", -1, false, &def_function, &def_void, &def_void},
  68. {"<CALL1>", "CALL1", -1, false, &def_function, &def_void, &def_void},
  69. {"<CALL2>", "CALL2", -1, false, &def_function, &def_void, &def_void},
  70. {"<CALL3>", "CALL3", -1, false, &def_function, &def_void, &def_void},
  71. {"<CALL4>", "CALL4", -1, false, &def_function, &def_void, &def_void},
  72. {"<CALL5>", "CALL5", -1, false, &def_function, &def_void, &def_void},
  73. {"<CALL6>", "CALL6", -1, false, &def_function, &def_void, &def_void},
  74. {"<CALL7>", "CALL7", -1, false, &def_function, &def_void, &def_void},
  75. {"<CALL8>", "CALL8", -1, false, &def_function, &def_void, &def_void},
  76. {"<STATE>", "STATE", -1, false, &def_float, &def_float, &def_void},
  77. {"<GOTO>", "GOTO", -1, false, &def_float, &def_void, &def_void},
  78. {"&&", "AND", 6, false, &def_float, &def_float, &def_float},
  79. {"||", "OR", 6, false, &def_float, &def_float, &def_float},
  80. {"&", "BITAND", 2, false, &def_float, &def_float, &def_float},
  81. {"|", "BITOR", 2, false, &def_float, &def_float, &def_float},
  82. {NULL}
  83. };
  84. #define TOP_PRIORITY 6
  85. #define NOT_PRIORITY 4
  86. def_t *PR_Expression (int priority);
  87. def_t junkdef;
  88. //===========================================================================
  89. /*
  90. ============
  91. PR_Statement
  92. Emits a primitive statement, returning the var it places it's value in
  93. ============
  94. */
  95. def_t *PR_Statement ( opcode_t *op, def_t *var_a, def_t *var_b)
  96. {
  97. dstatement_t *statement;
  98. def_t *var_c;
  99. statement = &statements[numstatements];
  100. numstatements++;
  101. statement_linenums[statement-statements] = pr_source_line;
  102. statement->op = op - pr_opcodes;
  103. statement->a = var_a ? var_a->ofs : 0;
  104. statement->b = var_b ? var_b->ofs : 0;
  105. if (op->type_c == &def_void || op->right_associative)
  106. {
  107. var_c = NULL;
  108. statement->c = 0; // ifs, gotos, and assignments
  109. // don't need vars allocated
  110. }
  111. else
  112. { // allocate result space
  113. var_c = malloc (sizeof(def_t));
  114. memset (var_c, 0, sizeof(def_t));
  115. var_c->ofs = numpr_globals;
  116. var_c->type = op->type_c->type;
  117. statement->c = numpr_globals;
  118. numpr_globals += type_size[op->type_c->type->type];
  119. }
  120. if (op->right_associative)
  121. return var_a;
  122. return var_c;
  123. }
  124. /*
  125. ============
  126. PR_ParseImmediate
  127. Looks for a preexisting constant
  128. ============
  129. */
  130. def_t *PR_ParseImmediate (void)
  131. {
  132. def_t *cn;
  133. // check for a constant with the same value
  134. for (cn=pr.def_head.next ; cn ; cn=cn->next)
  135. {
  136. if (!cn->initialized)
  137. continue;
  138. if (cn->type != pr_immediate_type)
  139. continue;
  140. if (pr_immediate_type == &type_string)
  141. {
  142. if (!strcmp(G_STRING(cn->ofs), pr_immediate_string) )
  143. {
  144. PR_Lex ();
  145. return cn;
  146. }
  147. }
  148. else if (pr_immediate_type == &type_float)
  149. {
  150. if ( G_FLOAT(cn->ofs) == pr_immediate._float )
  151. {
  152. PR_Lex ();
  153. return cn;
  154. }
  155. }
  156. else if (pr_immediate_type == &type_vector)
  157. {
  158. if ( ( G_FLOAT(cn->ofs) == pr_immediate.vector[0] )
  159. && ( G_FLOAT(cn->ofs+1) == pr_immediate.vector[1] )
  160. && ( G_FLOAT(cn->ofs+2) == pr_immediate.vector[2] ) )
  161. {
  162. PR_Lex ();
  163. return cn;
  164. }
  165. }
  166. else
  167. PR_ParseError ("weird immediate type");
  168. }
  169. // allocate a new one
  170. cn = malloc (sizeof(def_t));
  171. cn->next = NULL;
  172. pr.def_tail->next = cn;
  173. pr.def_tail = cn;
  174. cn->search_next = pr.search;
  175. pr.search = cn;
  176. cn->type = pr_immediate_type;
  177. cn->name = "IMMEDIATE";
  178. cn->initialized = 1;
  179. cn->scope = NULL; // always share immediates
  180. // copy the immediate to the global area
  181. cn->ofs = numpr_globals;
  182. pr_global_defs[cn->ofs] = cn;
  183. numpr_globals += type_size[pr_immediate_type->type];
  184. if (pr_immediate_type == &type_string)
  185. pr_immediate.string = CopyString (pr_immediate_string);
  186. memcpy (pr_globals + cn->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
  187. PR_Lex ();
  188. return cn;
  189. }
  190. void PrecacheSound (def_t *e, int ch)
  191. {
  192. char *n;
  193. int i;
  194. if (!e->ofs)
  195. return;
  196. n = G_STRING(e->ofs);
  197. for (i=0 ; i<numsounds ; i++)
  198. if (!strcmp(n, precache_sounds[i]))
  199. return;
  200. if (numsounds == MAX_SOUNDS)
  201. Error ("PrecacheSound: numsounds == MAX_SOUNDS");
  202. strcpy (precache_sounds[i], n);
  203. if (ch >= '1' && ch <= '9')
  204. precache_sounds_block[i] = ch - '0';
  205. else
  206. precache_sounds_block[i] = 1;
  207. numsounds++;
  208. }
  209. void PrecacheModel (def_t *e, int ch)
  210. {
  211. char *n;
  212. int i;
  213. if (!e->ofs)
  214. return;
  215. n = G_STRING(e->ofs);
  216. for (i=0 ; i<nummodels ; i++)
  217. if (!strcmp(n, precache_models[i]))
  218. return;
  219. if (numsounds == MAX_SOUNDS)
  220. Error ("PrecacheModels: numsounds == MAX_SOUNDS");
  221. strcpy (precache_models[i], n);
  222. if (ch >= '1' && ch <= '9')
  223. precache_models_block[i] = ch - '0';
  224. else
  225. precache_models_block[i] = 1;
  226. nummodels++;
  227. }
  228. void PrecacheFile (def_t *e, int ch)
  229. {
  230. char *n;
  231. int i;
  232. if (!e->ofs)
  233. return;
  234. n = G_STRING(e->ofs);
  235. for (i=0 ; i<numfiles ; i++)
  236. if (!strcmp(n, precache_files[i]))
  237. return;
  238. if (numfiles == MAX_FILES)
  239. Error ("PrecacheFile: numfiles == MAX_FILES");
  240. strcpy (precache_files[i], n);
  241. if (ch >= '1' && ch <= '9')
  242. precache_files_block[i] = ch - '0';
  243. else
  244. precache_files_block[i] = 1;
  245. numfiles++;
  246. }
  247. /*
  248. ============
  249. PR_ParseFunctionCall
  250. ============
  251. */
  252. def_t *PR_ParseFunctionCall (def_t *func)
  253. {
  254. def_t *e;
  255. int arg;
  256. type_t *t;
  257. t = func->type;
  258. if (t->type != ev_function)
  259. PR_ParseError ("not a function");
  260. // copy the arguments to the global parameter variables
  261. arg = 0;
  262. if (!PR_Check(")"))
  263. {
  264. do
  265. {
  266. if (t->num_parms != -1 && arg >= t->num_parms)
  267. PR_ParseError ("too many parameters");
  268. e = PR_Expression (TOP_PRIORITY);
  269. if (arg == 0 && func->name)
  270. {
  271. // save information for model and sound caching
  272. if (!strncmp(func->name,"precache_sound", 14))
  273. PrecacheSound (e, func->name[14]);
  274. else if (!strncmp(func->name,"precache_model", 14))
  275. PrecacheModel (e, func->name[14]);
  276. else if (!strncmp(func->name,"precache_file", 13))
  277. PrecacheFile (e, func->name[13]);
  278. }
  279. if (t->num_parms != -1 && ( e->type != t->parm_types[arg] ) )
  280. PR_ParseError ("type mismatch on parm %i", arg);
  281. // a vector copy will copy everything
  282. def_parms[arg].type = t->parm_types[arg];
  283. PR_Statement (&pr_opcodes[OP_STORE_V], e, &def_parms[arg]);
  284. arg++;
  285. } while (PR_Check (","));
  286. if (t->num_parms != -1 && arg != t->num_parms)
  287. PR_ParseError ("too few parameters");
  288. PR_Expect (")");
  289. }
  290. if (arg >8)
  291. PR_ParseError ("More than eight parameters");
  292. PR_Statement (&pr_opcodes[OP_CALL0+arg], func, 0);
  293. def_ret.type = t->aux_type;
  294. return &def_ret;
  295. }
  296. /*
  297. ============
  298. PR_ParseValue
  299. Returns the global ofs for the current token
  300. ============
  301. */
  302. def_t *PR_ParseValue (void)
  303. {
  304. def_t *d;
  305. char *name;
  306. // if the token is an immediate, allocate a constant for it
  307. if (pr_token_type == tt_immediate)
  308. return PR_ParseImmediate ();
  309. name = PR_ParseName ();
  310. // look through the defs
  311. d = PR_GetDef (NULL, name, pr_scope, false);
  312. if (!d)
  313. PR_ParseError ("Unknown value \"%s\"", name);
  314. return d;
  315. }
  316. /*
  317. ============
  318. PR_Term
  319. ============
  320. */
  321. def_t *PR_Term (void)
  322. {
  323. def_t *e, *e2;
  324. etype_t t;
  325. if (PR_Check ("!"))
  326. {
  327. e = PR_Expression (NOT_PRIORITY);
  328. t = e->type->type;
  329. if (t == ev_float)
  330. e2 = PR_Statement (&pr_opcodes[OP_NOT_F], e, 0);
  331. else if (t == ev_string)
  332. e2 = PR_Statement (&pr_opcodes[OP_NOT_S], e, 0);
  333. else if (t == ev_entity)
  334. e2 = PR_Statement (&pr_opcodes[OP_NOT_ENT], e, 0);
  335. else if (t == ev_vector)
  336. e2 = PR_Statement (&pr_opcodes[OP_NOT_V], e, 0);
  337. else if (t == ev_function)
  338. e2 = PR_Statement (&pr_opcodes[OP_NOT_FNC], e, 0);
  339. else
  340. {
  341. e2 = NULL; // shut up compiler warning;
  342. PR_ParseError ("type mismatch for !");
  343. }
  344. return e2;
  345. }
  346. if (PR_Check ("("))
  347. {
  348. e = PR_Expression (TOP_PRIORITY);
  349. PR_Expect (")");
  350. return e;
  351. }
  352. return PR_ParseValue ();
  353. }
  354. /*
  355. ==============
  356. PR_Expression
  357. ==============
  358. */
  359. def_t *PR_Expression (int priority)
  360. {
  361. opcode_t *op, *oldop;
  362. def_t *e, *e2;
  363. etype_t type_a, type_b, type_c;
  364. if (priority == 0)
  365. return PR_Term ();
  366. e = PR_Expression (priority-1);
  367. while (1)
  368. {
  369. if (priority == 1 && PR_Check ("(") )
  370. return PR_ParseFunctionCall (e);
  371. for (op=pr_opcodes ; op->name ; op++)
  372. {
  373. if (op->priority != priority)
  374. continue;
  375. if (!PR_Check (op->name))
  376. continue;
  377. if ( op->right_associative )
  378. {
  379. // if last statement is an indirect, change it to an address of
  380. if ( (unsigned)(statements[numstatements-1].op - OP_LOAD_F) < 6 )
  381. {
  382. statements[numstatements-1].op = OP_ADDRESS;
  383. def_pointer.type->aux_type = e->type;
  384. e->type = def_pointer.type;
  385. }
  386. e2 = PR_Expression (priority);
  387. }
  388. else
  389. e2 = PR_Expression (priority-1);
  390. // type check
  391. type_a = e->type->type;
  392. type_b = e2->type->type;
  393. if (op->name[0] == '.')// field access gets type from field
  394. {
  395. if (e2->type->aux_type)
  396. type_c = e2->type->aux_type->type;
  397. else
  398. type_c = -1; // not a field
  399. }
  400. else
  401. type_c = ev_void;
  402. oldop = op;
  403. while (type_a != op->type_a->type->type
  404. || type_b != op->type_b->type->type
  405. || (type_c != ev_void && type_c != op->type_c->type->type) )
  406. {
  407. op++;
  408. if (!op->name || strcmp (op->name , oldop->name))
  409. PR_ParseError ("type mismatch for %s", oldop->name);
  410. }
  411. if (type_a == ev_pointer && type_b != e->type->aux_type->type)
  412. PR_ParseError ("type mismatch for %s", op->name);
  413. if (op->right_associative)
  414. e = PR_Statement (op, e2, e);
  415. else
  416. e = PR_Statement (op, e, e2);
  417. if (type_c != ev_void) // field access gets type from field
  418. e->type = e2->type->aux_type;
  419. break;
  420. }
  421. if (!op->name)
  422. break; // next token isn't at this priority level
  423. }
  424. return e;
  425. }
  426. /*
  427. ============
  428. PR_ParseStatement
  429. ============
  430. */
  431. void PR_ParseStatement (void)
  432. {
  433. def_t *e;
  434. dstatement_t *patch1, *patch2;
  435. if (PR_Check ("{"))
  436. {
  437. do
  438. {
  439. PR_ParseStatement ();
  440. } while (!PR_Check ("}"));
  441. return;
  442. }
  443. if (PR_Check("return"))
  444. {
  445. if (PR_Check (";"))
  446. {
  447. PR_Statement (&pr_opcodes[OP_RETURN], 0, 0);
  448. return;
  449. }
  450. e = PR_Expression (TOP_PRIORITY);
  451. PR_Expect (";");
  452. PR_Statement (&pr_opcodes[OP_RETURN], e, 0);
  453. return;
  454. }
  455. if (PR_Check("while"))
  456. {
  457. PR_Expect ("(");
  458. patch2 = &statements[numstatements];
  459. e = PR_Expression (TOP_PRIORITY);
  460. PR_Expect (")");
  461. patch1 = &statements[numstatements];
  462. PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);
  463. PR_ParseStatement ();
  464. junkdef.ofs = patch2 - &statements[numstatements];
  465. PR_Statement (&pr_opcodes[OP_GOTO], &junkdef, 0);
  466. patch1->b = &statements[numstatements] - patch1;
  467. return;
  468. }
  469. if (PR_Check("do"))
  470. {
  471. patch1 = &statements[numstatements];
  472. PR_ParseStatement ();
  473. PR_Expect ("while");
  474. PR_Expect ("(");
  475. e = PR_Expression (TOP_PRIORITY);
  476. PR_Expect (")");
  477. PR_Expect (";");
  478. junkdef.ofs = patch1 - &statements[numstatements];
  479. PR_Statement (&pr_opcodes[OP_IF], e, &junkdef);
  480. return;
  481. }
  482. if (PR_Check("local"))
  483. {
  484. PR_ParseDefs ();
  485. locals_end = numpr_globals;
  486. return;
  487. }
  488. if (PR_Check("if"))
  489. {
  490. PR_Expect ("(");
  491. e = PR_Expression (TOP_PRIORITY);
  492. PR_Expect (")");
  493. patch1 = &statements[numstatements];
  494. PR_Statement (&pr_opcodes[OP_IFNOT], e, 0);
  495. PR_ParseStatement ();
  496. if (PR_Check ("else"))
  497. {
  498. patch2 = &statements[numstatements];
  499. PR_Statement (&pr_opcodes[OP_GOTO], 0, 0);
  500. patch1->b = &statements[numstatements] - patch1;
  501. PR_ParseStatement ();
  502. patch2->a = &statements[numstatements] - patch2;
  503. }
  504. else
  505. patch1->b = &statements[numstatements] - patch1;
  506. return;
  507. }
  508. PR_Expression (TOP_PRIORITY);
  509. PR_Expect (";");
  510. }
  511. /*
  512. ==============
  513. PR_ParseState
  514. States are special functions made for convenience. They automatically
  515. set frame, nextthink (implicitly), and think (allowing forward definitions).
  516. // void() name = [framenum, nextthink] {code}
  517. // expands to:
  518. // function void name ()
  519. // {
  520. // self.frame=framenum;
  521. // self.nextthink = time + 0.1;
  522. // self.think = nextthink
  523. // <code>
  524. // };
  525. ==============
  526. */
  527. void PR_ParseState (void)
  528. {
  529. char *name;
  530. def_t *s1, *def;
  531. if (pr_token_type != tt_immediate || pr_immediate_type != &type_float)
  532. PR_ParseError ("state frame must be a number");
  533. s1 = PR_ParseImmediate ();
  534. PR_Expect (",");
  535. name = PR_ParseName ();
  536. def = PR_GetDef (&type_function, name,0, true);
  537. PR_Expect ("]");
  538. PR_Statement (&pr_opcodes[OP_STATE], s1, def);
  539. }
  540. /*
  541. ============
  542. PR_ParseImmediateStatements
  543. Parse a function body
  544. ============
  545. */
  546. function_t *PR_ParseImmediateStatements (type_t *type)
  547. {
  548. int i;
  549. function_t *f;
  550. def_t *defs[MAX_PARMS];
  551. f = malloc (sizeof(function_t));
  552. //
  553. // check for builtin function definition #1, #2, etc
  554. //
  555. if (PR_Check ("#"))
  556. {
  557. if (pr_token_type != tt_immediate
  558. || pr_immediate_type != &type_float
  559. || pr_immediate._float != (int)pr_immediate._float)
  560. PR_ParseError ("Bad builtin immediate");
  561. f->builtin = (int)pr_immediate._float;
  562. PR_Lex ();
  563. return f;
  564. }
  565. f->builtin = 0;
  566. //
  567. // define the parms
  568. //
  569. for (i=0 ; i<type->num_parms ; i++)
  570. {
  571. defs[i] = PR_GetDef (type->parm_types[i], pr_parm_names[i], pr_scope, true);
  572. f->parm_ofs[i] = defs[i]->ofs;
  573. if (i > 0 && f->parm_ofs[i] < f->parm_ofs[i-1])
  574. Error ("bad parm order");
  575. }
  576. f->code = numstatements;
  577. //
  578. // check for a state opcode
  579. //
  580. if (PR_Check ("["))
  581. PR_ParseState ();
  582. //
  583. // parse regular statements
  584. //
  585. PR_Expect ("{");
  586. while (!PR_Check("}"))
  587. PR_ParseStatement ();
  588. // emit an end of statements opcode
  589. PR_Statement (pr_opcodes, 0,0);
  590. return f;
  591. }
  592. /*
  593. ============
  594. PR_GetDef
  595. If type is NULL, it will match any type
  596. If allocate is true, a new def will be allocated if it can't be found
  597. ============
  598. */
  599. def_t *PR_GetDef (type_t *type, char *name, def_t *scope, qboolean allocate)
  600. {
  601. def_t *def, **old;
  602. char element[MAX_NAME];
  603. // see if the name is already in use
  604. old = &pr.search;
  605. for (def = *old ; def ; old=&def->search_next,def = *old)
  606. if (!strcmp(def->name,name) )
  607. {
  608. if ( def->scope && def->scope != scope)
  609. continue; // in a different function
  610. if (type && def->type != type)
  611. PR_ParseError ("Type mismatch on redeclaration of %s",name);
  612. // move to head of list to find fast next time
  613. *old = def->search_next;
  614. def->search_next = pr.search;
  615. pr.search = def;
  616. return def;
  617. }
  618. if (!allocate)
  619. return NULL;
  620. // allocate a new def
  621. def = malloc (sizeof(def_t));
  622. memset (def, 0, sizeof(*def));
  623. def->next = NULL;
  624. pr.def_tail->next = def;
  625. pr.def_tail = def;
  626. def->search_next = pr.search;
  627. pr.search = def;
  628. def->name = malloc (strlen(name)+1);
  629. strcpy (def->name, name);
  630. def->type = type;
  631. def->scope = scope;
  632. def->ofs = numpr_globals;
  633. pr_global_defs[numpr_globals] = def;
  634. //
  635. // make automatic defs for the vectors elements
  636. // .origin can be accessed as .origin_x, .origin_y, and .origin_z
  637. //
  638. if (type->type == ev_vector)
  639. {
  640. sprintf (element, "%s_x",name);
  641. PR_GetDef (&type_float, element, scope, true);
  642. sprintf (element, "%s_y",name);
  643. PR_GetDef (&type_float, element, scope, true);
  644. sprintf (element, "%s_z",name);
  645. PR_GetDef (&type_float, element, scope, true);
  646. }
  647. else
  648. numpr_globals += type_size[type->type];
  649. if (type->type == ev_field)
  650. {
  651. *(int *)&pr_globals[def->ofs] = pr.size_fields;
  652. if (type->aux_type->type == ev_vector)
  653. {
  654. sprintf (element, "%s_x",name);
  655. PR_GetDef (&type_floatfield, element, scope, true);
  656. sprintf (element, "%s_y",name);
  657. PR_GetDef (&type_floatfield, element, scope, true);
  658. sprintf (element, "%s_z",name);
  659. PR_GetDef (&type_floatfield, element, scope, true);
  660. }
  661. else
  662. pr.size_fields += type_size[type->aux_type->type];
  663. }
  664. // if (pr_dumpasm)
  665. // PR_PrintOfs (def->ofs);
  666. return def;
  667. }
  668. /*
  669. ================
  670. PR_ParseDefs
  671. Called at the outer layer and when a local statement is hit
  672. ================
  673. */
  674. void PR_ParseDefs (void)
  675. {
  676. char *name;
  677. type_t *type;
  678. def_t *def;
  679. function_t *f;
  680. dfunction_t *df;
  681. int i;
  682. int locals_start;
  683. type = PR_ParseType ();
  684. if (pr_scope && (type->type == ev_field || type->type == ev_function) )
  685. PR_ParseError ("Fields and functions must be global");
  686. do
  687. {
  688. name = PR_ParseName ();
  689. def = PR_GetDef (type, name, pr_scope, true);
  690. // check for an initialization
  691. if ( PR_Check ("=") )
  692. {
  693. if (def->initialized)
  694. PR_ParseError ("%s redeclared", name);
  695. if (type->type == ev_function)
  696. {
  697. locals_start = locals_end = numpr_globals;
  698. pr_scope = def;
  699. f = PR_ParseImmediateStatements (type);
  700. pr_scope = NULL;
  701. def->initialized = 1;
  702. G_FUNCTION(def->ofs) = numfunctions;
  703. f->def = def;
  704. // if (pr_dumpasm)
  705. // PR_PrintFunction (def);
  706. // fill in the dfunction
  707. df = &functions[numfunctions];
  708. numfunctions++;
  709. if (f->builtin)
  710. df->first_statement = -f->builtin;
  711. else
  712. df->first_statement = f->code;
  713. df->s_name = CopyString (f->def->name);
  714. df->s_file = s_file;
  715. df->numparms = f->def->type->num_parms;
  716. df->locals = locals_end - locals_start;
  717. df->parm_start = locals_start;
  718. for (i=0 ; i<df->numparms ; i++)
  719. df->parm_size[i] = type_size[f->def->type->parm_types[i]->type];
  720. continue;
  721. }
  722. else if (pr_immediate_type != type)
  723. PR_ParseError ("wrong immediate type for %s", name);
  724. def->initialized = 1;
  725. memcpy (pr_globals + def->ofs, &pr_immediate, 4*type_size[pr_immediate_type->type]);
  726. PR_Lex ();
  727. }
  728. } while (PR_Check (","));
  729. PR_Expect (";");
  730. }
  731. /*
  732. ============
  733. PR_CompileFile
  734. compiles the 0 terminated text, adding defintions to the pr structure
  735. ============
  736. */
  737. qboolean PR_CompileFile (char *string, char *filename)
  738. {
  739. if (!pr.memory)
  740. Error ("PR_CompileFile: Didn't clear");
  741. PR_ClearGrabMacros (); // clear the frame macros
  742. pr_file_p = string;
  743. s_file = CopyString (filename);
  744. pr_source_line = 0;
  745. PR_NewLine ();
  746. PR_Lex (); // read first token
  747. while (pr_token_type != tt_eof)
  748. {
  749. if (setjmp(pr_parse_abort))
  750. {
  751. if (++pr_error_count > MAX_ERRORS)
  752. return false;
  753. PR_SkipToSemicolon ();
  754. if (pr_token_type == tt_eof)
  755. return false;
  756. }
  757. pr_scope = NULL; // outside all functions
  758. PR_ParseDefs ();
  759. }
  760. return (pr_error_count == 0);
  761. }