Compiler.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. #include <setjmp.h>
  2. #include <stdarg.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include "Compiler.h"
  7. #include "DataType.h"
  8. #include "tokenizer/Tokenizer.h"
  9. #include "utils/Functions.h"
  10. #include "utils/Structs.h"
  11. #include "utils/Variables.h"
  12. #include "vm/Operation.h"
  13. #define ERROR_LENGTH 256
  14. #define RETURN_BUFFER 16
  15. #define BREAK_BUFFER 32
  16. static jmp_buf errorJump;
  17. static char error[ERROR_LENGTH] = {'\0'};
  18. static ByteCode* code;
  19. static int16 line = 1;
  20. static Variables vars;
  21. static Functions functions;
  22. static Functions functionQueue;
  23. static Structs structs;
  24. static int returns[RETURN_BUFFER];
  25. static int returnIndex = 0;
  26. static bool hasReturn = false;
  27. static DataType returnType = DT_VOID;
  28. static int breaks[BREAK_BUFFER];
  29. static int breakIndex = 0;
  30. static int forWhileStack = 0;
  31. static int continueAt = 0;
  32. typedef struct {
  33. Operation intOp;
  34. Operation floatOp;
  35. Operation boolOp;
  36. const char* name;
  37. } TypedOp;
  38. static const TypedOp TYPED_MUL = {OP_MUL_INT, OP_MUL_FLOAT, OP_NOTHING, "*"};
  39. static const TypedOp TYPED_DIV = {OP_DIV_INT, OP_DIV_FLOAT, OP_NOTHING, "/"};
  40. static const TypedOp TYPED_MOD = {OP_MOD_INT, OP_NOTHING, OP_NOTHING, "%"};
  41. static const TypedOp TYPED_ADD = {OP_ADD_INT, OP_ADD_FLOAT, OP_NOTHING, "+"};
  42. static const TypedOp TYPED_SUB = {OP_SUB_INT, OP_SUB_FLOAT, OP_NOTHING, "-"};
  43. static const TypedOp TYPED_LESS = {OP_LESS_INT, OP_LESS_FLOAT, OP_NOTHING, "<"};
  44. static const TypedOp TYPED_LESS_EQUAL = {OP_GREATER_INT, OP_GREATER_FLOAT,
  45. OP_NOTHING, "<="};
  46. static const TypedOp TYPED_GREATER = {OP_GREATER_INT, OP_GREATER_FLOAT,
  47. OP_NOTHING, ">"};
  48. static const TypedOp TYPED_GREATER_EQUAL = {OP_LESS_INT, OP_LESS_FLOAT,
  49. OP_NOTHING, ">="};
  50. static const TypedOp TYPED_EQUAL = {OP_EQUAL_INT, OP_EQUAL_FLOAT, OP_EQUAL_BOOL,
  51. "=="};
  52. static const TypedOp TYPED_NOT_EQUAL = {OP_EQUAL_INT, OP_EQUAL_FLOAT,
  53. OP_EQUAL_BOOL, "!="};
  54. static const TypedOp TYPED_BIT_OR = {OP_BIT_OR, OP_NOTHING, OP_NOTHING, "|"};
  55. static const TypedOp TYPED_BIT_XOR = {OP_BIT_XOR, OP_NOTHING, OP_NOTHING, "^"};
  56. static const TypedOp TYPED_BIT_AND = {OP_BIT_AND, OP_NOTHING, OP_NOTHING, "&"};
  57. static const TypedOp TYPED_LEFT_SHIFT = {OP_LEFT_SHIFT, OP_NOTHING, OP_NOTHING,
  58. "<<"};
  59. static const TypedOp TYPED_RIGHT_SHIFT = {OP_RIGHT_SHIFT, OP_NOTHING,
  60. OP_NOTHING, ">>"};
  61. static void cError(const char* format, ...) {
  62. va_list args;
  63. va_start(args, format);
  64. vsnprintf(error, ERROR_LENGTH, format, args);
  65. va_end(args);
  66. longjmp(errorJump, 0);
  67. }
  68. static void cInvalidOperation(DataType a, DataType b, const char* op) {
  69. cError("invalid operation: %s %s %s", dtGetName(a), op, dtGetName(b));
  70. }
  71. static void cNotDeclared(const char* name) {
  72. cError("variable %s has not been declared", name);
  73. }
  74. static void cDeclared(const char* name) {
  75. cError("%s has already been declared", name);
  76. }
  77. static void cTooMuchArguments() {
  78. cError("too much function arguments");
  79. }
  80. static void cUnexpectedToken(Token t) {
  81. cError("unexpected token on line %d: %s", line, tGetName(t));
  82. }
  83. static void cAddOperation(Operation token) {
  84. unsigned char c = token;
  85. bcAddBytes(code, &c, 1);
  86. }
  87. static int cReserveInt() {
  88. return bcReserveBytes(code, sizeof(int));
  89. }
  90. static void cSetInt(int p, int i) {
  91. bcSetBytes(code, p, &i, sizeof(int));
  92. }
  93. static void cAddInt(int i) {
  94. bcAddBytes(code, &i, sizeof(int));
  95. }
  96. static void cAddInt16(int16 i) {
  97. bcAddBytes(code, &i, sizeof(int16));
  98. }
  99. static Token cReadTokenAndLine() {
  100. Token t = tReadToken();
  101. if(tReadInt16(&line)) {
  102. return t;
  103. }
  104. return T_END;
  105. }
  106. static void cConsumeToken(Token wanted) {
  107. Token t = cReadTokenAndLine();
  108. if(wanted != t) {
  109. cError("unexpected token on line %d: expected '%s' got '%s'", line,
  110. tGetName(wanted), tGetName(t));
  111. }
  112. }
  113. static bool cConsumeTokenIf(Token t) {
  114. if(tPeekToken() == t) {
  115. cReadTokenAndLine();
  116. return true;
  117. }
  118. return false;
  119. }
  120. static void cConstantInt() {
  121. int value;
  122. if(!tReadInt(&value)) {
  123. cError("int token without an int on line %d", line);
  124. }
  125. cAddOperation(OP_PUSH_INT);
  126. cAddInt(value);
  127. }
  128. static void cConstantFloat() {
  129. float value;
  130. if(!tReadFloat(&value)) {
  131. cError("float token without a float on line %d", line);
  132. }
  133. cAddOperation(OP_PUSH_FLOAT);
  134. bcAddBytes(code, &value, sizeof(float));
  135. }
  136. static const char* cReadString() {
  137. int length;
  138. const char* literal = tReadString(&length);
  139. if(literal == NULL) {
  140. cError("literal without string on line %d", line);
  141. }
  142. return literal;
  143. }
  144. static DataType cExpression();
  145. static void cCallFunctionArguments(Function* f) {
  146. while(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
  147. DataType dt = cExpression();
  148. if(fAddArgument(f, dt)) {
  149. cTooMuchArguments();
  150. }
  151. if(cConsumeTokenIf(T_COMMA) && tPeekToken() == T_CLOSE_BRACKET) {
  152. cUnexpectedToken(tPeekToken());
  153. }
  154. }
  155. }
  156. static DataType cCallFunction(const char* name) {
  157. cAddOperation(OP_PUSH_INT);
  158. cAddInt(0);
  159. Function f;
  160. fInit(&f, name, line);
  161. cCallFunctionArguments(&f);
  162. cAddOperation(OP_GOSUB);
  163. Function* found = fsSearch(&functions, &f);
  164. if(found == NULL) {
  165. cError("unknown function");
  166. }
  167. if(found->address == -1) {
  168. f.returnType = found->returnType;
  169. f.address = cReserveInt();
  170. fsAdd(&functionQueue, &f);
  171. } else {
  172. cAddInt(found->address);
  173. }
  174. cAddInt(found->size);
  175. return found->returnType;
  176. }
  177. static DataType cLoadVariable(Variable* v) {
  178. switch(v->type) {
  179. case DT_INT: cAddOperation(OP_LOAD_INT); break;
  180. case DT_BOOL: cAddOperation(OP_LOAD_BOOL); break;
  181. case DT_FLOAT: cAddOperation(OP_LOAD_FLOAT); break;
  182. default: cError("cannot load type %s", dtGetName(v->type));
  183. }
  184. cAddInt(v->address);
  185. return v->type;
  186. }
  187. static void cStoreVariable(Variable* v, DataType dt, const char* name) {
  188. if(v->type != dt) {
  189. cInvalidOperation(v->type, dt, name);
  190. }
  191. switch(v->type) {
  192. case DT_INT: cAddOperation(OP_STORE_INT); break;
  193. case DT_BOOL: cAddOperation(OP_STORE_BOOL); break;
  194. case DT_FLOAT: cAddOperation(OP_STORE_FLOAT); break;
  195. default:
  196. if(dtIsArray(v->type)) {
  197. cAddOperation(OP_STORE_ARRAY);
  198. } else {
  199. cError("cannot store type %s", dtGetName(v->type));
  200. }
  201. }
  202. cAddInt(v->address);
  203. }
  204. static DataType cPostChange(Variable* v, int change, const char* name) {
  205. if(v->type != DT_INT) {
  206. cError("%s needs an int", name);
  207. }
  208. cAddOperation(OP_LOAD_INT);
  209. cAddInt(v->address);
  210. cAddOperation(OP_LOAD_INT);
  211. cAddInt(v->address);
  212. cAddOperation(OP_PUSH_INT);
  213. cAddInt(change);
  214. cAddOperation(OP_ADD_INT);
  215. cAddOperation(OP_STORE_INT);
  216. cAddInt(v->address);
  217. return DT_INT;
  218. }
  219. static DataType cLiteral() {
  220. const char* literal = cReadString();
  221. if(cConsumeTokenIf(T_OPEN_BRACKET)) {
  222. DataType dt = cCallFunction(literal);
  223. if(dt == DT_VOID) {
  224. cError("function returns void");
  225. }
  226. return dt;
  227. }
  228. Variable* v = vSearch(&vars, literal);
  229. if(v == NULL) {
  230. cNotDeclared(literal);
  231. }
  232. if(cConsumeTokenIf(T_INCREMENT)) {
  233. return cPostChange(v, 1, "++");
  234. } else if(cConsumeTokenIf(T_DECREMENT)) {
  235. return cPostChange(v, -1, "--");
  236. }
  237. return cLoadVariable(v);
  238. }
  239. static DataType cBracketPrimary() {
  240. DataType result = cExpression();
  241. cConsumeToken(T_CLOSE_BRACKET);
  242. return result;
  243. }
  244. static DataType cAllocArray(DataType dt, Operation op) {
  245. cConsumeToken(T_OPEN_SQUARE_BRACKET);
  246. DataType index = cExpression();
  247. if(index != DT_INT) {
  248. cError("array size must be an int");
  249. }
  250. cConsumeToken(T_CLOSE_SQUARE_BRACKET);
  251. cAddOperation(op);
  252. return dtArray(dt, 1);
  253. }
  254. static DataType cPrimary() {
  255. Token t = cReadTokenAndLine();
  256. switch(t) {
  257. case T_CONST_INT: cConstantInt(); return DT_INT;
  258. case T_CONST_FLOAT: cConstantFloat(); return DT_FLOAT;
  259. case T_TRUE: cAddOperation(OP_PUSH_TRUE); return DT_BOOL;
  260. case T_FALSE: cAddOperation(OP_PUSH_FALSE); return DT_BOOL;
  261. case T_OPEN_BRACKET: return cBracketPrimary();
  262. case T_LITERAL: return cLiteral();
  263. case T_INT: return cAllocArray(DT_INT, OP_INT_ARRAY);
  264. default: cUnexpectedToken(t); return DT_VOID;
  265. }
  266. }
  267. static DataType cPreChange(int change, const char* name) {
  268. cConsumeToken(T_LITERAL);
  269. const char* literal = cReadString();
  270. Variable* v = vSearch(&vars, literal);
  271. if(v == NULL) {
  272. cNotDeclared(literal);
  273. } else if(v->type != DT_INT) {
  274. cError("%s needs an int", name);
  275. }
  276. cAddOperation(OP_LOAD_INT);
  277. cAddInt(v->address);
  278. cAddOperation(OP_PUSH_INT);
  279. cAddInt(change);
  280. cAddOperation(OP_ADD_INT);
  281. cAddOperation(OP_STORE_INT);
  282. cAddInt(v->address);
  283. cAddOperation(OP_LOAD_INT);
  284. cAddInt(v->address);
  285. return DT_INT;
  286. }
  287. static DataType cPreUnary() {
  288. if(cConsumeTokenIf(T_SUB)) {
  289. DataType result = cPrimary();
  290. switch(result) {
  291. case DT_INT: cAddOperation(OP_INVERT_SIGN_INT); break;
  292. case DT_FLOAT: cAddOperation(OP_INVERT_SIGN_FLOAT); break;
  293. default: cError("cannot invert sign of %s", dtGetName(result));
  294. }
  295. return result;
  296. } else if(cConsumeTokenIf(T_INCREMENT)) {
  297. return cPreChange(1, "++");
  298. } else if(cConsumeTokenIf(T_DECREMENT)) {
  299. return cPreChange(-1, "--");
  300. } else if(cConsumeTokenIf(T_NOT)) {
  301. int counter = 1;
  302. while(cConsumeTokenIf(T_NOT)) {
  303. counter++;
  304. }
  305. DataType result = cPrimary();
  306. if(result != DT_BOOL) {
  307. cError("! needs a bool not %s", dtGetName(result));
  308. }
  309. cAddOperation(OP_NOT);
  310. if((counter & 1) == 0) {
  311. cAddOperation(OP_NOT);
  312. }
  313. return DT_BOOL;
  314. } else if(cConsumeTokenIf(T_BIT_NOT)) {
  315. DataType result = cPrimary();
  316. if(result == DT_INT) {
  317. cAddOperation(OP_BIT_NOT);
  318. } else {
  319. cError("~ needs an int not %s", dtGetName(result));
  320. }
  321. return result;
  322. }
  323. return cPrimary();
  324. }
  325. static void cAddTypeOperation(DataType a, DataType b, const TypedOp* op) {
  326. if(a == DT_INT && b == DT_INT && op->intOp != OP_NOTHING) {
  327. cAddOperation(op->intOp);
  328. } else if(a == DT_FLOAT && b == DT_FLOAT && op->floatOp != OP_NOTHING) {
  329. cAddOperation(op->floatOp);
  330. } else if(a == DT_BOOL && b == DT_BOOL && op->boolOp != OP_NOTHING) {
  331. cAddOperation(op->boolOp);
  332. } else {
  333. cInvalidOperation(a, b, op->name);
  334. }
  335. }
  336. static DataType cMul() {
  337. DataType a = cPreUnary();
  338. while(true) {
  339. if(cConsumeTokenIf(T_MUL)) {
  340. cAddTypeOperation(a, cPreUnary(), &TYPED_MUL);
  341. } else if(cConsumeTokenIf(T_DIV)) {
  342. cAddTypeOperation(a, cPreUnary(), &TYPED_DIV);
  343. } else if(cConsumeTokenIf(T_MOD)) {
  344. cAddTypeOperation(a, cPreUnary(), &TYPED_MOD);
  345. } else {
  346. break;
  347. }
  348. }
  349. return a;
  350. }
  351. static DataType cAdd() {
  352. DataType a = cMul();
  353. while(true) {
  354. if(cConsumeTokenIf(T_ADD)) {
  355. cAddTypeOperation(a, cMul(), &TYPED_ADD);
  356. } else if(cConsumeTokenIf(T_SUB)) {
  357. cAddTypeOperation(a, cMul(), &TYPED_SUB);
  358. } else {
  359. break;
  360. }
  361. }
  362. return a;
  363. }
  364. static DataType cShift() {
  365. DataType a = cAdd();
  366. while(true) {
  367. if(cConsumeTokenIf(T_LEFT_SHIFT)) {
  368. cAddTypeOperation(a, cAdd(), &TYPED_LEFT_SHIFT);
  369. } else if(cConsumeTokenIf(T_RIGHT_SHIFT)) {
  370. cAddTypeOperation(a, cAdd(), &TYPED_RIGHT_SHIFT);
  371. } else {
  372. break;
  373. }
  374. }
  375. return a;
  376. }
  377. static DataType cComparison() {
  378. DataType a = cShift();
  379. while(true) {
  380. if(cConsumeTokenIf(T_LESS)) {
  381. cAddTypeOperation(a, cShift(), &TYPED_LESS);
  382. a = DT_BOOL;
  383. } else if(cConsumeTokenIf(T_LESS_EQUAL)) {
  384. cAddTypeOperation(a, cShift(), &TYPED_LESS_EQUAL);
  385. cAddOperation(OP_NOT);
  386. a = DT_BOOL;
  387. } else if(cConsumeTokenIf(T_GREATER)) {
  388. cAddTypeOperation(a, cShift(), &TYPED_GREATER);
  389. a = DT_BOOL;
  390. } else if(cConsumeTokenIf(T_GREATER_EQUAL)) {
  391. cAddTypeOperation(a, cShift(), &TYPED_GREATER_EQUAL);
  392. cAddOperation(OP_NOT);
  393. a = DT_BOOL;
  394. } else {
  395. break;
  396. }
  397. }
  398. return a;
  399. }
  400. static DataType cEqual() {
  401. DataType a = cComparison();
  402. while(true) {
  403. if(cConsumeTokenIf(T_EQUAL)) {
  404. cAddTypeOperation(a, cComparison(), &TYPED_EQUAL);
  405. a = DT_BOOL;
  406. } else if(cConsumeTokenIf(T_NOT_EQUAL)) {
  407. cAddTypeOperation(a, cComparison(), &TYPED_NOT_EQUAL);
  408. cAddOperation(OP_NOT);
  409. a = DT_BOOL;
  410. } else {
  411. break;
  412. }
  413. }
  414. return a;
  415. }
  416. static DataType cBitAnd() {
  417. DataType a = cEqual();
  418. while(cConsumeTokenIf(T_BIT_AND)) {
  419. DataType b = cEqual();
  420. cAddTypeOperation(a, b, &TYPED_BIT_AND);
  421. }
  422. return a;
  423. }
  424. static DataType cBitXor() {
  425. DataType a = cBitAnd();
  426. while(cConsumeTokenIf(T_BIT_XOR)) {
  427. DataType b = cBitAnd();
  428. cAddTypeOperation(a, b, &TYPED_BIT_XOR);
  429. }
  430. return a;
  431. }
  432. static DataType cBitOr() {
  433. DataType a = cBitXor();
  434. while(cConsumeTokenIf(T_BIT_OR)) {
  435. DataType b = cBitXor();
  436. cAddTypeOperation(a, b, &TYPED_BIT_OR);
  437. }
  438. return a;
  439. }
  440. static DataType cAnd() {
  441. DataType a = cBitOr();
  442. while(cConsumeTokenIf(T_AND)) {
  443. cAddOperation(OP_PEEK_FALSE_GOTO);
  444. int p = cReserveInt();
  445. DataType b = cBitOr();
  446. if(a != DT_BOOL || b != DT_BOOL) {
  447. cInvalidOperation(a, b, "&&");
  448. }
  449. cAddOperation(OP_AND);
  450. cSetInt(p, code->length);
  451. }
  452. return a;
  453. }
  454. static DataType cOr() {
  455. DataType a = cAnd();
  456. while(cConsumeTokenIf(T_OR)) {
  457. cAddOperation(OP_PEEK_TRUE_GOTO);
  458. int p = cReserveInt();
  459. DataType b = cAnd();
  460. if(a != DT_BOOL || b != DT_BOOL) {
  461. cInvalidOperation(a, b, "||");
  462. }
  463. cAddOperation(OP_OR);
  464. cSetInt(p, code->length);
  465. }
  466. return a;
  467. }
  468. static DataType cExpression() {
  469. return cOr();
  470. }
  471. static void cOperationSet(Variable* v, const TypedOp* op) {
  472. DataType a = cLoadVariable(v);
  473. DataType b = cExpression();
  474. cAddTypeOperation(a, b, op);
  475. cStoreVariable(v, b, "=");
  476. }
  477. static void cAddPostLineChange(Variable* v, int change, const char* name) {
  478. if(v->type != DT_INT) {
  479. cError("%s needs an int", name);
  480. }
  481. cAddOperation(OP_LOAD_INT);
  482. cAddInt(v->address);
  483. cAddOperation(OP_PUSH_INT);
  484. cAddInt(change);
  485. cAddOperation(OP_ADD_INT);
  486. cAddOperation(OP_STORE_INT);
  487. cAddInt(v->address);
  488. }
  489. static void cDeclareStruct(Struct* st) {
  490. cConsumeToken(T_LITERAL);
  491. const char* var = cReadString();
  492. Variable* v = vSearchScope(&vars, var);
  493. if(v != NULL) {
  494. cDeclared(var);
  495. }
  496. vAdd(&vars, var, dtStruct(st->id));
  497. int varLength = strlen(var);
  498. for(int i = 0; i < st->amount; i++) {
  499. int length = strlen(st->vars[i].name);
  500. char* fullName = malloc(varLength + length + 2);
  501. memcpy(fullName, var, varLength);
  502. fullName[varLength] = '.';
  503. memcpy(fullName + varLength + 1, st->vars[i].name, length + 1);
  504. vAdd(&vars, fullName, st->vars[i].type);
  505. free(fullName);
  506. }
  507. }
  508. static void cLineLiteral() {
  509. const char* literal = cReadString();
  510. if(cConsumeTokenIf(T_OPEN_BRACKET)) {
  511. DataType dt = cCallFunction(literal);
  512. if(dt != DT_VOID) {
  513. cError("function returns %s not void", dtGetName(dt));
  514. }
  515. return;
  516. }
  517. Struct* st = stsSearch(&structs, literal);
  518. if(st != NULL) {
  519. cDeclareStruct(st);
  520. return;
  521. }
  522. Variable* v = vSearch(&vars, literal);
  523. if(v == NULL) {
  524. cNotDeclared(literal);
  525. }
  526. Token t = cReadTokenAndLine();
  527. switch(t) {
  528. case T_SET: cStoreVariable(v, cExpression(), "="); break;
  529. case T_ADD_SET: cOperationSet(v, &TYPED_ADD); break;
  530. case T_SUB_SET: cOperationSet(v, &TYPED_SUB); break;
  531. case T_MUL_SET: cOperationSet(v, &TYPED_MUL); break;
  532. case T_DIV_SET: cOperationSet(v, &TYPED_DIV); break;
  533. case T_MOD_SET: cOperationSet(v, &TYPED_MOD); break;
  534. case T_BIT_AND_SET: cOperationSet(v, &TYPED_BIT_AND); break;
  535. case T_BIT_OR_SET: cOperationSet(v, &TYPED_BIT_OR); break;
  536. case T_BIT_XOR_SET: cOperationSet(v, &TYPED_BIT_XOR); break;
  537. case T_LEFT_SHIFT_SET: cOperationSet(v, &TYPED_LEFT_SHIFT); break;
  538. case T_RIGHT_SHIFT_SET: cOperationSet(v, &TYPED_RIGHT_SHIFT); break;
  539. case T_INCREMENT: cAddPostLineChange(v, 1, "++"); break;
  540. case T_DECREMENT: cAddPostLineChange(v, -1, "--"); break;
  541. default: cUnexpectedToken(t);
  542. }
  543. }
  544. static void cLine(Token t);
  545. static void cConsumeBody() {
  546. int oldLine = line;
  547. while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) {
  548. Token t = cReadTokenAndLine();
  549. if(t == T_END) {
  550. line = oldLine;
  551. cError("unexpected end of file: non closed curved bracket");
  552. }
  553. cLine(t);
  554. }
  555. }
  556. static void cConsumeScope() {
  557. Scope scope;
  558. vEnterScope(&vars, &scope);
  559. cConsumeBody();
  560. vLeaveScope(&vars, &scope);
  561. }
  562. static void cAddReturn(Operation op) {
  563. cAddOperation(op);
  564. returns[returnIndex++] = cReserveInt();
  565. }
  566. static void cReturn() {
  567. if(returnIndex >= RETURN_BUFFER) {
  568. cError("too much returns in function");
  569. }
  570. hasReturn = true;
  571. if(returnType == DT_VOID) {
  572. cConsumeToken(T_SEMICOLON);
  573. cAddReturn(OP_RETURN);
  574. return;
  575. }
  576. DataType dt = cExpression();
  577. if(dt != returnType) {
  578. cError("wrong return type, should be %s", dtGetName(returnType));
  579. }
  580. switch(dt) {
  581. case DT_INT: cAddReturn(OP_RETURN_INT); break;
  582. case DT_BOOL: cAddReturn(OP_RETURN_BOOL); break;
  583. case DT_FLOAT: cAddReturn(OP_RETURN_FLOAT); break;
  584. default: cError("cannot return %s", dtGetName(dt));
  585. }
  586. cConsumeToken(T_SEMICOLON);
  587. }
  588. static void cPrint() {
  589. DataType dt = cExpression();
  590. switch(dt) {
  591. case DT_INT: cAddOperation(OP_PRINT_INT); break;
  592. case DT_FLOAT: cAddOperation(OP_PRINT_FLOAT); break;
  593. case DT_BOOL: cAddOperation(OP_PRINT_BOOL); break;
  594. default: cError("cannot print type %s", dtGetName(dt));
  595. }
  596. cConsumeToken(T_SEMICOLON);
  597. }
  598. static void cIf() {
  599. cConsumeToken(T_OPEN_BRACKET);
  600. DataType dt = cExpression();
  601. if(dt != DT_BOOL) {
  602. cError("if expects a bool not %s", dtGetName(dt));
  603. }
  604. cConsumeToken(T_CLOSE_BRACKET);
  605. cAddOperation(OP_IF_GOTO);
  606. int ifP = cReserveInt();
  607. cConsumeToken(T_OPEN_CURVED_BRACKET);
  608. cConsumeScope();
  609. cSetInt(ifP, code->length);
  610. if(cConsumeTokenIf(T_ELSE)) {
  611. cAddOperation(OP_GOTO);
  612. int elseP = cReserveInt();
  613. cSetInt(ifP, code->length);
  614. if(cConsumeTokenIf(T_IF)) {
  615. cIf();
  616. } else {
  617. cConsumeToken(T_OPEN_CURVED_BRACKET);
  618. cConsumeScope();
  619. }
  620. cSetInt(elseP, code->length);
  621. }
  622. }
  623. static void cConsumeBreaks(int start, int address) {
  624. for(int i = start; i < breakIndex; i++) {
  625. cSetInt(breaks[i], address);
  626. }
  627. breakIndex = start;
  628. }
  629. static void cWhile() {
  630. int start = code->length;
  631. cConsumeToken(T_OPEN_BRACKET);
  632. DataType dt = cExpression();
  633. if(dt != DT_BOOL) {
  634. cError("while expects a bool not %s", dtGetName(dt));
  635. }
  636. cConsumeToken(T_CLOSE_BRACKET);
  637. cAddOperation(OP_IF_GOTO);
  638. int ifP = cReserveInt();
  639. int breakStart = breakIndex;
  640. forWhileStack++;
  641. int oldContinue = continueAt;
  642. continueAt = start;
  643. cConsumeToken(T_OPEN_CURVED_BRACKET);
  644. cConsumeScope();
  645. continueAt = oldContinue;
  646. forWhileStack--;
  647. cAddOperation(OP_GOTO);
  648. cAddInt(start);
  649. cSetInt(ifP, code->length);
  650. cConsumeBreaks(breakStart, code->length);
  651. }
  652. static DataType cDimension(DataType dt) {
  653. int dimension = 0;
  654. while(cConsumeTokenIf(T_MUL)) {
  655. dimension++;
  656. }
  657. if(dimension > 0) {
  658. dt = dtArray(dt, dimension);
  659. }
  660. return dt;
  661. }
  662. static void cDeclare(DataType dt) {
  663. dt = cDimension(dt);
  664. cConsumeToken(T_LITERAL);
  665. const char* var = cReadString();
  666. Variable* v = vSearchScope(&vars, var);
  667. if(v != NULL) {
  668. cDeclared(var);
  669. }
  670. v = vAdd(&vars, var, dt);
  671. cConsumeToken(T_SET);
  672. cStoreVariable(v, cExpression(), "=");
  673. }
  674. static void cAddPreLineChange(int change, const char* name) {
  675. cConsumeToken(T_LITERAL);
  676. const char* literal = cReadString();
  677. Variable* v = vSearch(&vars, literal);
  678. if(v == NULL) {
  679. cNotDeclared(literal);
  680. }
  681. cAddPostLineChange(v, change, name);
  682. }
  683. static void cLineExpression(Token t) {
  684. switch(t) {
  685. case T_LITERAL: cLineLiteral(); break;
  686. case T_INT: cDeclare(DT_INT); break;
  687. case T_BOOL: cDeclare(DT_BOOL); break;
  688. case T_FLOAT: cDeclare(DT_FLOAT); break;
  689. case T_INCREMENT: cAddPreLineChange(1, "++"); break;
  690. case T_DECREMENT: cAddPreLineChange(-1, "--"); break;
  691. default: cUnexpectedToken(t);
  692. }
  693. }
  694. static void cFor() {
  695. Scope scope;
  696. vEnterScope(&vars, &scope);
  697. cConsumeToken(T_OPEN_BRACKET);
  698. cLineExpression(cReadTokenAndLine());
  699. cConsumeToken(T_SEMICOLON);
  700. int startCheck = code->length;
  701. DataType dt = cExpression();
  702. if(dt != DT_BOOL) {
  703. cError("for expects a bool not %s", dtGetName(dt));
  704. }
  705. cConsumeToken(T_SEMICOLON);
  706. cAddOperation(OP_IF_GOTO);
  707. int end = cReserveInt();
  708. cAddOperation(OP_GOTO);
  709. int beginBody = cReserveInt();
  710. int startPerLoop = code->length;
  711. cLineExpression(cReadTokenAndLine());
  712. cAddOperation(OP_GOTO);
  713. cAddInt(startCheck);
  714. cConsumeToken(T_CLOSE_BRACKET);
  715. cSetInt(beginBody, code->length);
  716. int breakStart = breakIndex;
  717. forWhileStack++;
  718. int oldContinue = continueAt;
  719. continueAt = startPerLoop;
  720. cConsumeToken(T_OPEN_CURVED_BRACKET);
  721. cConsumeBody();
  722. continueAt = oldContinue;
  723. forWhileStack--;
  724. cAddOperation(OP_GOTO);
  725. cAddInt(startPerLoop);
  726. cSetInt(end, code->length);
  727. cConsumeBreaks(breakStart, code->length);
  728. vLeaveScope(&vars, &scope);
  729. }
  730. static void cBreak() {
  731. if(forWhileStack == 0) {
  732. cError("break without for or while on line %d", line);
  733. } else if(breakIndex >= BREAK_BUFFER) {
  734. cError("too much breaks around line %d", line);
  735. }
  736. cAddOperation(OP_GOTO);
  737. breaks[breakIndex++] = cReserveInt();
  738. cConsumeToken(T_SEMICOLON);
  739. }
  740. static void cContinue() {
  741. if(forWhileStack == 0) {
  742. cError("continue without for or while on line %d", line);
  743. }
  744. cAddOperation(OP_GOTO);
  745. cAddInt(continueAt);
  746. cConsumeToken(T_SEMICOLON);
  747. }
  748. static void cLine(Token t) {
  749. hasReturn = false;
  750. cAddOperation(OP_LINE);
  751. cAddInt16(line);
  752. switch(t) {
  753. case T_OPEN_CURVED_BRACKET: cConsumeScope(); break;
  754. case T_PRINT: cPrint(); break;
  755. case T_RETURN: cReturn(); break;
  756. case T_IF: cIf(); break;
  757. case T_WHILE: cWhile(); break;
  758. case T_FOR: cFor(); break;
  759. case T_BREAK: cBreak(); break;
  760. case T_CONTINUE: cContinue(); break;
  761. default: cLineExpression(t); cConsumeToken(T_SEMICOLON);
  762. }
  763. }
  764. static void cFunctionArgument(Function* f);
  765. static void cFunctionCommaOrEnd(Function* f) {
  766. if(cConsumeTokenIf(T_CLOSE_BRACKET)) {
  767. return;
  768. }
  769. cConsumeToken(T_COMMA);
  770. cFunctionArgument(f);
  771. }
  772. static void cFunctionAddArgument(Function* f, DataType dt) {
  773. cConsumeToken(T_LITERAL);
  774. const char* name = cReadString();
  775. Variable* v = vSearchScope(&vars, name);
  776. if(v != NULL) {
  777. cDeclared(name);
  778. }
  779. vAdd(&vars, name, dt);
  780. if(fAddArgument(f, dt)) {
  781. cTooMuchArguments();
  782. }
  783. cFunctionCommaOrEnd(f);
  784. }
  785. static void cFunctionArgument(Function* f) {
  786. Token t = cReadTokenAndLine();
  787. switch(t) {
  788. case T_INT: cFunctionAddArgument(f, DT_INT); break;
  789. default: cUnexpectedToken(t);
  790. }
  791. }
  792. static void cFunctionArguments(Function* f) {
  793. cConsumeToken(T_OPEN_BRACKET);
  794. if(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
  795. cFunctionArgument(f);
  796. }
  797. }
  798. static int cReserve(int offset) {
  799. cAddOperation(OP_RESERVE);
  800. int p = cReserveInt();
  801. cAddInt(offset);
  802. return p;
  803. }
  804. static void cFree(int p, int bytes) {
  805. cAddOperation(OP_RETURN);
  806. cAddInt(bytes);
  807. cSetInt(p, bytes);
  808. }
  809. static void cLinkReturns(int bytes) {
  810. for(int i = 0; i < returnIndex; i++) {
  811. cSetInt(returns[i], bytes);
  812. }
  813. returnIndex = 0;
  814. }
  815. static void cInnerFunction(Function* f) {
  816. cConsumeToken(T_OPEN_CURVED_BRACKET);
  817. int p = cReserve(f->size);
  818. returnIndex = 0;
  819. hasReturn = false;
  820. cConsumeScope();
  821. if(returnType != DT_VOID && !hasReturn) {
  822. cError("missing return");
  823. }
  824. cFree(p, vars.maxAddress);
  825. cLinkReturns(vars.maxAddress);
  826. }
  827. static bool cForwardFunction(Function* found, Function* f) {
  828. if(!cConsumeTokenIf(T_SEMICOLON)) {
  829. return false;
  830. } else if(found != NULL) {
  831. cError("function registered twice");
  832. }
  833. f->address = -1;
  834. fsAdd(&functions, f);
  835. return true;
  836. }
  837. static void cBuildFunction(Function* f, DataType rType) {
  838. cConsumeToken(T_LITERAL);
  839. fInit(f, cReadString(), line);
  840. f->returnType = rType;
  841. vReset(&vars);
  842. cFunctionArguments(f);
  843. }
  844. static void cFunction(DataType rType) {
  845. Function f;
  846. cBuildFunction(&f, rType);
  847. Function* found = fsSearch(&functions, &f);
  848. if(cForwardFunction(found, &f)) {
  849. return;
  850. }
  851. cAddOperation(OP_LINE);
  852. cAddInt16(line);
  853. cAddOperation(OP_GOTO);
  854. int end = cReserveInt();
  855. f.address = code->length;
  856. if(found != NULL) {
  857. if(found->address == -1) {
  858. found->address = f.address;
  859. } else {
  860. cError("function registered twice");
  861. }
  862. } else {
  863. fsAdd(&functions, &f);
  864. }
  865. returnType = rType;
  866. cInnerFunction(&f);
  867. cSetInt(end, code->length);
  868. }
  869. static void cStruct() {
  870. cConsumeToken(T_LITERAL);
  871. const char* name = cReadString();
  872. if(stsSearch(&structs, name) != NULL) {
  873. cError("struct registered twice");
  874. }
  875. Struct* st = stsAdd(&structs, name);
  876. cConsumeToken(T_OPEN_CURVED_BRACKET);
  877. while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) {
  878. Token t = cReadTokenAndLine();
  879. DataType dt = DT_VOID;
  880. switch(t) {
  881. case T_INT: dt = DT_INT; break;
  882. case T_BOOL: dt = DT_BOOL; break;
  883. case T_FLOAT: dt = DT_FLOAT; break;
  884. default: cUnexpectedToken(t);
  885. }
  886. dt = cDimension(dt);
  887. cConsumeToken(T_LITERAL);
  888. const char* name = cReadString();
  889. stAddVariable(st, name, dt);
  890. cConsumeToken(T_SEMICOLON);
  891. }
  892. cConsumeToken(T_SEMICOLON);
  893. }
  894. static void cGlobalScope(Token t) {
  895. switch(t) {
  896. case T_VOID: cFunction(DT_VOID); break;
  897. case T_INT: cFunction(DT_INT); break;
  898. case T_BOOL: cFunction(DT_BOOL); break;
  899. case T_FLOAT: cFunction(DT_FLOAT); break;
  900. case T_STRUCT: cStruct(); break;
  901. default: cUnexpectedToken(t);
  902. }
  903. }
  904. static void cCallMain() {
  905. Function f;
  906. fInit(&f, "main", line);
  907. Function* found = fsSearch(&functions, &f);
  908. if(found != NULL && found->returnType == DT_VOID) {
  909. cAddOperation(OP_PUSH_INT);
  910. cAddInt(0);
  911. cAddOperation(OP_GOSUB);
  912. cAddInt(found->address);
  913. cAddInt(found->size);
  914. }
  915. }
  916. static void cForEachLine() {
  917. Token t = cReadTokenAndLine();
  918. while(t != T_END) {
  919. cGlobalScope(t);
  920. t = cReadTokenAndLine();
  921. }
  922. cCallMain();
  923. }
  924. static void cLinkQueuedFunctions() {
  925. for(int i = 0; i < functionQueue.entries; i++) {
  926. Function* f = functionQueue.data + i;
  927. Function* found = fsSearch(&functions, f);
  928. if(found == NULL) {
  929. line = f->line;
  930. cError("unknown function");
  931. } else if(f->returnType != found->returnType) {
  932. line = f->line;
  933. cError("function return type is not %s", dtGetName(f->returnType));
  934. }
  935. cSetInt(f->address, found->address);
  936. }
  937. }
  938. static void cAllocAndCompile() {
  939. forWhileStack = 0;
  940. breakIndex = 0;
  941. vInit(&vars);
  942. fsInit(&functions);
  943. fsInit(&functionQueue);
  944. stsInit(&structs);
  945. if(!setjmp(errorJump)) {
  946. cForEachLine();
  947. cLinkQueuedFunctions();
  948. }
  949. stsDelete(&structs);
  950. fsDelete(&functionQueue);
  951. fsDelete(&functions);
  952. vDelete(&vars);
  953. }
  954. ByteCode* cCompile() {
  955. error[0] = '\0';
  956. code = bcInit();
  957. cAllocAndCompile();
  958. if(error[0] != '\0') {
  959. bcDelete(code);
  960. return NULL;
  961. }
  962. return code;
  963. }
  964. const char* cGetError() {
  965. return error;
  966. }
  967. int cGetLine() {
  968. return line;
  969. }