Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

611 строки
23 KiB

  1. Ast_Node* eval_expr(Ast_Node* node, Environment* env);
  2. Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, Environment* parent) {
  3. Environment* new_env = create_child_environment(parent);
  4. // positional arguments
  5. for (int i = 0; i < function->positional_arguments->next_index; ++i) {
  6. if (arguments->type == Ast_Node_Type_Pair) {
  7. define_symbol(
  8. create_ast_node_symbol(function->positional_arguments->identifiers[i]),
  9. arguments->value.pair->first, new_env);
  10. } else {
  11. // not enough arguments given
  12. create_error(Error_Type_Ill_Formed_Arguments, arguments);
  13. return nullptr;
  14. }
  15. arguments = arguments->value.pair->rest;
  16. }
  17. Ast_Node* result;
  18. try {
  19. result = eval_expr(function->body, new_env);
  20. }
  21. return result;
  22. }
  23. /* (define type (lambda (e) (if (and (= (old-type e) :pair) (= (first e) :my-type)) :my-type (old-type e)))) */
  24. /**
  25. This parses the argument specification of funcitons into their
  26. Function struct. It dois this by allocating new
  27. positional_arguments, keyword_arguments and rest_argument and
  28. filling it in
  29. */
  30. void parse_argument_list(Ast_Node* arguments, Function* function) {
  31. // first init the fields
  32. function->positional_arguments = create_positional_argument_list(16);
  33. function->keyword_arguments = create_keyword_argument_list(16);
  34. function->rest_argument = nullptr;
  35. // okay let's try to read some positional arguments
  36. while (arguments->type == Ast_Node_Type_Pair) {
  37. if (arguments->value.pair->first->type == Ast_Node_Type_Keyword) {
  38. if (string_equal(arguments->value.pair->first->value.keyword->identifier, "keys") ||
  39. string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
  40. break;
  41. else {
  42. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  43. return;
  44. }
  45. }
  46. if (arguments->value.pair->first->type != Ast_Node_Type_Symbol) {
  47. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  48. return;
  49. }
  50. // okay wow we found an actual symbol
  51. append_to_positional_argument_list(
  52. function->positional_arguments,
  53. arguments->value.pair->first->value.symbol->identifier);
  54. arguments = arguments->value.pair->rest;
  55. }
  56. // okay we are done with positional arguments, lets check for
  57. // keywords,
  58. if (arguments->type != Ast_Node_Type_Pair) {
  59. if (arguments->type != Ast_Node_Type_Nil)
  60. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  61. return;
  62. }
  63. if (arguments->value.pair->first->type == Ast_Node_Type_Keyword &&
  64. string_equal(arguments->value.pair->first->value.keyword->identifier, "keys"))
  65. {
  66. arguments = arguments->value.pair->rest;
  67. if (arguments->type != Ast_Node_Type_Pair ||
  68. arguments->value.pair->first->type != Ast_Node_Type_Symbol)
  69. {
  70. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  71. return;
  72. }
  73. while (arguments->type == Ast_Node_Type_Pair) {
  74. if (arguments->value.pair->first->type == Ast_Node_Type_Keyword) {
  75. if (string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
  76. break;
  77. else {
  78. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  79. return;
  80. }
  81. }
  82. if (arguments->value.pair->first->type != Ast_Node_Type_Symbol) {
  83. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  84. return;
  85. }
  86. // we found a symbol (arguments->value.pair->first) for
  87. // the keyword args! Let's check if the next arguement is
  88. // :defaults-to
  89. Ast_Node* next = arguments->value.pair->rest;
  90. if (next->type == Ast_Node_Type_Pair &&
  91. next->value.pair->first->type == Ast_Node_Type_Keyword &&
  92. string_equal(next->value.pair->first->value.keyword->identifier,
  93. "defaults-to"))
  94. {
  95. // check if there is a next argument too, otherwise it
  96. // would be an error
  97. next = next->value.pair->rest;
  98. if (next->type == Ast_Node_Type_Pair) {
  99. append_to_keyword_argument_list(function->keyword_arguments,
  100. arguments->value.pair->first->value.symbol->identifier,
  101. next->value.pair->first);
  102. arguments = next->value.pair->rest;
  103. } else {
  104. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  105. return;
  106. }
  107. } else {
  108. // No :defaults-to, so just add it to the list
  109. append_to_keyword_argument_list(function->keyword_arguments,
  110. arguments->value.pair->first->value.symbol->identifier,
  111. nullptr);
  112. arguments = next;
  113. }
  114. }
  115. }
  116. // Now we are also done with keyword arguments, lets check for
  117. // if there is a rest argument
  118. if (arguments->type != Ast_Node_Type_Pair) {
  119. if (arguments->type != Ast_Node_Type_Nil)
  120. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  121. return;
  122. }
  123. if (arguments->value.pair->first->type == Ast_Node_Type_Keyword &&
  124. string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
  125. {
  126. arguments = arguments->value.pair->rest;
  127. if (arguments->type != Ast_Node_Type_Pair ||
  128. arguments->value.pair->first->type != Ast_Node_Type_Symbol)
  129. {
  130. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  131. return;
  132. }
  133. function->rest_argument = arguments->value.pair->first->value.symbol->identifier;
  134. if (arguments->value.pair->rest->type != Ast_Node_Type_Nil) {
  135. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  136. }
  137. } else {
  138. printf("this should not happen?");
  139. create_error(Error_Type_Unknown_Error, arguments);
  140. }
  141. }
  142. int list_length(Ast_Node* node) {
  143. if (node->type == Ast_Node_Type_Nil)
  144. return 0;
  145. if (node->type != Ast_Node_Type_Pair) {
  146. create_error(Error_Type_Type_Missmatch, node);
  147. return 0;
  148. }
  149. int len = 0;
  150. while (node->type == Ast_Node_Type_Pair) {
  151. ++len;
  152. node = node->value.pair->rest;
  153. if (node->type == Ast_Node_Type_Nil)
  154. return len;
  155. }
  156. create_error(Error_Type_Ill_Formed_List, node);
  157. return 0;
  158. }
  159. /**
  160. Copies a list, in that it creates a new list, however the items are
  161. the same as in the original (same pointers). This is needed to copy
  162. a list when evaluating a parameters list, but not wanting to change
  163. the parameters list. This happens if you have someting like:
  164. (define a 10)
  165. (define condition (quote (= a 10)))
  166. (eval condition)
  167. > 1.00000
  168. If we wouldn't copy the parameters list, after calling eval would
  169. be baked into the quoted list. So even after changing a, the result
  170. of (eval condition) would be 1.00000.
  171. **/
  172. Ast_Node* copy_list(Ast_Node* node) {
  173. // we don't copy immutables in here
  174. if (node->type != Ast_Node_Type_Pair) {
  175. return node;
  176. }
  177. Ast_Node* result = new(Ast_Node);
  178. result->type = Ast_Node_Type_Pair;
  179. result->value.pair = new(Pair);
  180. result->value.pair->first = copy_list(node->value.pair->first);
  181. result->value.pair->rest = copy_list(node->value.pair->rest);
  182. return result;
  183. }
  184. bool is_truthy (Ast_Node* expression, Environment* env);
  185. Ast_Node* extract_keyword_value(char* keyword, Parsed_Arguments* args) {
  186. // NOTE(Felix): This will be a hashmap lookup later
  187. for (int i = 0; i < args->keyword_keys->next_index; ++i) {
  188. if (string_equal(args->keyword_keys->data[i]->value.keyword->identifier, keyword))
  189. return args->keyword_values->data[i];
  190. }
  191. return nullptr;
  192. }
  193. Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_arguments_length) {
  194. *out_arguments_length = 0;
  195. if (arguments->type == Ast_Node_Type_Nil) {
  196. return arguments;
  197. }
  198. Ast_Node* evaluated_arguments = create_ast_node_pair(nullptr, nullptr);
  199. Ast_Node* evaluated_arguments_head = evaluated_arguments;
  200. Ast_Node* current_head = arguments;
  201. while (current_head->type == Ast_Node_Type_Pair) {
  202. try {
  203. evaluated_arguments_head->value.pair->first =
  204. eval_expr(current_head->value.pair->first, env);
  205. }
  206. current_head = current_head->value.pair->rest;
  207. if (current_head->type == Ast_Node_Type_Pair) {
  208. evaluated_arguments_head->value.pair->rest = create_ast_node_pair(nullptr, nullptr);
  209. evaluated_arguments_head = evaluated_arguments_head->value.pair->rest;
  210. }
  211. else if (current_head->type == Ast_Node_Type_Nil) {
  212. evaluated_arguments_head->value.pair->rest = current_head;
  213. }
  214. else {
  215. create_error(Error_Type_Ill_Formed_Arguments, arguments);
  216. return nullptr;
  217. }
  218. ++(*out_arguments_length);
  219. }
  220. return evaluated_arguments;
  221. }
  222. Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
  223. #define report_error(_type) { \
  224. create_error(_type, node); \
  225. return nullptr; \
  226. }
  227. if (error)
  228. return nullptr;
  229. Ast_Node* ret = new(Ast_Node);
  230. switch (node->type) {
  231. case Ast_Node_Type_Nil:
  232. ret->type = Ast_Node_Type_Nil;
  233. return ret;
  234. case Ast_Node_Type_Symbol: {
  235. Ast_Node* symbol;
  236. try {
  237. symbol = lookup_symbol(node->value.symbol, env);
  238. }
  239. return symbol;
  240. }
  241. case Ast_Node_Type_Number:
  242. case Ast_Node_Type_Keyword:
  243. case Ast_Node_Type_String:
  244. return node;
  245. case Ast_Node_Type_Pair: {
  246. Ast_Node* operator;
  247. if (node->value.pair->first->type != Ast_Node_Type_Built_In_Function) {
  248. try {
  249. operator = eval_expr(node->value.pair->first, env);
  250. }
  251. } else {
  252. operator = node->value.pair->first;
  253. }
  254. Ast_Node* arguments = node->value.pair->rest;
  255. int arguments_length;
  256. // check for special form
  257. if (operator->type == Ast_Node_Type_Built_In_Function) {
  258. switch (operator->value.built_in_function->type) {
  259. case Built_In_Lambda: {
  260. /*
  261. * (lambda ())
  262. * (lambda (x d) (+ 1 2) (- 1 2) (* 1 2))
  263. */
  264. try {
  265. arguments_length = list_length(arguments);
  266. }
  267. if (arguments_length == 0)
  268. report_error(Error_Type_Wrong_Number_Of_Arguments);
  269. Function* function = new(Function);
  270. // if parameters were specified
  271. if (arguments->value.pair->first->type != Ast_Node_Type_Nil) {
  272. try {
  273. assert_type(arguments->value.pair->first, Ast_Node_Type_Pair);
  274. }
  275. try {
  276. parse_argument_list(arguments->value.pair->first, function);
  277. }
  278. }
  279. arguments = arguments->value.pair->rest;
  280. // if there is a docstring, use it
  281. if (arguments->value.pair->first->type == Ast_Node_Type_String) {
  282. function->docstring = arguments->value.pair->first->value.string->value;
  283. arguments = arguments->value.pair->rest;
  284. }
  285. // we are now in the function body, just wrap it in an
  286. // implicit prog
  287. function->body = create_ast_node_pair(
  288. create_ast_node_built_in_function("prog"),
  289. arguments);
  290. Ast_Node* ret = new(Ast_Node);
  291. ret->type = Ast_Node_Type_Function;
  292. ret->value.function = function;
  293. return ret;
  294. }
  295. case Built_In_And: {
  296. bool result = true;
  297. while (arguments->type != Ast_Node_Type_Nil) {
  298. if (arguments->type != Ast_Node_Type_Pair) {
  299. report_error(Error_Type_Ill_Formed_List);
  300. }
  301. try {
  302. result &= is_truthy(arguments->value.pair->first, env);
  303. }
  304. arguments = arguments->value.pair->rest;
  305. if (!result) return create_ast_node_nil();
  306. }
  307. return create_ast_node_number(1);
  308. }
  309. case Built_In_Or: {
  310. bool result = false;
  311. while (arguments->type != Ast_Node_Type_Nil) {
  312. if (arguments->type != Ast_Node_Type_Pair) {
  313. report_error(Error_Type_Ill_Formed_List);
  314. }
  315. try {
  316. result |= is_truthy(arguments->value.pair->first, env);
  317. }
  318. arguments = arguments->value.pair->rest;
  319. if (result) return create_ast_node_number(1);;
  320. }
  321. return create_ast_node_nil();
  322. }
  323. case Built_In_Not: {
  324. try {
  325. arguments_length = list_length(arguments);
  326. }
  327. if (arguments_length != 1) {
  328. report_error(Error_Type_Wrong_Number_Of_Arguments);
  329. }
  330. bool truthy;
  331. try {
  332. truthy = is_truthy(arguments->value.pair->first, env);
  333. }
  334. if (truthy)
  335. return create_ast_node_nil();
  336. return create_ast_node_number(1);
  337. }
  338. case Built_In_If: {
  339. try {
  340. arguments_length = list_length(arguments);
  341. }
  342. if (arguments_length != 2 && arguments_length != 3) {
  343. report_error(Error_Type_Wrong_Number_Of_Arguments);
  344. }
  345. Ast_Node* condition = arguments->value.pair->first;
  346. Ast_Node* then_part = arguments->value.pair->rest;
  347. Ast_Node* else_part = then_part->value.pair->rest;
  348. bool truthy;
  349. try {
  350. truthy = is_truthy(condition, env);
  351. }
  352. Ast_Node* result;
  353. if (truthy)
  354. try{
  355. result = eval_expr(then_part->value.pair->first, env);
  356. }
  357. else if (arguments_length == 3)
  358. try {
  359. result = eval_expr(else_part->value.pair->first, env);
  360. }
  361. else return create_ast_node_nil();
  362. return result;
  363. }
  364. case Built_In_Quote: {
  365. arguments_length = list_length(arguments);
  366. if (arguments_length != 1) {
  367. report_error(Error_Type_Wrong_Number_Of_Arguments);
  368. }
  369. return arguments->value.pair->first;
  370. }
  371. case Built_In_Define: {
  372. try {
  373. arguments_length = list_length(arguments);
  374. }
  375. if (arguments_length != 2) {
  376. report_error(Error_Type_Wrong_Number_Of_Arguments);
  377. }
  378. Ast_Node* symbol = arguments->value.pair->first;
  379. if (symbol->type != Ast_Node_Type_Symbol)
  380. report_error(Error_Type_Type_Missmatch);
  381. Ast_Node* value = arguments->value.pair->rest->value.pair->first;
  382. try {
  383. value = eval_expr(value, env);
  384. }
  385. define_symbol(symbol, value, env);
  386. return value;
  387. }
  388. }
  389. // okay it is not a special form, so in any case we want
  390. // to evaluate the arguments; eval_arguments will also tell
  391. // us the arguments_length.
  392. Ast_Node* evaluated_arguments;
  393. try {
  394. evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
  395. }
  396. switch (operator->value.built_in_function->type) {
  397. case Built_In_Addition: {
  398. return built_in_add(evaluated_arguments);
  399. }
  400. case Built_In_Subtraction: {
  401. return built_in_substract(evaluated_arguments);
  402. }
  403. case Built_In_Multiplication: {
  404. return built_in_multiply(evaluated_arguments);
  405. }
  406. case Built_In_Division: {
  407. return built_in_divide(evaluated_arguments);
  408. }
  409. case Built_In_Equal: {
  410. return built_in_equals(evaluated_arguments);
  411. }
  412. case Built_In_Pair: {
  413. if (arguments_length != 2) {
  414. report_error(Error_Type_Wrong_Number_Of_Arguments);
  415. }
  416. return create_ast_node_pair(evaluated_arguments->value.pair->first, evaluated_arguments->value.pair->rest->value.pair->first);
  417. }
  418. case Built_In_First: {
  419. if (arguments_length != 1) {
  420. report_error(Error_Type_Wrong_Number_Of_Arguments);
  421. }
  422. if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil)
  423. return create_ast_node_nil();
  424. if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_Pair)
  425. report_error(Error_Type_Type_Missmatch);
  426. return evaluated_arguments->value.pair->first->value.pair->first;
  427. }
  428. case Built_In_Rest: {
  429. if (arguments_length != 1) {
  430. report_error(Error_Type_Wrong_Number_Of_Arguments);
  431. }
  432. if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil)
  433. return create_ast_node_nil();
  434. if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_Pair)
  435. report_error(Error_Type_Type_Missmatch);
  436. return evaluated_arguments->value.pair->first->value.pair->rest;
  437. }
  438. case Built_In_Eval: {
  439. if (arguments_length != 1) {
  440. report_error(Error_Type_Wrong_Number_Of_Arguments);
  441. }
  442. Ast_Node* result;
  443. try {
  444. result = eval_expr(evaluated_arguments->value.pair->first, env);
  445. }
  446. return result;
  447. }
  448. case Built_In_Prog: {
  449. if (evaluated_arguments->type == Ast_Node_Type_Nil)
  450. return evaluated_arguments;
  451. // skip to the last evaluated operand and return it,
  452. // we use eval_arguments here instead of doing it
  453. // manually, because we want to increase code reuse,
  454. // but at the cost that we have to find the end of the
  455. // list again
  456. while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type_Pair) {
  457. evaluated_arguments = evaluated_arguments->value.pair->rest;
  458. }
  459. return evaluated_arguments->value.pair->first;
  460. }
  461. case Built_In_List: {
  462. return evaluated_arguments;
  463. }
  464. case Built_In_Print: {
  465. if (arguments_length != 1) {
  466. report_error(Error_Type_Wrong_Number_Of_Arguments);
  467. }
  468. print(evaluated_arguments->value.pair->first);
  469. printf("\n");
  470. return arguments->value.pair->first;
  471. }
  472. case Built_In_Read: {
  473. if (arguments_length > 1) {
  474. report_error(Error_Type_Wrong_Number_Of_Arguments);
  475. }
  476. if (arguments_length == 1) {
  477. Ast_Node* prompt = evaluated_arguments->value.pair->first;
  478. if (prompt->type == Ast_Node_Type_String)
  479. printf("%s", prompt->value.string->value);
  480. else
  481. print(evaluated_arguments->value.pair->first);
  482. }
  483. char* line = read_line();
  484. return create_ast_node_string(line, (int)strlen(line));
  485. }
  486. case Built_In_Type: {
  487. if (arguments_length != 1) {
  488. report_error(Error_Type_Wrong_Number_Of_Arguments);
  489. }
  490. Ast_Node_Type type = evaluated_arguments->value.pair->first->type;
  491. switch (type) {
  492. case Ast_Node_Type_Built_In_Function: return create_ast_node_keyword("built-in-function");
  493. case Ast_Node_Type_Function: return create_ast_node_keyword("dynamic-function");
  494. case Ast_Node_Type_Keyword: return create_ast_node_keyword("keyword");
  495. case Ast_Node_Type_Nil: return create_ast_node_keyword("nil");
  496. case Ast_Node_Type_Number: return create_ast_node_keyword("number");
  497. case Ast_Node_Type_Pair: return create_ast_node_keyword("pair");
  498. case Ast_Node_Type_String: return create_ast_node_keyword("string");
  499. case Ast_Node_Type_Symbol: return create_ast_node_keyword("symbol");
  500. }
  501. }
  502. case Built_In_Exit: {
  503. if (arguments_length > 1) {
  504. report_error(Error_Type_Wrong_Number_Of_Arguments);
  505. }
  506. if (arguments_length == 1) {
  507. Ast_Node* error_code = evaluated_arguments->value.pair->first;
  508. if (error_code->type != Ast_Node_Type_Number)
  509. report_error(Error_Type_Type_Missmatch);
  510. exit((int)error_code->value.number->value);
  511. }
  512. exit(0);
  513. }
  514. default:
  515. report_error(Error_Type_Not_Yet_Implemented);
  516. }
  517. }
  518. // assume it's lambda function and evaluate the arguments
  519. arguments = eval_arguments(arguments, env, &arguments_length);
  520. if (operator->type == Ast_Node_Type_Function) {
  521. Ast_Node* result;
  522. try {
  523. result = apply_arguments_to_function(arguments, operator->value.function, env);
  524. }
  525. return result;
  526. }
  527. }
  528. default:
  529. report_error(Error_Type_Not_A_Function);
  530. }
  531. #undef report_error
  532. }
  533. bool is_truthy (Ast_Node* expression, Environment* env) {
  534. Ast_Node* result;
  535. try {
  536. result = eval_expr(expression, env);
  537. }
  538. if (result->type == Ast_Node_Type_Nil)
  539. return false;
  540. return true;
  541. }