Compiler.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. #include <setjmp.h>
  2. #include <stdarg.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include "Compiler.h"
  6. #include "DataType.h"
  7. #include "tokenizer/Tokenizer.h"
  8. #include "utils/FunctionMap.h"
  9. #include "utils/Variables.h"
  10. #include "vm/Operation.h"
  11. #define ERROR_LENGTH 256
  12. //#define RETURN_BUFFER 16
  13. //#define BREAK_BUFFER 32
  14. static jmp_buf errorJump;
  15. static char error[ERROR_LENGTH] = {'\0'};
  16. static ByteCode* code;
  17. static int16 line = 1;
  18. static Variables vars;
  19. // static FunctionMap functions;
  20. /*static int returns[RETURN_BUFFER];
  21. static int returnIndex = 0;
  22. static int returnState = 0;
  23. static int breaks[BREAK_BUFFER];
  24. static int breakIndex = 0;
  25. static int forWhileStack = 0;
  26. static int continueAt = 0;*/
  27. typedef struct {
  28. Operation intOp;
  29. Operation floatOp;
  30. Operation boolOp;
  31. const char* name;
  32. } TypedOp;
  33. static const TypedOp TYPED_MUL = {OP_MUL_INT, OP_MUL_FLOAT, OP_NOTHING, "*"};
  34. static const TypedOp TYPED_DIV = {OP_DIV_INT, OP_DIV_FLOAT, OP_NOTHING, "/"};
  35. static const TypedOp TYPED_MOD = {OP_MOD_INT, OP_NOTHING, OP_NOTHING, "%"};
  36. static const TypedOp TYPED_ADD = {OP_ADD_INT, OP_ADD_FLOAT, OP_NOTHING, "+"};
  37. static const TypedOp TYPED_SUB = {OP_SUB_INT, OP_SUB_FLOAT, OP_NOTHING, "-"};
  38. static const TypedOp TYPED_LESS = {OP_LESS_INT, OP_LESS_FLOAT, OP_NOTHING, "<"};
  39. static const TypedOp TYPED_LESS_EQUAL = {OP_GREATER_INT, OP_GREATER_FLOAT,
  40. OP_NOTHING, "<="};
  41. static const TypedOp TYPED_GREATER = {OP_GREATER_INT, OP_GREATER_FLOAT,
  42. OP_NOTHING, ">"};
  43. static const TypedOp TYPED_GREATER_EQUAL = {OP_LESS_INT, OP_LESS_FLOAT,
  44. OP_NOTHING, ">="};
  45. static const TypedOp TYPED_EQUAL = {OP_EQUAL_INT, OP_EQUAL_FLOAT, OP_EQUAL_BOOL,
  46. "=="};
  47. static const TypedOp TYPED_NOT_EQUAL = {OP_EQUAL_INT, OP_EQUAL_FLOAT,
  48. OP_EQUAL_BOOL, "!="};
  49. static void cError(const char* format, ...) {
  50. va_list args;
  51. va_start(args, format);
  52. vsnprintf(error, ERROR_LENGTH, format, args);
  53. va_end(args);
  54. longjmp(errorJump, 0);
  55. }
  56. static void cInvalidOperation(DataType a, DataType b, const char* op) {
  57. cError("invalid operation: %s %s %s", dtGetName(a), op, dtGetName(b));
  58. }
  59. static void cNotDeclared(const char* name) {
  60. cError("variable %s has not been declared", name);
  61. }
  62. static void cNotInitialized(const char* name) {
  63. cError("variable %s has not been initialized", name);
  64. }
  65. /*static int cAddVar(const char* var) {
  66. int index = vars[varIndex].entries;
  67. simAdd(vars + varIndex, var, &index);
  68. return index;
  69. }*/
  70. static void cUnexpectedToken(Token t) {
  71. cError("unexpected token on line %d: %s", line, tGetName(t));
  72. }
  73. static void cAddOperation(Operation token) {
  74. unsigned char c = token;
  75. bcAddBytes(code, &c, 1);
  76. }
  77. /*static int cReserveInt() {
  78. return bcReserveBytes(code, sizeof(int));
  79. }
  80. static void cSetInt(int p, int i) {
  81. bcSetBytes(code, p, &i, sizeof(int));
  82. }*/
  83. static void cAddInt(int i) {
  84. bcAddBytes(code, &i, sizeof(int));
  85. }
  86. static void cAddInt16(int16 i) {
  87. bcAddBytes(code, &i, sizeof(int16));
  88. }
  89. /*static int cAddPush(int offset) {
  90. cAddOperation(OP_PUSH_VARS);
  91. int p = cReserveInt();
  92. cAddInt(offset);
  93. return p;
  94. }
  95. static void cAddPop(int p, int vars) {
  96. cAddOperation(OP_POP_VARS);
  97. cAddInt(vars);
  98. cSetInt(p, vars);
  99. }*/
  100. static Token cReadTokenAndLine() {
  101. Token t = tReadToken();
  102. if(tReadInt16(&line)) {
  103. return t;
  104. }
  105. return T_END;
  106. }
  107. static void cConsumeToken(Token wanted) {
  108. Token t = cReadTokenAndLine();
  109. if(wanted != t) {
  110. cError("unexpected token on line %d: expected '%s' got '%s'", line,
  111. tGetName(wanted), tGetName(t));
  112. }
  113. }
  114. static bool cConsumeTokenIf(Token t) {
  115. if(tPeekToken() == t) {
  116. cReadTokenAndLine();
  117. return true;
  118. }
  119. return false;
  120. }
  121. static void cConstantInt() {
  122. int value;
  123. if(!tReadInt(&value)) {
  124. cError("int token without an int on line %d", line);
  125. }
  126. cAddOperation(OP_PUSH_INT);
  127. cAddInt(value);
  128. }
  129. static void cConstantFloat() {
  130. float value;
  131. if(!tReadFloat(&value)) {
  132. cError("float token without a float on line %d", line);
  133. }
  134. cAddOperation(OP_PUSH_FLOAT);
  135. bcAddBytes(code, &value, sizeof(float));
  136. }
  137. /*static void cConstantString() {
  138. int length;
  139. const char* s = tReadString(&length);
  140. if(s == NULL) {
  141. cError("text without string on line %d", line);
  142. }
  143. cAddOperation(OP_PUSH_CONST_STRING);
  144. cAddInt(length);
  145. bcAddBytes(code, s, length);
  146. }*/
  147. static const char* cReadString() {
  148. int length;
  149. const char* literal = tReadString(&length);
  150. if(literal == NULL) {
  151. cError("literal without string on line %d", line);
  152. }
  153. return literal;
  154. }
  155. static DataType cExpression();
  156. /*static int cCallFunctionArguments() {
  157. int arguments = 0;
  158. while(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
  159. arguments++;
  160. cExpression();
  161. if(cConsumeTokenIf(T_COMMA) && tPeekToken() == T_CLOSE_BRACKET) {
  162. cUnexpectedToken(tPeekToken());
  163. }
  164. }
  165. return arguments;
  166. }
  167. static void cCallFunction(const char* literal, bool noReturn) {
  168. cAddOperation(OP_PUSH_INT);
  169. cAddInt(0);
  170. int arguments = cCallFunctionArguments();
  171. Function* f = fmSearch(&functions, literal, arguments);
  172. cAddOperation(OP_GOSUB);
  173. if(f == NULL) {
  174. fmEnqueue(&functions, literal, arguments, line, cReserveInt(),
  175. noReturn);
  176. cAddInt(arguments);
  177. cAddOperation(OP_NOTHING);
  178. } else {
  179. if(!noReturn && !f->returns) {
  180. cError("function '%s' needs a return value on line %d", f->name,
  181. line);
  182. }
  183. cAddInt(f->address);
  184. cAddInt(arguments);
  185. if(f->returns && noReturn) {
  186. cAddOperation(OP_POP);
  187. }
  188. }
  189. }*/
  190. static void cAddReference(int address) {
  191. // if(cConsumeTokenIf(T_OPEN_SQUARE_BRACKET)) {
  192. // cExpression();
  193. // cAddOperation(OP_REFERENCE_FROM_ARRAY);
  194. // cAddInt(cAddVar(var));
  195. // cConsumeToken(T_CLOSE_SQUARE_BRACKET);
  196. //} else {
  197. cAddOperation(OP_REFERENCE_FROM_VAR);
  198. cAddInt(address);
  199. //}
  200. }
  201. static DataType cLiteral() {
  202. const char* literal = cReadString();
  203. /*if(cConsumeTokenIf(T_OPEN_BRACKET)) {
  204. cCallFunction(literal, false);
  205. return;
  206. }*/
  207. Variable* v = vSearch(&vars, literal);
  208. if(v == NULL) {
  209. cNotDeclared(literal);
  210. } else if(!v->initialized) {
  211. cNotInitialized(literal);
  212. }
  213. cAddReference(v->address);
  214. cAddOperation(OP_DEREFERENCE_INT);
  215. return v->type;
  216. /*if(cConsumeTokenIf(T_INCREMENT)) {
  217. cAddOperation(OP_POST_INCREMENT);
  218. } else if(cConsumeTokenIf(T_DECREMENT)) {
  219. cAddOperation(OP_POST_DECREMENT);
  220. } else if(cConsumeTokenIf(T_POINT)) {
  221. cConsumeToken(T_LITERAL);
  222. const char* access = cReadString();
  223. if(strcmp(access, "length") == 0) {
  224. cAddOperation(OP_ARRAY_LENGTH);
  225. } else {
  226. cError("'%s' not supported after . on line %d", access, line);
  227. }
  228. } else {
  229. cAddOperation(OP_DEREFERENCE);
  230. }*/
  231. }
  232. /*static void cArray() {
  233. cConsumeToken(T_OPEN_SQUARE_BRACKET);
  234. cExpression();
  235. cConsumeToken(T_CLOSE_SQUARE_BRACKET);
  236. cAddOperation(OP_ALLOCATE_ARRAY);
  237. }*/
  238. static DataType cBracketPrimary() {
  239. DataType result = cExpression();
  240. cConsumeToken(T_CLOSE_BRACKET);
  241. return result;
  242. }
  243. static DataType cPrimary() {
  244. Token t = cReadTokenAndLine();
  245. switch(t) {
  246. case T_CONST_INT: cConstantInt(); return DT_INT;
  247. case T_FLOAT: cConstantFloat(); return DT_FLOAT;
  248. // case T_TEXT: cConstantString(); break;
  249. // case T_NULL: cAddOperation(OP_PUSH_NULL); break;
  250. case T_TRUE: cAddOperation(OP_PUSH_TRUE); return DT_BOOL;
  251. case T_FALSE: cAddOperation(OP_PUSH_FALSE); return DT_BOOL;
  252. case T_OPEN_BRACKET: return cBracketPrimary();
  253. case T_LITERAL: return cLiteral();
  254. // case T_ARRAY: cArray(); break;
  255. default: cUnexpectedToken(t); return DT_VOID;
  256. }
  257. }
  258. /*static void cPreChange(Operation op) {
  259. cConsumeToken(T_LITERAL);
  260. cAddReference(cReadString());
  261. cAddOperation(op);
  262. }*/
  263. static DataType cPreUnary() {
  264. if(cConsumeTokenIf(T_SUB)) {
  265. DataType result = cPrimary();
  266. switch(result) {
  267. case DT_INT: cAddOperation(OP_INVERT_SIGN_INT); break;
  268. case DT_FLOAT: cAddOperation(OP_INVERT_SIGN_FLOAT); break;
  269. default: cError("cannot invert sign of %s", dtGetName(result));
  270. }
  271. return result;
  272. } /*else if(cConsumeTokenIf(T_INCREMENT)) {
  273. cPreChange(OP_PRE_INCREMENT);
  274. } else if(cConsumeTokenIf(T_DECREMENT)) {
  275. cPreChange(OP_PRE_DECREMENT);
  276. } else if(cConsumeTokenIf(T_NOT)) {
  277. int counter = 1;
  278. while(cConsumeTokenIf(T_NOT)) {
  279. counter++;
  280. }
  281. cPrimary();
  282. cAddOperation(OP_NOT);
  283. if((counter & 1) == 0) {
  284. cAddOperation(OP_NOT);
  285. }
  286. } else if(cConsumeTokenIf(T_BIT_NOT)) {
  287. cPrimary();
  288. cAddOperation(OP_BIT_NOT);
  289. } else {*/
  290. return cPrimary();
  291. //}
  292. }
  293. static void cAddTypeOperation(DataType a, DataType b, const TypedOp* op) {
  294. if(a == DT_INT && b == DT_INT && op->intOp != OP_NOTHING) {
  295. cAddOperation(op->intOp);
  296. } else if(a == DT_FLOAT && b == DT_FLOAT && op->floatOp != OP_NOTHING) {
  297. cAddOperation(op->floatOp);
  298. } else if(a == DT_BOOL && b == DT_BOOL && op->boolOp != OP_NOTHING) {
  299. cAddOperation(op->boolOp);
  300. } else {
  301. cInvalidOperation(a, b, op->name);
  302. }
  303. }
  304. static DataType cMul() {
  305. DataType a = cPreUnary();
  306. while(true) {
  307. if(cConsumeTokenIf(T_MUL)) {
  308. cAddTypeOperation(a, cPreUnary(), &TYPED_MUL);
  309. } else if(cConsumeTokenIf(T_DIV)) {
  310. cAddTypeOperation(a, cPreUnary(), &TYPED_DIV);
  311. } else if(cConsumeTokenIf(T_MOD)) {
  312. cAddTypeOperation(a, cPreUnary(), &TYPED_MOD);
  313. } else {
  314. break;
  315. }
  316. }
  317. return a;
  318. }
  319. static DataType cAdd() {
  320. DataType a = cMul();
  321. while(true) {
  322. if(cConsumeTokenIf(T_ADD)) {
  323. cAddTypeOperation(a, cMul(), &TYPED_ADD);
  324. } else if(cConsumeTokenIf(T_SUB)) {
  325. cAddTypeOperation(a, cMul(), &TYPED_SUB);
  326. } else {
  327. break;
  328. }
  329. }
  330. return a;
  331. }
  332. static DataType cShift() {
  333. return cAdd();
  334. /*while(true) {
  335. if(cConsumeTokenIf(T_LEFT_SHIFT)) {
  336. cAdd();
  337. cAddOperation(OP_LEFT_SHIFT);
  338. } else if(cConsumeTokenIf(T_RIGHT_SHIFT)) {
  339. cAdd();
  340. cAddOperation(OP_RIGHT_SHIFT);
  341. } else {
  342. break;
  343. }
  344. }*/
  345. }
  346. static DataType cComparison() {
  347. DataType a = cShift();
  348. while(true) {
  349. if(cConsumeTokenIf(T_LESS)) {
  350. cAddTypeOperation(a, cShift(), &TYPED_LESS);
  351. a = DT_BOOL;
  352. } else if(cConsumeTokenIf(T_LESS_EQUAL)) {
  353. cAddTypeOperation(a, cShift(), &TYPED_LESS_EQUAL);
  354. cAddOperation(OP_NOT);
  355. a = DT_BOOL;
  356. } else if(cConsumeTokenIf(T_GREATER)) {
  357. cAddTypeOperation(a, cShift(), &TYPED_GREATER);
  358. a = DT_BOOL;
  359. } else if(cConsumeTokenIf(T_GREATER_EQUAL)) {
  360. cAddTypeOperation(a, cShift(), &TYPED_GREATER_EQUAL);
  361. cAddOperation(OP_NOT);
  362. a = DT_BOOL;
  363. } else {
  364. break;
  365. }
  366. }
  367. return a;
  368. }
  369. static DataType cEqual() {
  370. DataType a = cComparison();
  371. while(true) {
  372. if(cConsumeTokenIf(T_EQUAL)) {
  373. cAddTypeOperation(a, cComparison(), &TYPED_EQUAL);
  374. a = DT_BOOL;
  375. } else if(cConsumeTokenIf(T_NOT_EQUAL)) {
  376. cAddTypeOperation(a, cComparison(), &TYPED_NOT_EQUAL);
  377. cAddOperation(OP_NOT);
  378. a = DT_BOOL;
  379. } else {
  380. break;
  381. }
  382. }
  383. return a;
  384. }
  385. static DataType cBitAnd() {
  386. return cEqual();
  387. /*while(cConsumeTokenIf(T_BIT_AND)) {
  388. cEqual();
  389. cAddOperation(OP_BIT_AND);
  390. }*/
  391. }
  392. static DataType cBitXor() {
  393. return cBitAnd();
  394. /*while(cConsumeTokenIf(T_BIT_XOR)) {
  395. cBitAnd();
  396. cAddOperation(OP_BIT_XOR);
  397. }*/
  398. }
  399. static DataType cBitOr() {
  400. return cBitXor();
  401. /*while(cConsumeTokenIf(T_BIT_OR)) {
  402. cBitXor();
  403. cAddOperation(OP_BIT_OR);
  404. }*/
  405. }
  406. static DataType cAnd() {
  407. return cBitOr();
  408. /*while(cConsumeTokenIf(T_AND)) {
  409. cAddOperation(OP_DUPLICATE);
  410. cAddOperation(OP_IF_GOTO);
  411. int p = cReserveInt();
  412. cBitOr();
  413. cAddOperation(OP_AND);
  414. cSetInt(p, code->length);
  415. }*/
  416. }
  417. static DataType cOr() {
  418. return cAnd();
  419. /*while(cConsumeTokenIf(T_OR)) {
  420. cAddOperation(OP_DUPLICATE);
  421. cAddOperation(OP_NOT);
  422. cAddOperation(OP_IF_GOTO);
  423. int p = cReserveInt();
  424. cAnd();
  425. cAddOperation(OP_OR);
  426. cSetInt(p, code->length);
  427. }*/
  428. }
  429. static DataType cExpression() {
  430. return cOr();
  431. }
  432. /*static void cOperationSet(Operation op) {
  433. cAddOperation(OP_DUPLICATE);
  434. cAddOperation(OP_DEREFERENCE);
  435. cExpression();
  436. cAddOperation(op);
  437. cAddOperation(OP_SET);
  438. }*/
  439. static void cLineLiteral() {
  440. const char* literal = cReadString();
  441. /*if(cConsumeTokenIf(T_OPEN_BRACKET)) {
  442. cCallFunction(literal, true);
  443. return;
  444. }*/
  445. Variable* v = vSearch(&vars, literal);
  446. if(v == NULL) {
  447. cNotDeclared(literal);
  448. }
  449. cAddReference(v->address);
  450. cConsumeToken(T_SET);
  451. DataType dt = cExpression();
  452. if(v->type != dt) {
  453. cInvalidOperation(v->type, dt, "=");
  454. }
  455. if(dt == DT_INT) {
  456. cAddOperation(OP_SET_INT);
  457. } else {
  458. cError("%s cannot be set", dtGetName(dt));
  459. }
  460. v->initialized = true;
  461. /*Token t = cReadTokenAndLine();
  462. switch(t) {
  463. case T_SET:
  464. cExpression();
  465. cAddOperation(OP_SET);
  466. break;
  467. case T_ADD_SET: cOperationSet(OP_ADD); break;
  468. case T_SUB_SET: cOperationSet(OP_SUB); break;
  469. case T_MUL_SET: cOperationSet(OP_MUL); break;
  470. case T_DIV_SET: cOperationSet(OP_DIV); break;
  471. case T_MOD_SET: cOperationSet(OP_MOD); break;
  472. case T_BIT_AND_SET: cOperationSet(OP_BIT_AND); break;
  473. case T_BIT_OR_SET: cOperationSet(OP_BIT_OR); break;
  474. case T_BIT_XOR_SET: cOperationSet(OP_BIT_XOR); break;
  475. case T_LEFT_SHIFT_SET: cOperationSet(OP_LEFT_SHIFT); break;
  476. case T_RIGHT_SHIFT_SET: cOperationSet(OP_RIGHT_SHIFT); break;
  477. case T_INCREMENT:
  478. cAddOperation(OP_POST_INCREMENT);
  479. cAddOperation(OP_POP);
  480. break;
  481. case T_DECREMENT:
  482. cAddOperation(OP_POST_DECREMENT);
  483. cAddOperation(OP_POP);
  484. break;
  485. default: cUnexpectedToken(t);
  486. }*/
  487. }
  488. /*static int cFunctionArguments() {
  489. int arguments = 0;
  490. while(!cConsumeTokenIf(T_CLOSE_BRACKET)) {
  491. cConsumeToken(T_LITERAL);
  492. arguments++;
  493. cAddVar(cReadString());
  494. if(cConsumeTokenIf(T_COMMA) && tPeekToken() != T_LITERAL) {
  495. cUnexpectedToken(tPeekToken());
  496. }
  497. }
  498. return arguments;
  499. }
  500. static void cLine(Token t);
  501. static void cConsumeBody() {
  502. cConsumeToken(T_OPEN_CURVED_BRACKET);
  503. int oldLine = line;
  504. while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) {
  505. Token t = cReadTokenAndLine();
  506. if(t == T_END) {
  507. cError(
  508. "unexpected end of file: non closed curved bracket on line %d",
  509. oldLine);
  510. }
  511. cLine(t);
  512. }
  513. }
  514. static void cLinkReturns() {
  515. for(int i = 0; i < returnIndex; i++) {
  516. cSetInt(returns[i], vars[1].entries);
  517. }
  518. returnIndex = 0;
  519. }
  520. static void cFunctionBody(const char* name, int arguments) {
  521. int oldLine = line;
  522. cAddOperation(OP_GOTO);
  523. int gotoIndex = cReserveInt();
  524. int address = code->length;
  525. returnState = 0;
  526. int p = cAddPush(arguments);
  527. cConsumeBody();
  528. cAddPop(p, vars[1].entries);
  529. cLinkReturns();
  530. if(!fmAdd(&functions, name, arguments, address, returnState == 2)) {
  531. cError("function registered twice on line %d", oldLine);
  532. }
  533. cAddOperation(OP_RETURN);
  534. cSetInt(gotoIndex, code->length);
  535. }
  536. static void cFunction() {
  537. if(varIndex == 1) {
  538. cError("function inside function on line %d", line);
  539. }
  540. cConsumeToken(T_LITERAL);
  541. const char* name = cReadString();
  542. cConsumeToken(T_OPEN_BRACKET);
  543. varIndex = 1;
  544. vars[1].entries = 0;
  545. cFunctionBody(name, cFunctionArguments());
  546. varIndex = 0;
  547. }
  548. static void cAddReturn() {
  549. cAddOperation(OP_POP_VARS);
  550. returns[returnIndex++] = cReserveInt(vars);
  551. cAddOperation(OP_RETURN);
  552. }
  553. static void cReturn() {
  554. if(varIndex == 0) {
  555. cError("return without a function on line %d", line);
  556. } else if(returnIndex >= RETURN_BUFFER) {
  557. cError("too much returns in function around line %d", line);
  558. }
  559. if(cConsumeTokenIf(T_SEMICOLON)) {
  560. if(returnState == 2) {
  561. cError("mixed return type on line %d", line);
  562. }
  563. returnState = 1;
  564. cAddReturn();
  565. } else {
  566. if(returnState == 1) {
  567. cError("mixed return type on line %d", line);
  568. }
  569. returnState = 2;
  570. cExpression();
  571. cAddOperation(OP_SET_RETURN);
  572. cAddReturn();
  573. cConsumeToken(T_SEMICOLON);
  574. }
  575. }*/
  576. static void cPrint() {
  577. DataType dt = cExpression();
  578. switch(dt) {
  579. case DT_INT: cAddOperation(OP_PRINT_INT); break;
  580. case DT_FLOAT: cAddOperation(OP_PRINT_FLOAT); break;
  581. case DT_BOOL: cAddOperation(OP_PRINT_BOOL); break;
  582. default: cError("cannot print data type %s", dtGetName(dt));
  583. }
  584. cConsumeToken(T_SEMICOLON);
  585. }
  586. /*static void cIf() {
  587. cConsumeToken(T_OPEN_BRACKET);
  588. cExpression();
  589. cConsumeToken(T_CLOSE_BRACKET);
  590. cAddOperation(OP_IF_GOTO);
  591. int ifP = cReserveInt();
  592. cConsumeBody();
  593. cSetInt(ifP, code->length);
  594. if(cConsumeTokenIf(T_ELSE)) {
  595. cAddOperation(OP_GOTO);
  596. int elseP = cReserveInt();
  597. cSetInt(ifP, code->length);
  598. if(cConsumeTokenIf(T_IF)) {
  599. cIf();
  600. } else {
  601. cConsumeBody();
  602. }
  603. cSetInt(elseP, code->length);
  604. }
  605. }
  606. static void cConsumeBreaks(int start, int address) {
  607. for(int i = start; i < breakIndex; i++) {
  608. cSetInt(breaks[i], address);
  609. }
  610. breakIndex = start;
  611. }
  612. static void cWhile() {
  613. int start = code->length;
  614. cConsumeToken(T_OPEN_BRACKET);
  615. cExpression();
  616. cConsumeToken(T_CLOSE_BRACKET);
  617. cAddOperation(OP_IF_GOTO);
  618. int ifP = cReserveInt();
  619. int breakStart = breakIndex;
  620. forWhileStack++;
  621. int oldContinue = continueAt;
  622. continueAt = start;
  623. cConsumeBody();
  624. continueAt = oldContinue;
  625. forWhileStack--;
  626. cAddOperation(OP_GOTO);
  627. cAddInt(start);
  628. cSetInt(ifP, code->length);
  629. cConsumeBreaks(breakStart, code->length);
  630. }*/
  631. static void cInt() {
  632. cConsumeToken(T_LITERAL);
  633. const char* var = cReadString();
  634. Variable* v = vSearch(&vars, var);
  635. if(v != NULL) {
  636. cError("%s has already been declared", var);
  637. }
  638. v = vAdd(&vars, var, DT_INT);
  639. if(tPeekToken() == T_SEMICOLON) {
  640. return;
  641. }
  642. cConsumeToken(T_SET);
  643. cAddReference(v->address);
  644. DataType dt = cExpression();
  645. if(dt != DT_INT) {
  646. cInvalidOperation(DT_INT, dt, "=");
  647. }
  648. cAddOperation(OP_SET_INT);
  649. v->initialized = true;
  650. }
  651. static void cLineExpression(Token t) {
  652. switch(t) {
  653. case T_LITERAL: cLineLiteral(); break;
  654. case T_INT: cInt(); break;
  655. /*case T_INCREMENT:
  656. cPreChange(OP_PRE_INCREMENT);
  657. cAddOperation(OP_POP);
  658. break;
  659. case T_DECREMENT:
  660. cPreChange(OP_PRE_DECREMENT);
  661. cAddOperation(OP_POP);
  662. break;*/
  663. default: cUnexpectedToken(t);
  664. }
  665. }
  666. /*static void cFor() {
  667. cConsumeToken(T_OPEN_BRACKET);
  668. cLineExpression(cReadTokenAndLine());
  669. cConsumeToken(T_SEMICOLON);
  670. int startCheck = code->length;
  671. cExpression();
  672. cConsumeToken(T_SEMICOLON);
  673. cAddOperation(OP_IF_GOTO);
  674. int end = cReserveInt();
  675. cAddOperation(OP_GOTO);
  676. int beginBody = cReserveInt();
  677. int startPerLoop = code->length;
  678. cLineExpression(cReadTokenAndLine());
  679. cAddOperation(OP_GOTO);
  680. cAddInt(startCheck);
  681. cConsumeToken(T_CLOSE_BRACKET);
  682. cSetInt(beginBody, code->length);
  683. int breakStart = breakIndex;
  684. forWhileStack++;
  685. int oldContinue = continueAt;
  686. continueAt = startPerLoop;
  687. cConsumeBody();
  688. continueAt = oldContinue;
  689. forWhileStack--;
  690. cAddOperation(OP_GOTO);
  691. cAddInt(startPerLoop);
  692. cSetInt(end, code->length);
  693. cConsumeBreaks(breakStart, code->length);
  694. }
  695. static void cBreak() {
  696. if(forWhileStack == 0) {
  697. cError("break without for or while on line %d", line);
  698. } else if(breakIndex >= BREAK_BUFFER) {
  699. cError("too much breaks around line %d", line);
  700. }
  701. cAddOperation(OP_GOTO);
  702. breaks[breakIndex++] = cReserveInt();
  703. cConsumeToken(T_SEMICOLON);
  704. }
  705. static void cContinue() {
  706. if(forWhileStack == 0) {
  707. cError("continue without for or while on line %d", line);
  708. }
  709. cAddOperation(OP_GOTO);
  710. cAddInt(continueAt);
  711. cConsumeToken(T_SEMICOLON);
  712. }*/
  713. static void cLine(Token t) {
  714. cAddOperation(OP_LINE);
  715. cAddInt16(line);
  716. switch(t) {
  717. case T_PRINT: cPrint(); break;
  718. // case T_FUNCTION: cFunction(); break;
  719. // case T_RETURN: cReturn(); break;
  720. // case T_IF: cIf(); break;
  721. // case T_WHILE: cWhile(); break;
  722. // case T_FOR: cFor(); break;
  723. // case T_BREAK: cBreak(); break;
  724. // case T_CONTINUE: cContinue(); break;
  725. default: cLineExpression(t); cConsumeToken(T_SEMICOLON);
  726. }
  727. }
  728. static void cForEachLine() {
  729. Token t = cReadTokenAndLine();
  730. while(t != T_END) {
  731. cLine(t);
  732. t = cReadTokenAndLine();
  733. }
  734. }
  735. /*static void cLinkQueuedFunctions() {
  736. for(int i = 0; i < functions.queueEntries; i++) {
  737. Function* f = fmSearch(&functions, functions.queue[i].name,
  738. functions.queue[i].arguments);
  739. if(f == NULL) {
  740. cError("unknown function on line %d", functions.queue[i].line);
  741. } else if(!functions.queue[i].noReturn && !f->returns) {
  742. cError("function '%s' needs a return value on line %d", f->name,
  743. functions.queue[i].line);
  744. }
  745. cSetInt(functions.queue[i].reserved, f->address);
  746. if(functions.queue[i].noReturn && f->returns) {
  747. code->code[functions.queue[i].reserved + sizeof(int) * 2] = OP_POP;
  748. }
  749. }
  750. }*/
  751. static void cAllocAndCompile() {
  752. // varIndex = 0;
  753. // returnIndex = 0;
  754. // returnState = 0;
  755. // forWhileStack = 0;
  756. // breakIndex = 0;
  757. vInit(&vars);
  758. // fmInit(&functions);
  759. if(!setjmp(errorJump)) {
  760. // int p = cAddPush(0);
  761. cForEachLine();
  762. // cAddPop(p, vars[varIndex].entries);
  763. // cLinkQueuedFunctions();
  764. }
  765. // fmDelete(&functions);
  766. vDelete(&vars);
  767. }
  768. ByteCode* cCompile() {
  769. error[0] = '\0';
  770. code = bcInit();
  771. cAllocAndCompile();
  772. if(error[0] != '\0') {
  773. bcDelete(code);
  774. return NULL;
  775. }
  776. return code;
  777. }
  778. const char* cGetError() {
  779. return error;
  780. }
  781. int cGetLine() {
  782. return line;
  783. }