ajs.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #define MAX_TOKENS 1000
  6. #define MAX_VARS 100
  7. #define MAX_STACK 100
  8. #define MAX_SCOPES 10
  9. typedef enum {
  10. VAL_NUM,
  11. VAL_STR,
  12. VAL_OBJ
  13. } value_type_t;
  14. typedef enum {
  15. TOK_NUM,
  16. TOK_STR,
  17. TOK_IDENT,
  18. TOK_LET,
  19. TOK_IF,
  20. TOK_ELSE,
  21. TOK_WHILE,
  22. TOK_FOR,
  23. TOK_LPAREN,
  24. TOK_RPAREN,
  25. TOK_LBRACE,
  26. TOK_RBRACE,
  27. TOK_SEMI,
  28. TOK_EQ,
  29. TOK_PLUS,
  30. TOK_MINUS,
  31. TOK_MUL,
  32. TOK_DIV,
  33. TOK_LT,
  34. TOK_GT,
  35. TOK_LE,
  36. TOK_GE,
  37. TOK_EQEQ,
  38. TOK_NE,
  39. TOK_FUNC,
  40. TOK_RETURN,
  41. TOK_COMMA,
  42. TOK_DOT,
  43. TOK_COLON,
  44. TOK_EOF
  45. } token_type_t;
  46. typedef struct interpreter interpreter_t;
  47. typedef struct value {
  48. value_type_t type;
  49. union {
  50. double num;
  51. char *str;
  52. struct {
  53. struct value *fields;
  54. char **field_names;
  55. int field_count;
  56. } obj;
  57. struct {
  58. int func_start;
  59. int param_count;
  60. char **param_names;
  61. int is_native;
  62. struct value (*native_func)(interpreter_t *, struct value *, int);
  63. } func;
  64. } data;
  65. } value_t;
  66. typedef struct token {
  67. token_type_t type;
  68. char *value;
  69. value_t val;
  70. } token_t;
  71. typedef struct variable {
  72. char *name;
  73. value_t value;
  74. int is_func;
  75. int func_start;
  76. int param_count;
  77. char **param_names;
  78. } variable_t;
  79. typedef struct scope {
  80. variable_t vars[MAX_VARS];
  81. int var_count;
  82. } scope_t;
  83. typedef struct interpreter {
  84. token_t tokens[MAX_TOKENS];
  85. int token_count;
  86. int pos;
  87. scope_t scopes[MAX_SCOPES];
  88. int scope_depth;
  89. value_t stack[MAX_STACK];
  90. int stack_ptr;
  91. } interpreter_t;
  92. void init_interpreter(interpreter_t *interp);
  93. void push_scope(interpreter_t *interp);
  94. void pop_scope(interpreter_t *interp);
  95. value_t *get_var(interpreter_t *interp, const char *name);
  96. variable_t *get_var_def(interpreter_t *interp, const char *name);
  97. void skip_whitespace(const char **p);
  98. void tokenize(interpreter_t *interp, const char *code);
  99. value_t eval_expression(interpreter_t *interp);
  100. value_t eval_object(interpreter_t *interp);
  101. void execute_statement(interpreter_t *interp);
  102. void execute(interpreter_t *interp, const char *code);
  103. void print_value(value_t val) {
  104. switch (val.type) {
  105. case VAL_NUM:
  106. printf("%f", val.data.num);
  107. break;
  108. case VAL_STR:
  109. printf("%s", val.data.str);
  110. break;
  111. case VAL_OBJ:
  112. if (val.data.func.func_start != 0) {
  113. printf("[Function]");
  114. }
  115. else {
  116. printf("{");
  117. for (int i = 0; i < val.data.obj.field_count; i++) {
  118. printf("%s: ", val.data.obj.field_names[i]);
  119. print_value(val.data.obj.fields[i]);
  120. if (i < val.data.obj.field_count - 1) {
  121. printf(", ");
  122. }
  123. }
  124. printf("}");
  125. }
  126. break;
  127. }
  128. }
  129. value_t native_console_log(interpreter_t *interp, value_t *args, int arg_count) {
  130. if (arg_count > 0) {
  131. print_value(args[0]);
  132. printf("\n");
  133. }
  134. value_t result = {VAL_NUM};
  135. result.data.num = 0;
  136. return result;
  137. }
  138. void init_interpreter(interpreter_t *interp) {
  139. interp->token_count = 0;
  140. interp->pos = 0;
  141. interp->scope_depth = 0;
  142. interp->scopes[0].var_count = 0;
  143. interp->stack_ptr = 0;
  144. variable_t *console = &interp->scopes[0].vars[interp->scopes[0].var_count++];
  145. console->name = strdup("console");
  146. console->value.type = VAL_OBJ;
  147. console->value.data.obj.field_count = 1;
  148. console->value.data.obj.fields = malloc(sizeof(value_t));
  149. console->value.data.obj.field_names = malloc(sizeof(char *));
  150. console->value.data.obj.field_names[0] = strdup("log");
  151. console->is_func = 0;
  152. value_t log_func = {0};
  153. log_func.type = VAL_OBJ;
  154. log_func.data.func.func_start = -1;
  155. log_func.data.func.is_native = 1;
  156. log_func.data.func.native_func = native_console_log;
  157. log_func.data.func.param_count = 1;
  158. log_func.data.func.param_names = malloc(sizeof(char *));
  159. log_func.data.func.param_names[0] = strdup("arg");
  160. console->value.data.obj.fields[0] = log_func;
  161. }
  162. void push_scope(interpreter_t *interp) {
  163. interp->scope_depth++;
  164. interp->scopes[interp->scope_depth].var_count = 0;
  165. }
  166. void pop_scope(interpreter_t *interp) {
  167. interp->scope_depth--;
  168. }
  169. value_t *get_var(interpreter_t *interp, const char *name) {
  170. for (int s = interp->scope_depth; s >= 0; s--) {
  171. for (int i = 0; i < interp->scopes[s].var_count; i++) {
  172. if (strcmp(interp->scopes[s].vars[i].name, name) == 0) {
  173. return &interp->scopes[s].vars[i].value;
  174. }
  175. }
  176. }
  177. variable_t *v = &interp->scopes[interp->scope_depth].vars[interp->scopes[interp->scope_depth].var_count++];
  178. v->name = strdup(name);
  179. v->value.type = VAL_NUM;
  180. v->value.data.num = 0;
  181. v->is_func = 0;
  182. return &v->value;
  183. }
  184. variable_t *get_var_def(interpreter_t *interp, const char *name) {
  185. for (int s = interp->scope_depth; s >= 0; s--) {
  186. for (int i = 0; i < interp->scopes[s].var_count; i++) {
  187. if (strcmp(interp->scopes[s].vars[i].name, name) == 0) {
  188. return &interp->scopes[s].vars[i];
  189. }
  190. }
  191. }
  192. return NULL;
  193. }
  194. void skip_whitespace(const char **p) {
  195. while (isspace(**p)) {
  196. (*p)++;
  197. }
  198. }
  199. void tokenize(interpreter_t *interp, const char *code) {
  200. const char *p = code;
  201. while (*p) {
  202. skip_whitespace(&p);
  203. if (!*p) {
  204. break;
  205. }
  206. token_t *t = &interp->tokens[interp->token_count++];
  207. if (isdigit(*p)) {
  208. t->type = TOK_NUM;
  209. t->val.type = VAL_NUM;
  210. t->val.data.num = strtod(p, (char **)&p);
  211. }
  212. else if (*p == '"') {
  213. t->type = TOK_STR;
  214. t->val.type = VAL_STR;
  215. p++;
  216. const char *start = p;
  217. while (*p && *p != '"') {
  218. p++;
  219. }
  220. t->val.data.str = strndup(start, p - start);
  221. p++;
  222. }
  223. else if (isalpha(*p)) {
  224. const char *start = p;
  225. while (isalnum(*p)) p++;
  226. t->value = strndup(start, p - start);
  227. if (strcmp(t->value, "let") == 0) t->type = TOK_LET;
  228. else if (strcmp(t->value, "if") == 0) t->type = TOK_IF;
  229. else if (strcmp(t->value, "else") == 0) t->type = TOK_ELSE;
  230. else if (strcmp(t->value, "while") == 0) t->type = TOK_WHILE;
  231. else if (strcmp(t->value, "for") == 0) t->type = TOK_FOR;
  232. else if (strcmp(t->value, "function") == 0) t->type = TOK_FUNC;
  233. else if (strcmp(t->value, "return") == 0) t->type = TOK_RETURN;
  234. else t->type = TOK_IDENT;
  235. }
  236. else {
  237. switch (*p) {
  238. case '(': t->type = TOK_LPAREN; break;
  239. case ')': t->type = TOK_RPAREN; break;
  240. case '{': t->type = TOK_LBRACE; break;
  241. case '}': t->type = TOK_RBRACE; break;
  242. case ';': t->type = TOK_SEMI; break;
  243. case '=':
  244. if (*(p+1) == '=') { t->type = TOK_EQEQ; p++; }
  245. else t->type = TOK_EQ;
  246. break;
  247. case '+': t->type = TOK_PLUS; break;
  248. case '-': t->type = TOK_MINUS; break;
  249. case '*': t->type = TOK_MUL; break;
  250. case '/': t->type = TOK_DIV; break;
  251. case '<':
  252. if (*(p+1) == '=') { t->type = TOK_LE; p++; }
  253. else t->type = TOK_LT;
  254. break;
  255. case '>':
  256. if (*(p+1) == '=') { t->type = TOK_GE; p++; }
  257. else t->type = TOK_GT;
  258. break;
  259. case '!':
  260. if (*(p+1) == '=') { t->type = TOK_NE; p++; }
  261. break;
  262. case ',': t->type = TOK_COMMA; break;
  263. case '.': t->type = TOK_DOT; break;
  264. case ':': t->type = TOK_COLON; break;
  265. default: printf("Unknown char: %c\n", *p); exit(1);
  266. }
  267. p++;
  268. }
  269. }
  270. interp->tokens[interp->token_count++].type = TOK_EOF;
  271. }
  272. value_t eval_object(interpreter_t *interp) {
  273. value_t obj;
  274. obj.type = VAL_OBJ;
  275. obj.data.obj.field_count = 0;
  276. obj.data.obj.fields = NULL;
  277. obj.data.obj.field_names = NULL;
  278. interp->pos++;
  279. while (interp->tokens[interp->pos].type != TOK_RBRACE) {
  280. char *field_name = interp->tokens[interp->pos++].value;
  281. interp->pos++;
  282. value_t field_value = eval_expression(interp);
  283. obj.data.obj.fields = realloc(obj.data.obj.fields,
  284. sizeof(value_t) * (obj.data.obj.field_count + 1));
  285. obj.data.obj.field_names = realloc(obj.data.obj.field_names,
  286. sizeof(char *) * (obj.data.obj.field_count + 1));
  287. obj.data.obj.field_names[obj.data.obj.field_count] = strdup(field_name);
  288. obj.data.obj.fields[obj.data.obj.field_count] = field_value;
  289. obj.data.obj.field_count++;
  290. if (interp->tokens[interp->pos].type == TOK_COMMA) {
  291. interp->pos++;
  292. }
  293. }
  294. interp->pos++;
  295. return obj;
  296. }
  297. value_t eval_expression(interpreter_t *interp) {
  298. value_t left;
  299. memset(&left, 0, sizeof(value_t));
  300. if (interp->tokens[interp->pos].type == TOK_NUM ||
  301. interp->tokens[interp->pos].type == TOK_STR) {
  302. left = interp->tokens[interp->pos++].val;
  303. }
  304. else if (interp->tokens[interp->pos].type == TOK_IDENT) {
  305. char *name = interp->tokens[interp->pos++].value;
  306. if (interp->tokens[interp->pos].type == TOK_LPAREN) {
  307. variable_t *func_var = get_var_def(interp, name);
  308. if (func_var && func_var->is_func) {
  309. interp->pos++;
  310. value_t params[10];
  311. int param_count = 0;
  312. while (interp->tokens[interp->pos].type != TOK_RPAREN) {
  313. params[param_count++] = eval_expression(interp);
  314. if (interp->tokens[interp->pos].type == TOK_COMMA) {
  315. interp->pos++;
  316. }
  317. }
  318. interp->pos++;
  319. push_scope(interp);
  320. for (int i = 0; i < func_var->param_count; i++) {
  321. *get_var(interp, func_var->param_names[i]) = params[i];
  322. }
  323. int old_pos = interp->pos;
  324. interp->pos = func_var->func_start;
  325. execute_statement(interp);
  326. pop_scope(interp);
  327. interp->pos = old_pos;
  328. return interp->stack[--interp->stack_ptr];
  329. }
  330. }
  331. else if (interp->tokens[interp->pos].type == TOK_DOT) {
  332. interp->pos++;
  333. char *field = interp->tokens[interp->pos++].value;
  334. value_t *obj = get_var(interp, name);
  335. if (obj->type == VAL_OBJ) {
  336. for (int i = 0; i < obj->data.obj.field_count; i++) {
  337. if (strcmp(obj->data.obj.field_names[i], field) == 0) {
  338. value_t field_val = obj->data.obj.fields[i];
  339. if (interp->tokens[interp->pos].type == TOK_LPAREN) {
  340. interp->pos++;
  341. value_t params[10];
  342. int param_count = 0;
  343. while (interp->tokens[interp->pos].type != TOK_RPAREN) {
  344. params[param_count++] = eval_expression(interp);
  345. if (interp->tokens[interp->pos].type == TOK_COMMA) {
  346. interp->pos++;
  347. }
  348. }
  349. interp->pos++;
  350. if (field_val.type == VAL_OBJ && field_val.data.func.func_start != 0) {
  351. if (field_val.data.func.is_native) {
  352. return field_val.data.func.native_func(interp, params, param_count);
  353. }
  354. else {
  355. push_scope(interp);
  356. for (int j = 0; j < field_val.data.func.param_count; j++) {
  357. *get_var(interp, field_val.data.func.param_names[j]) = params[j];
  358. }
  359. int old_pos = interp->pos;
  360. interp->pos = field_val.data.func.func_start;
  361. execute_statement(interp);
  362. pop_scope(interp);
  363. interp->pos = old_pos;
  364. return interp->stack[--interp->stack_ptr];
  365. }
  366. }
  367. }
  368. return field_val;
  369. }
  370. }
  371. }
  372. }
  373. left = *get_var(interp, name);
  374. }
  375. else if (interp->tokens[interp->pos].type == TOK_LBRACE) {
  376. return eval_object(interp);
  377. }
  378. else if (interp->tokens[interp->pos].type == TOK_LPAREN) {
  379. interp->pos++;
  380. left = eval_expression(interp);
  381. interp->pos++;
  382. }
  383. while (interp->pos < interp->token_count) {
  384. token_type_t op = interp->tokens[interp->pos].type;
  385. if (op != TOK_PLUS && op != TOK_MINUS && op != TOK_MUL && op != TOK_DIV &&
  386. op != TOK_LT && op != TOK_GT && op != TOK_LE && op != TOK_GE &&
  387. op != TOK_EQEQ && op != TOK_NE) break;
  388. interp->pos++;
  389. value_t right = eval_expression(interp);
  390. if (left.type == VAL_NUM && right.type == VAL_NUM) {
  391. switch (op) {
  392. case TOK_PLUS: left.data.num += right.data.num; break;
  393. case TOK_MINUS: left.data.num -= right.data.num; break;
  394. case TOK_MUL: left.data.num *= right.data.num; break;
  395. case TOK_DIV: left.data.num /= right.data.num; break;
  396. case TOK_LT: left.type = VAL_NUM; left.data.num = left.data.num < right.data.num; break;
  397. case TOK_GT: left.type = VAL_NUM; left.data.num = left.data.num > right.data.num; break;
  398. case TOK_LE: left.type = VAL_NUM; left.data.num = left.data.num <= right.data.num; break;
  399. case TOK_GE: left.type = VAL_NUM; left.data.num = left.data.num >= right.data.num; break;
  400. case TOK_EQEQ: left.type = VAL_NUM; left.data.num = left.data.num == right.data.num; break;
  401. case TOK_NE: left.type = VAL_NUM; left.data.num = left.data.num != right.data.num; break;
  402. }
  403. }
  404. }
  405. return left;
  406. }
  407. void execute_statement(interpreter_t *interp) {
  408. while (interp->pos < interp->token_count &&
  409. interp->tokens[interp->pos].type != TOK_RBRACE) {
  410. token_t t = interp->tokens[interp->pos];
  411. if (t.type == TOK_IF) {
  412. interp->pos++; // Skip IF
  413. interp->pos++; // Skip LPAREN
  414. value_t cond = eval_expression(interp);
  415. interp->pos++; // Skip RPAREN
  416. interp->pos++; // Skip LBRACE
  417. push_scope(interp);
  418. int if_end_pos = interp->pos;
  419. if (cond.type == VAL_NUM && cond.data.num) {
  420. execute_statement(interp);
  421. if_end_pos = interp->pos;
  422. }
  423. else {
  424. while (interp->tokens[interp->pos].type != TOK_RBRACE) {
  425. interp->pos++;
  426. }
  427. if_end_pos = interp->pos;
  428. }
  429. pop_scope(interp);
  430. interp->pos++; // Skip RBRACE
  431. if (interp->tokens[interp->pos].type == TOK_ELSE) {
  432. interp->pos++; // Skip ELSE
  433. interp->pos++; // Skip LBRACE
  434. push_scope(interp);
  435. if (cond.type == VAL_NUM && !cond.data.num) {
  436. execute_statement(interp);
  437. }
  438. else {
  439. while (interp->tokens[interp->pos].type != TOK_RBRACE) {
  440. interp->pos++;
  441. }
  442. }
  443. pop_scope(interp);
  444. interp->pos++; // Skip RBRACE
  445. }
  446. else {
  447. interp->pos = if_end_pos + 1;
  448. }
  449. }
  450. else if (t.type == TOK_LET) {
  451. interp->pos++;
  452. char *name = interp->tokens[interp->pos++].value;
  453. interp->pos++;
  454. *get_var(interp, name) = eval_expression(interp);
  455. interp->pos++;
  456. }
  457. else if (t.type == TOK_FUNC) {
  458. interp->pos++;
  459. variable_t *v = &interp->scopes[interp->scope_depth].vars[interp->scopes[interp->scope_depth].var_count++];
  460. v->name = interp->tokens[interp->pos++].value;
  461. v->is_func = 1;
  462. interp->pos++;
  463. v->param_count = 0;
  464. v->param_names = NULL;
  465. while (interp->tokens[interp->pos].type != TOK_RPAREN) {
  466. v->param_names = realloc(v->param_names, sizeof(char *) * (v->param_count + 1));
  467. v->param_names[v->param_count++] = interp->tokens[interp->pos++].value;
  468. if (interp->tokens[interp->pos].type == TOK_COMMA) {
  469. interp->pos++;
  470. }
  471. }
  472. interp->pos++;
  473. interp->pos++;
  474. v->func_start = interp->pos;
  475. while (interp->tokens[interp->pos].type != TOK_RBRACE) {
  476. interp->pos++;
  477. }
  478. interp->pos++;
  479. }
  480. else if (t.type == TOK_RETURN) {
  481. interp->pos++;
  482. interp->stack[interp->stack_ptr++] = eval_expression(interp);
  483. interp->pos++;
  484. while (interp->tokens[interp->pos].type != TOK_RBRACE) {
  485. interp->pos++;
  486. }
  487. }
  488. else if (t.type == TOK_WHILE) {
  489. int start_pos = interp->pos;
  490. interp->pos++;
  491. interp->pos++;
  492. int cond_pos = interp->pos;
  493. value_t cond = eval_expression(interp);
  494. interp->pos++;
  495. interp->pos++;
  496. push_scope(interp);
  497. while (cond.type == VAL_NUM && cond.data.num) {
  498. execute_statement(interp);
  499. interp->pos = cond_pos;
  500. cond = eval_expression(interp);
  501. }
  502. pop_scope(interp);
  503. interp->pos++;
  504. }
  505. else if (t.type == TOK_FOR) {
  506. interp->pos++;
  507. interp->pos++;
  508. push_scope(interp);
  509. execute_statement(interp);
  510. int cond_pos = interp->pos;
  511. value_t cond = eval_expression(interp);
  512. interp->pos++;
  513. int update_pos = interp->pos;
  514. while (interp->tokens[interp->pos].type != TOK_RPAREN) interp->pos++;
  515. interp->pos++;
  516. interp->pos++;
  517. while (cond.type == VAL_NUM && cond.data.num) {
  518. execute_statement(interp);
  519. int save_pos = interp->pos;
  520. interp->pos = update_pos;
  521. eval_expression(interp);
  522. interp->pos = cond_pos;
  523. cond = eval_expression(interp);
  524. interp->pos = save_pos;
  525. }
  526. pop_scope(interp);
  527. interp->pos++;
  528. }
  529. else if (t.type == TOK_IDENT && interp->tokens[interp->pos+1].type == TOK_EQ) {
  530. char *name = t.value;
  531. interp->pos += 2;
  532. *get_var(interp, name) = eval_expression(interp);
  533. interp->pos++;
  534. }
  535. else {
  536. eval_expression(interp);
  537. interp->pos++;
  538. }
  539. }
  540. }
  541. void execute(interpreter_t *interp, const char *code) {
  542. tokenize(interp, code);
  543. interp->pos = 0;
  544. execute_statement(interp);
  545. }
  546. int main() {
  547. interpreter_t interp;
  548. init_interpreter(&interp);
  549. const char *code =
  550. "console.log(\"Hello, world!\");\n";
  551. execute(&interp, code);
  552. return 0;
  553. }