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

949 строки
37 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. // NOTE(Felix): if it is a macro, we will set it later, so we can
  4. // use the default "define_symbol" method here instead of
  5. // switching between "define_symbol" and "define_macro_symbol" all
  6. // the time
  7. Environment* new_env = create_child_environment(parent, Environment_Type_Lambda);
  8. // positional arguments
  9. for (int i = 0; i < function->positional_arguments->next_index; ++i) {
  10. if (arguments->type == Ast_Node_Type_Pair) {
  11. // TODO(Felix): here we create new ast_node_symbols from
  12. // their identifiers but before we converted them to
  13. // strings from symbols... Wo maybe just use the symbols?
  14. define_symbol(
  15. create_ast_node_symbol(function->positional_arguments->identifiers[i]),
  16. arguments->value.pair->first, new_env);
  17. } else {
  18. // not enough arguments given
  19. create_error(Error_Type_Ill_Formed_Arguments, arguments);
  20. return nullptr;
  21. }
  22. arguments = arguments->value.pair->rest;
  23. }
  24. if (arguments->type == Ast_Node_Type_Nil)
  25. goto eval_time;
  26. String_Array_List* read_in_keywords = create_String_array_list(16);
  27. // keyword arguments: use all given ones and keep track of the
  28. // added ones (array list), if end of parameters in encountered or
  29. // something that is not a keyword is encountered or a keyword
  30. // that is not recognized is encoutered, jump out of the loop.
  31. while (arguments->value.pair->first->type == Ast_Node_Type_Keyword) {
  32. // check if this one is even an accepted keyword
  33. bool accepted = false;
  34. for (int i = 0; i < function->keyword_arguments->next_index; ++i) {
  35. if (string_equal(
  36. arguments->value.pair->first->value.keyword->identifier,
  37. function->keyword_arguments->identifiers[i]))
  38. {
  39. accepted = true;
  40. break;
  41. }
  42. }
  43. if (!accepted) {
  44. create_error(Error_Type_Ill_Formed_Arguments, arguments);
  45. return nullptr;
  46. }
  47. // check if it was already read in
  48. for (int i = 0; i < read_in_keywords->next_index; ++i) {
  49. if (string_equal(
  50. arguments->value.pair->first->value.keyword->identifier,
  51. read_in_keywords->data[i]))
  52. {
  53. // TODO(Felix): if we are actually done with all the
  54. // necessary keywords then we have to count the rest
  55. // as :rest here, instead od always creating an error
  56. // (special case with default variables)
  57. create_error(Error_Type_Ill_Formed_Arguments, arguments);
  58. return nullptr;
  59. }
  60. }
  61. // okay so we found a keyword that has to be read in and was
  62. // not already read in, is there a next element to actually
  63. // set it to?
  64. if (arguments->value.pair->rest->type != Ast_Node_Type_Pair) {
  65. create_error(Error_Type_Ill_Formed_Arguments, arguments);
  66. return nullptr;
  67. }
  68. // if not set it and then add it to the array list
  69. define_symbol(
  70. create_ast_node_symbol(arguments->value.pair->first->value.keyword->identifier),
  71. arguments->value.pair->rest->value.pair->first, new_env);
  72. append_to_String_array_list(read_in_keywords, arguments->value.pair->first->value.keyword->identifier);
  73. // overstep both for next one
  74. arguments = arguments->value.pair->rest->value.pair->rest;
  75. if (arguments->type == Ast_Node_Type_Nil) {
  76. break;
  77. }
  78. }
  79. // check if all necessary keywords have been read in
  80. for (int i = 0; i < function->keyword_arguments->next_index; ++i) {
  81. char* defined_keyword = function->keyword_arguments->identifiers[i];
  82. bool was_set = false;
  83. for (int j = 0; j < read_in_keywords->next_index; ++j) {
  84. if (string_equal(
  85. read_in_keywords->data[j],
  86. defined_keyword))
  87. {
  88. was_set = true;
  89. break;
  90. }
  91. }
  92. if (function->keyword_arguments->values->data[i] == nullptr) {
  93. // if this one does not have a default value
  94. if (!was_set) {
  95. create_error(Error_Type_Ill_Formed_Arguments, arguments);
  96. return nullptr;
  97. }
  98. } else {
  99. // this one does have a default value, lets see if we have
  100. // to use it or if the user supplied his own
  101. if (!was_set) {
  102. define_symbol(
  103. create_ast_node_symbol(defined_keyword),
  104. function->keyword_arguments->values->data[i], new_env);
  105. }
  106. }
  107. }
  108. if (arguments->type == Ast_Node_Type_Nil) {
  109. if (function->rest_argument) {
  110. define_symbol(
  111. create_ast_node_symbol(function->rest_argument),
  112. create_ast_node_nil(), new_env);
  113. }
  114. } else {
  115. if (function->rest_argument) {
  116. define_symbol(
  117. create_ast_node_symbol(function->rest_argument),
  118. arguments, new_env);
  119. } else {
  120. // rest was not declared but additional arguments were found
  121. create_error(Error_Type_Ill_Formed_Arguments, arguments);
  122. return nullptr;
  123. }
  124. }
  125. eval_time: {
  126. Ast_Node* result;
  127. // don't have to check every time if it is macro environment or
  128. // not
  129. if (function->is_macro)
  130. new_env->type = Environment_Type_Macro;
  131. try {
  132. result = eval_expr(function->body, new_env);
  133. }
  134. free(new_env);
  135. return result;
  136. }
  137. }
  138. /*
  139. (prog
  140. (define type--before type)
  141. (define type
  142. (lambda (e)
  143. (if (and (= (type--before e) :pair) (= (first e) :my-type))
  144. :my-type
  145. (type--before e))))
  146. )
  147. */
  148. /**
  149. This parses the argument specification of funcitons into their
  150. Function struct. It dois this by allocating new
  151. positional_arguments, keyword_arguments and rest_argument and
  152. filling it in
  153. */
  154. void parse_argument_list(Ast_Node* arguments, Function* function) {
  155. // first init the fields
  156. function->positional_arguments = create_positional_argument_list(16);
  157. function->keyword_arguments = create_keyword_argument_list(16);
  158. function->rest_argument = nullptr;
  159. // okay let's try to read some positional arguments
  160. while (arguments->type == Ast_Node_Type_Pair) {
  161. if (arguments->value.pair->first->type == Ast_Node_Type_Keyword) {
  162. if (string_equal(arguments->value.pair->first->value.keyword->identifier, "keys") ||
  163. string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
  164. break;
  165. else {
  166. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  167. return;
  168. }
  169. }
  170. if (arguments->value.pair->first->type != Ast_Node_Type_Symbol) {
  171. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  172. return;
  173. }
  174. // okay wow we found an actual symbol
  175. append_to_positional_argument_list(
  176. function->positional_arguments,
  177. arguments->value.pair->first->value.symbol->identifier);
  178. arguments = arguments->value.pair->rest;
  179. }
  180. // okay we are done with positional arguments, lets check for
  181. // keywords,
  182. if (arguments->type != Ast_Node_Type_Pair) {
  183. if (arguments->type != Ast_Node_Type_Nil)
  184. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  185. return;
  186. }
  187. if (arguments->value.pair->first->type == Ast_Node_Type_Keyword &&
  188. string_equal(arguments->value.pair->first->value.keyword->identifier, "keys"))
  189. {
  190. arguments = arguments->value.pair->rest;
  191. if (arguments->type != Ast_Node_Type_Pair ||
  192. arguments->value.pair->first->type != Ast_Node_Type_Symbol)
  193. {
  194. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  195. return;
  196. }
  197. while (arguments->type == Ast_Node_Type_Pair) {
  198. if (arguments->value.pair->first->type == Ast_Node_Type_Keyword) {
  199. if (string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
  200. break;
  201. else {
  202. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  203. return;
  204. }
  205. }
  206. if (arguments->value.pair->first->type != Ast_Node_Type_Symbol) {
  207. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  208. return;
  209. }
  210. // we found a symbol (arguments->value.pair->first) for
  211. // the keyword args! Let's check if the next arguement is
  212. // :defaults-to
  213. Ast_Node* next = arguments->value.pair->rest;
  214. if (next->type == Ast_Node_Type_Pair &&
  215. next->value.pair->first->type == Ast_Node_Type_Keyword &&
  216. string_equal(next->value.pair->first->value.keyword->identifier,
  217. "defaults-to"))
  218. {
  219. // check if there is a next argument too, otherwise it
  220. // would be an error
  221. next = next->value.pair->rest;
  222. if (next->type == Ast_Node_Type_Pair) {
  223. append_to_keyword_argument_list(function->keyword_arguments,
  224. arguments->value.pair->first->value.symbol->identifier,
  225. next->value.pair->first);
  226. arguments = next->value.pair->rest;
  227. } else {
  228. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  229. return;
  230. }
  231. } else {
  232. // No :defaults-to, so just add it to the list
  233. append_to_keyword_argument_list(function->keyword_arguments,
  234. arguments->value.pair->first->value.symbol->identifier,
  235. nullptr);
  236. arguments = next;
  237. }
  238. }
  239. }
  240. // Now we are also done with keyword arguments, lets check for
  241. // if there is a rest argument
  242. if (arguments->type != Ast_Node_Type_Pair) {
  243. if (arguments->type != Ast_Node_Type_Nil)
  244. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  245. return;
  246. }
  247. if (arguments->value.pair->first->type == Ast_Node_Type_Keyword &&
  248. string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
  249. {
  250. arguments = arguments->value.pair->rest;
  251. if (arguments->type != Ast_Node_Type_Pair ||
  252. arguments->value.pair->first->type != Ast_Node_Type_Symbol)
  253. {
  254. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  255. return;
  256. }
  257. function->rest_argument = arguments->value.pair->first->value.symbol->identifier;
  258. if (arguments->value.pair->rest->type != Ast_Node_Type_Nil) {
  259. create_error(Error_Type_Ill_Formed_Lambda_List, arguments);
  260. }
  261. } else {
  262. printf("this should not happen?");
  263. create_error(Error_Type_Unknown_Error, arguments);
  264. }
  265. }
  266. int list_length(Ast_Node* node) {
  267. if (node->type == Ast_Node_Type_Nil)
  268. return 0;
  269. if (node->type != Ast_Node_Type_Pair) {
  270. create_error(Error_Type_Type_Missmatch, node);
  271. return 0;
  272. }
  273. int len = 0;
  274. while (node->type == Ast_Node_Type_Pair) {
  275. ++len;
  276. node = node->value.pair->rest;
  277. if (node->type == Ast_Node_Type_Nil)
  278. return len;
  279. }
  280. create_error(Error_Type_Ill_Formed_List, node);
  281. return 0;
  282. }
  283. bool is_truthy (Ast_Node* expression, Environment* env);
  284. Ast_Node* extract_keyword_value(char* keyword, Parsed_Arguments* args) {
  285. // NOTE(Felix): This will be a hashmap lookup later
  286. for (int i = 0; i < args->keyword_keys->next_index; ++i) {
  287. if (string_equal(args->keyword_keys->data[i]->value.keyword->identifier, keyword))
  288. return args->keyword_values->data[i];
  289. }
  290. return nullptr;
  291. }
  292. Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_arguments_length) {
  293. *out_arguments_length = 0;
  294. if (arguments->type == Ast_Node_Type_Nil) {
  295. return arguments;
  296. }
  297. Ast_Node* evaluated_arguments = create_ast_node_pair(nullptr, nullptr);
  298. Ast_Node* evaluated_arguments_head = evaluated_arguments;
  299. Ast_Node* current_head = arguments;
  300. while (current_head->type == Ast_Node_Type_Pair) {
  301. try {
  302. evaluated_arguments_head->value.pair->first =
  303. eval_expr(current_head->value.pair->first, env);
  304. }
  305. current_head = current_head->value.pair->rest;
  306. if (current_head->type == Ast_Node_Type_Pair) {
  307. evaluated_arguments_head->value.pair->rest = create_ast_node_pair(nullptr, nullptr);
  308. evaluated_arguments_head = evaluated_arguments_head->value.pair->rest;
  309. } else if (current_head->type == Ast_Node_Type_Nil) {
  310. evaluated_arguments_head->value.pair->rest = current_head;
  311. } else {
  312. create_error(Error_Type_Ill_Formed_Arguments, arguments);
  313. return nullptr;
  314. }
  315. ++(*out_arguments_length);
  316. }
  317. return evaluated_arguments;
  318. }
  319. Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
  320. #define report_error(_type) { \
  321. create_error(_type, node); \
  322. return nullptr; \
  323. }
  324. if (error)
  325. return nullptr;
  326. Ast_Node* ret = new(Ast_Node);
  327. switch (node->type) {
  328. case Ast_Node_Type_T:
  329. case Ast_Node_Type_Nil:
  330. return node;
  331. case Ast_Node_Type_Symbol: {
  332. Ast_Node* symbol;
  333. try {
  334. symbol = lookup_symbol(node->value.symbol, env);
  335. }
  336. return symbol;
  337. }
  338. case Ast_Node_Type_Number:
  339. case Ast_Node_Type_Keyword:
  340. case Ast_Node_Type_String:
  341. return node;
  342. case Ast_Node_Type_Pair: {
  343. Ast_Node* operator;
  344. if (node->value.pair->first->type != Ast_Node_Type_Built_In_Function &&
  345. node->value.pair->first->type != Ast_Node_Type_Function)
  346. {
  347. try {
  348. operator = eval_expr(node->value.pair->first, env);
  349. }
  350. } else {
  351. operator = node->value.pair->first;
  352. }
  353. Ast_Node* arguments = node->value.pair->rest;
  354. int arguments_length;
  355. // check for special form
  356. if (operator->type == Ast_Node_Type_Built_In_Function) {
  357. switch (operator->value.built_in_function->type) {
  358. case Built_In_Breakpoint: {
  359. print_environment(env);
  360. #ifdef _DEBUG
  361. __debugbreak();
  362. #endif
  363. return create_ast_node_nil();
  364. }
  365. case Built_In_Info: {
  366. try {
  367. arguments_length = list_length(arguments);
  368. }
  369. if (arguments_length != 1) {
  370. report_error(Error_Type_Wrong_Number_Of_Arguments);
  371. }
  372. print(arguments->value.pair->first);
  373. Ast_Node* type = eval_expr(
  374. create_ast_node_pair(
  375. create_ast_node_symbol("type"),
  376. create_ast_node_pair(arguments->value.pair->first, create_ast_node_nil())),
  377. env);
  378. if (type) {
  379. printf(" is of type ");
  380. print(type);
  381. printf("\n");
  382. // just make sure type was not redefined and
  383. // returns something that is not a keyword
  384. if (type->type == Ast_Node_Type_Keyword &&
  385. (string_equal(type->value.keyword->identifier, "dynamic-function") ||
  386. string_equal(type->value.keyword->identifier, "dynamic-macro")))
  387. {
  388. Ast_Node* fun = eval_expr(arguments->value.pair->first, env);
  389. printf("\nMacro? %s\n", (fun->value.function->is_macro) ? "yes" : "no");
  390. if (fun->value.function->docstring)
  391. printf("Docstring:\n==========\n%s\n\n", fun->value.function->docstring);
  392. else
  393. printf("No docstring avaliable\n");
  394. printf("Arguments:\n==========\n");
  395. printf("Postitional: {");
  396. if (fun->value.function->positional_arguments->next_index != 0) {
  397. printf("%s", fun->value.function->positional_arguments->identifiers[0]);
  398. for (int i = 1; i < fun->value.function->positional_arguments->next_index; ++i) {
  399. printf(", %s", fun->value.function->positional_arguments->identifiers[i]);
  400. }
  401. }
  402. printf("}\n");
  403. printf("Keyword: {");
  404. if (fun->value.function->keyword_arguments->next_index != 0) {
  405. printf("%s", fun->value.function->keyword_arguments->identifiers[0]);
  406. for (int i = 1; i < fun->value.function->keyword_arguments->next_index; ++i) {
  407. printf(", %s", fun->value.function->keyword_arguments->identifiers[i]);
  408. }
  409. }
  410. printf("}\n");
  411. printf("Rest: {");
  412. if (fun->value.function->rest_argument)
  413. printf("%s", fun->value.function->rest_argument);
  414. printf("}\n");
  415. }
  416. } else {
  417. printf(" is not defined\n");
  418. delete_error();
  419. }
  420. return create_ast_node_nil();
  421. }
  422. case Built_In_Macro:
  423. case Built_In_Lambda: {
  424. /*
  425. * (lambda ())
  426. * (lambda (x d) (+ 1 2) (- 1 2) (* 1 2))
  427. */
  428. try {
  429. arguments_length = list_length(arguments);
  430. }
  431. if (arguments_length == 0)
  432. report_error(Error_Type_Wrong_Number_Of_Arguments);
  433. Function* function = new(Function);
  434. if (operator->value.built_in_function->type == Built_In_Macro) {
  435. function->is_macro = true;
  436. } else {
  437. function->is_macro = false;
  438. }
  439. // if parameters were specified
  440. if (arguments->value.pair->first->type != Ast_Node_Type_Nil) {
  441. try {
  442. assert_type(arguments->value.pair->first, Ast_Node_Type_Pair);
  443. }
  444. try {
  445. parse_argument_list(arguments->value.pair->first, function);
  446. }
  447. } else {
  448. function->positional_arguments = create_positional_argument_list(1);
  449. function->keyword_arguments = create_keyword_argument_list(1);
  450. function->rest_argument = nullptr;
  451. }
  452. arguments = arguments->value.pair->rest;
  453. // if there is a docstring, use it
  454. if (arguments->value.pair->first->type == Ast_Node_Type_String) {
  455. function->docstring = arguments->value.pair->first->value.string->value;
  456. arguments = arguments->value.pair->rest;
  457. } else {
  458. function->docstring = nullptr;
  459. }
  460. // we are now in the function body, just wrap it in an
  461. // implicit prog
  462. function->body = create_ast_node_pair(
  463. create_ast_node_built_in_function("prog"),
  464. arguments);
  465. Ast_Node* ret = new(Ast_Node);
  466. ret->type = Ast_Node_Type_Function;
  467. ret->value.function = function;
  468. return ret;
  469. }
  470. case Built_In_Let: {
  471. // (let ((a 10)(b 20)) (body1) (body2))
  472. try {
  473. arguments_length = list_length(arguments);
  474. }
  475. if (arguments_length < 1)
  476. report_error(Error_Type_Wrong_Number_Of_Arguments);
  477. Environment* let_env = create_child_environment(env, Environment_Type_Let);
  478. Ast_Node* bindings = arguments->value.pair->first;
  479. while (true) {
  480. if (bindings->type == Ast_Node_Type_Nil) {
  481. break;
  482. } else if (bindings->type != Ast_Node_Type_Pair) {
  483. report_error(Error_Type_Ill_Formed_Arguments);
  484. }
  485. Ast_Node* sym = bindings->value.pair->first->value.pair->first;
  486. if(sym->type != Ast_Node_Type_Symbol) {
  487. report_error(Error_Type_Ill_Formed_Arguments);
  488. }
  489. Ast_Node* rest_sym = bindings->value.pair->first->value.pair->rest;
  490. if (rest_sym->type != Ast_Node_Type_Pair) {
  491. report_error(Error_Type_Ill_Formed_Arguments);
  492. }
  493. if (rest_sym->value.pair->rest->type != Ast_Node_Type_Nil) {
  494. report_error(Error_Type_Ill_Formed_Arguments);
  495. }
  496. Ast_Node* value = rest_sym->value.pair->first;
  497. define_symbol(sym, value, let_env);
  498. bindings = bindings->value.pair->rest;
  499. }
  500. arguments = arguments->value.pair->rest;
  501. Ast_Node* evaluated_arguments;
  502. try {
  503. evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length);
  504. }
  505. if (evaluated_arguments->type == Ast_Node_Type_Nil)
  506. return evaluated_arguments;
  507. // skip to the last evaluated operand and return it,
  508. // we use eval_arguments here instead of doing it
  509. // manually, because we want to increase code reuse,
  510. // but at the cost that we have to find the end of the
  511. // list again
  512. while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type_Pair) {
  513. evaluated_arguments = evaluated_arguments->value.pair->rest;
  514. }
  515. return evaluated_arguments->value.pair->first;
  516. }
  517. case Built_In_And: {
  518. bool result = true;
  519. while (arguments->type != Ast_Node_Type_Nil) {
  520. if (arguments->type != Ast_Node_Type_Pair) {
  521. report_error(Error_Type_Ill_Formed_List);
  522. }
  523. try {
  524. result &= is_truthy(arguments->value.pair->first, env);
  525. }
  526. arguments = arguments->value.pair->rest;
  527. if (!result) return create_ast_node_nil();
  528. }
  529. return create_ast_node_t();
  530. }
  531. case Built_In_Or: {
  532. bool result = false;
  533. while (arguments->type != Ast_Node_Type_Nil) {
  534. if (arguments->type != Ast_Node_Type_Pair) {
  535. report_error(Error_Type_Ill_Formed_List);
  536. }
  537. try {
  538. result |= is_truthy(arguments->value.pair->first, env);
  539. }
  540. arguments = arguments->value.pair->rest;
  541. if (result) return create_ast_node_t();
  542. }
  543. return create_ast_node_nil();
  544. }
  545. case Built_In_Not: {
  546. try {
  547. arguments_length = list_length(arguments);
  548. }
  549. if (arguments_length != 1) {
  550. report_error(Error_Type_Wrong_Number_Of_Arguments);
  551. }
  552. bool truthy;
  553. try {
  554. truthy = is_truthy(arguments->value.pair->first, env);
  555. }
  556. if (truthy)
  557. return create_ast_node_nil();
  558. return create_ast_node_t();
  559. }
  560. case Built_In_While: {
  561. try {
  562. arguments_length = list_length(arguments);
  563. }
  564. if (arguments_length < 2) {
  565. report_error(Error_Type_Wrong_Number_Of_Arguments);
  566. }
  567. Ast_Node* condition = arguments->value.pair->first;
  568. Ast_Node* then_part = arguments->value.pair->rest;
  569. Ast_Node* result = create_ast_node_nil();
  570. while (eval_expr(condition, env)->type != Ast_Node_Type_Nil) {
  571. result = eval_expr(then_part->value.pair->first, env);
  572. }
  573. return result;
  574. }
  575. case Built_In_If: {
  576. try {
  577. arguments_length = list_length(arguments);
  578. }
  579. if (arguments_length != 2 && arguments_length != 3) {
  580. report_error(Error_Type_Wrong_Number_Of_Arguments);
  581. }
  582. Ast_Node* condition = arguments->value.pair->first;
  583. Ast_Node* then_part = arguments->value.pair->rest;
  584. Ast_Node* else_part = then_part->value.pair->rest;
  585. bool truthy;
  586. try {
  587. truthy = is_truthy(condition, env);
  588. }
  589. Ast_Node* result;
  590. if (truthy)
  591. try{
  592. result = eval_expr(then_part->value.pair->first, env);
  593. }
  594. else if (arguments_length == 3)
  595. try {
  596. result = eval_expr(else_part->value.pair->first, env);
  597. }
  598. else return create_ast_node_nil();
  599. return result;
  600. }
  601. case Built_In_Quote: {
  602. arguments_length = list_length(arguments);
  603. if (arguments_length != 1) {
  604. report_error(Error_Type_Wrong_Number_Of_Arguments);
  605. }
  606. return arguments->value.pair->first;
  607. }
  608. case Built_In_Macro_Define:
  609. case Built_In_Define: {
  610. try {
  611. arguments_length = list_length(arguments);
  612. }
  613. if (arguments_length != 2) {
  614. report_error(Error_Type_Wrong_Number_Of_Arguments);
  615. }
  616. Ast_Node* symbol = arguments->value.pair->first;
  617. if (symbol->type == Ast_Node_Type_Pair) {
  618. try {
  619. symbol = eval_expr(symbol, env);
  620. }
  621. }
  622. if (symbol->type != Ast_Node_Type_Symbol) {
  623. report_error(Error_Type_Type_Missmatch);
  624. }
  625. Ast_Node* value = arguments->value.pair->rest->value.pair->first;
  626. /* print(value); */
  627. try {
  628. value = eval_expr(value, env);
  629. }
  630. /* print(value); */
  631. if (operator->value.built_in_function->type == Built_In_Macro_Define) {
  632. /* printf("Defining %s in the macro env to be ", symbol->value.symbol->identifier); */
  633. /* print(value); */
  634. define_macro_symbol(symbol, value, env);
  635. }
  636. else
  637. define_symbol(symbol, value, env);
  638. return value;
  639. }
  640. }
  641. // okay it is not a special form, so in any case we want
  642. // to evaluate the arguments; eval_arguments will also tell
  643. // us the arguments_length.
  644. Ast_Node* evaluated_arguments;
  645. try {
  646. evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
  647. }
  648. switch (operator->value.built_in_function->type) {
  649. case Built_In_Addition: {
  650. return built_in_add(evaluated_arguments);
  651. }
  652. case Built_In_Subtraction: {
  653. return built_in_substract(evaluated_arguments);
  654. }
  655. case Built_In_Multiplication: {
  656. return built_in_multiply(evaluated_arguments);
  657. }
  658. case Built_In_Division: {
  659. return built_in_divide(evaluated_arguments);
  660. }
  661. case Built_In_Equal: {
  662. return built_in_equals(evaluated_arguments);
  663. }
  664. case Built_In_Greater: {
  665. return built_in_greater(evaluated_arguments);
  666. }
  667. case Built_In_Greater_Equal: {
  668. return built_in_greater_equal(evaluated_arguments);
  669. }
  670. case Built_In_Less: {
  671. return built_in_less(evaluated_arguments);
  672. }
  673. case Built_In_Less_Equal: {
  674. return built_in_less_equal(evaluated_arguments);
  675. }
  676. case Built_In_Mutate: {
  677. if (arguments_length != 2)
  678. report_error(Error_Type_Wrong_Number_Of_Arguments);
  679. if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil ||
  680. evaluated_arguments->value.pair->first->type == Ast_Node_Type_Keyword)
  681. {
  682. report_error(Error_Type_Type_Missmatch);
  683. }
  684. Ast_Node* target = evaluated_arguments->value.pair->first;
  685. Ast_Node* source = evaluated_arguments->value.pair->rest->value.pair->first;
  686. *target = *source;
  687. return target;
  688. }
  689. case Built_In_Load: {
  690. if (arguments_length != 1)
  691. report_error(Error_Type_Wrong_Number_Of_Arguments);
  692. if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_String)
  693. report_error(Error_Type_Type_Missmatch);
  694. Ast_Node* result;
  695. try {
  696. result = built_in_load(
  697. evaluated_arguments->value.pair->first->value.string->value, env);
  698. }
  699. return result;
  700. }
  701. case Built_In_Pair: {
  702. if (arguments_length != 2) {
  703. report_error(Error_Type_Wrong_Number_Of_Arguments);
  704. }
  705. return create_ast_node_pair(evaluated_arguments->value.pair->first, evaluated_arguments->value.pair->rest->value.pair->first);
  706. }
  707. case Built_In_First: {
  708. if (arguments_length != 1) {
  709. report_error(Error_Type_Wrong_Number_Of_Arguments);
  710. }
  711. if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil)
  712. return create_ast_node_nil();
  713. if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_Pair)
  714. report_error(Error_Type_Type_Missmatch);
  715. return evaluated_arguments->value.pair->first->value.pair->first;
  716. }
  717. case Built_In_Rest: {
  718. if (arguments_length != 1) {
  719. report_error(Error_Type_Wrong_Number_Of_Arguments);
  720. }
  721. if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil)
  722. return create_ast_node_nil();
  723. if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_Pair)
  724. report_error(Error_Type_Type_Missmatch);
  725. return evaluated_arguments->value.pair->first->value.pair->rest;
  726. }
  727. case Built_In_Eval: {
  728. if (arguments_length != 1) {
  729. report_error(Error_Type_Wrong_Number_Of_Arguments);
  730. }
  731. Ast_Node* result;
  732. try {
  733. result = eval_expr(evaluated_arguments->value.pair->first, env);
  734. }
  735. return result;
  736. }
  737. case Built_In_Prog: {
  738. if (evaluated_arguments->type == Ast_Node_Type_Nil)
  739. return evaluated_arguments;
  740. // skip to the last evaluated operand and return it,
  741. // we use eval_arguments here instead of doing it
  742. // manually, because we want to increase code reuse,
  743. // but at the cost that we have to find the end of the
  744. // list again
  745. while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type_Pair) {
  746. evaluated_arguments = evaluated_arguments->value.pair->rest;
  747. }
  748. return evaluated_arguments->value.pair->first;
  749. }
  750. case Built_In_List: {
  751. return evaluated_arguments;
  752. }
  753. case Built_In_Print: {
  754. if (arguments_length != 1) {
  755. report_error(Error_Type_Wrong_Number_Of_Arguments);
  756. }
  757. print(evaluated_arguments->value.pair->first);
  758. /* printf("\n"); */
  759. return arguments->value.pair->first;
  760. }
  761. case Built_In_Read: {
  762. if (arguments_length > 1) {
  763. report_error(Error_Type_Wrong_Number_Of_Arguments);
  764. }
  765. if (arguments_length == 1) {
  766. Ast_Node* prompt = evaluated_arguments->value.pair->first;
  767. if (prompt->type == Ast_Node_Type_String)
  768. printf("%s", prompt->value.string->value);
  769. else
  770. print(evaluated_arguments->value.pair->first);
  771. }
  772. char* line = read_line();
  773. return create_ast_node_string(line, (int)strlen(line));
  774. }
  775. case Built_In_Type: {
  776. if (arguments_length != 1) {
  777. report_error(Error_Type_Wrong_Number_Of_Arguments);
  778. }
  779. Ast_Node_Type type = evaluated_arguments->value.pair->first->type;
  780. switch (type) {
  781. case Ast_Node_Type_Built_In_Function: return create_ast_node_keyword("built-in-function");
  782. case Ast_Node_Type_Function: {
  783. if (evaluated_arguments->value.pair->first->value.function->is_macro)
  784. return create_ast_node_keyword("dynamic-macro");
  785. return create_ast_node_keyword("dynamic-function");
  786. }
  787. case Ast_Node_Type_Keyword: return create_ast_node_keyword("keyword");
  788. case Ast_Node_Type_Nil: return create_ast_node_keyword("nil");
  789. case Ast_Node_Type_T: return create_ast_node_keyword("t");
  790. case Ast_Node_Type_Number: return create_ast_node_keyword("number");
  791. case Ast_Node_Type_Pair: return create_ast_node_keyword("pair");
  792. case Ast_Node_Type_String: return create_ast_node_keyword("string");
  793. case Ast_Node_Type_Symbol: return create_ast_node_keyword("symbol");
  794. }
  795. }
  796. case Built_In_Exit: {
  797. if (arguments_length > 1) {
  798. report_error(Error_Type_Wrong_Number_Of_Arguments);
  799. }
  800. if (arguments_length == 1) {
  801. Ast_Node* error_code = evaluated_arguments->value.pair->first;
  802. if (error_code->type != Ast_Node_Type_Number)
  803. report_error(Error_Type_Type_Missmatch);
  804. exit((int)error_code->value.number->value);
  805. }
  806. exit(0);
  807. }
  808. default:
  809. report_error(Error_Type_Not_Yet_Implemented);
  810. }
  811. }
  812. if (operator->type == Ast_Node_Type_Function) {
  813. if (!operator->value.function->is_macro) {
  814. try {
  815. arguments = eval_arguments(arguments, env, &arguments_length);
  816. }
  817. }
  818. Ast_Node* result;
  819. try {
  820. result = apply_arguments_to_function(arguments, operator->value.function, env);
  821. }
  822. return result;
  823. }
  824. }
  825. default: {
  826. #ifdef _DEBUG
  827. __debugbreak();
  828. #endif
  829. report_error(Error_Type_Not_A_Function);
  830. }
  831. }
  832. #undef report_error
  833. }
  834. bool is_truthy (Ast_Node* expression, Environment* env) {
  835. Ast_Node* result;
  836. try {
  837. result = eval_expr(expression, env);
  838. }
  839. if (result->type == Ast_Node_Type_Nil)
  840. return false;
  841. return true;
  842. }