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

619 строки
24 KiB

  1. namespace Slime {
  2. proc create_extended_environment_for_function_application_nrc(
  3. // TODO(Felix): pass cs as value as soon as we got rid of
  4. // destructors, to prevent destroying it on scope exit
  5. Array_List<Lisp_Object*>* cs,
  6. Lisp_Object* function,
  7. int arg_start,
  8. int arg_count) -> Environment*
  9. {
  10. profile_this();
  11. bool is_c_function = function->value.function->is_c;
  12. Environment* new_env = Memory::create_child_environment(function->value.function->parent_environment);
  13. Arguments* arg_spec = &function->value.function->args;
  14. // NOTE(Felix): Step 1.
  15. // - setting the parent environment
  16. // - setting the arg_spec
  17. // - potentially evaluating the arguments
  18. // NOTE(Felix): Even though we will return the environment at the
  19. // end, for defining symbols here for the parameters, it has to be
  20. // on the envi stack.
  21. push_environment(new_env);
  22. defer {
  23. pop_environment();
  24. };
  25. // NOTE(Felix): Step 2.
  26. // Reading the argument spec and fill in the environment
  27. // for the function call
  28. Lisp_Object* sym, *val; // used as temp storage to use `try`
  29. Array_List<Lisp_Object*> read_in_keywords;
  30. read_in_keywords.alloc();
  31. defer {
  32. read_in_keywords.dealloc();
  33. };
  34. int obligatory_keywords_count = 0;
  35. int read_obligatory_keywords_count = 0;
  36. Lisp_Object* next_arg = cs->data[arg_start];
  37. proc read_positional_args = [&] {
  38. for (int i = 0; i < arg_spec->positional.symbols.next_index; ++i) {
  39. if (arg_count == 0) {
  40. create_parsing_error("Wrong number of arguments.");
  41. return;
  42. }
  43. // NOTE(Felix): We have to copy all the arguments,
  44. // otherwise we change the program code.
  45. // XXX(Felix): T C functions we pass by reference.
  46. // TODO(Felix): Why did we decide this??
  47. sym = arg_spec->positional.symbols.data[i];
  48. if (is_c_function) {
  49. define_symbol(sym, next_arg);
  50. } else {
  51. define_symbol(
  52. sym,
  53. Memory::copy_lisp_object_except_pairs(next_arg));
  54. }
  55. next_arg = cs->data[++arg_start];
  56. --arg_count;
  57. }
  58. };
  59. proc read_keyword_args = [&] {
  60. // debug_break();
  61. // keyword arguments: use all given ones and keep track of the
  62. // added ones (array list), if end of parameters in encountered or
  63. // something that is not a keyword is encountered or a keyword
  64. // that is not recognized is encoutered, jump out of the loop.
  65. if (arg_count == 0) {
  66. return;
  67. }
  68. // find out how many keyword args we /have/ to read
  69. for (int i = 0; i < arg_spec->keyword.values.next_index; ++i) {
  70. if (arg_spec->keyword.values.data[i] == nullptr)
  71. ++obligatory_keywords_count;
  72. else
  73. break;
  74. }
  75. while (Memory::get_type(next_arg) == Lisp_Object_Type::Keyword) {
  76. // check if this one is even an accepted keyword
  77. bool accepted = false;
  78. for (int i = 0; i < arg_spec->keyword.keywords.next_index; ++i) {
  79. if (next_arg == arg_spec->keyword.keywords.data[i])
  80. {
  81. accepted = true;
  82. break;
  83. }
  84. }
  85. if (!accepted) {
  86. // NOTE(Felix): if we are actually done with all the
  87. // necessary keywords then we have to count the rest
  88. // as :rest here, instead od always creating an error
  89. // (special case with default variables)
  90. if (read_obligatory_keywords_count == obligatory_keywords_count)
  91. return;
  92. create_generic_error(
  93. "The function does not take the keyword argument ':%s'\n"
  94. "and not all required keyword arguments have been read\n"
  95. "in to potentially count it as the rest argument.",
  96. &(next_arg->value.symbol->data));
  97. return;
  98. }
  99. // check if it was already read in
  100. for (int i = 0; i < read_in_keywords.next_index; ++i) {
  101. if (next_arg == read_in_keywords.data[i])
  102. {
  103. // NOTE(Felix): if we are actually done with all the
  104. // necessary keywords then we have to count the rest
  105. // as :rest here, instead od always creating an error
  106. // (special case with default variables)
  107. if (read_obligatory_keywords_count == obligatory_keywords_count)
  108. return;
  109. create_generic_error(
  110. "The function already read the keyword argument ':%s'",
  111. &(next_arg->value.symbol->data));
  112. return;
  113. }
  114. }
  115. // okay so we found a keyword that has to be read in and was
  116. // not already read in, is there a next element to actually
  117. // set it to?
  118. if (arg_count == 0) {
  119. create_generic_error(
  120. "Attempting to set the keyword argument ':%s', but no value was supplied.",
  121. &(next_arg->value.symbol->data));
  122. return;
  123. }
  124. // if not set it and then add it to the array list
  125. Lisp_Object* key = next_arg;
  126. try_void sym = Memory::get_symbol(key->value.symbol);
  127. next_arg = cs->data[++arg_start];
  128. --arg_count;
  129. // NOTE(Felix): It seems we do not need to evaluate the argument here...
  130. if (is_c_function) {
  131. try_void define_symbol(sym, next_arg);
  132. } else {
  133. try_void define_symbol(sym,
  134. Memory::copy_lisp_object_except_pairs(next_arg));
  135. }
  136. read_in_keywords.append(key);
  137. ++read_obligatory_keywords_count;
  138. // overstep both for next one
  139. next_arg = cs->data[++arg_start];
  140. --arg_count;
  141. if (arg_count == 0) {
  142. break;
  143. }
  144. }
  145. };
  146. proc check_keyword_args = [&]() -> void {
  147. // check if all necessary keywords have been read in
  148. for (int i = 0; i < arg_spec->keyword.values.next_index; ++i) {
  149. auto defined_keyword = arg_spec->keyword.keywords.data[i];
  150. bool was_set = false;
  151. for (int j = 0; j < read_in_keywords.next_index; ++j) {
  152. if (read_in_keywords.data[j] == defined_keyword) {
  153. was_set = true;
  154. break;
  155. }
  156. }
  157. if (arg_spec->keyword.values.data[i] == nullptr) {
  158. // if this one does not have a default value
  159. if (!was_set) {
  160. create_generic_error(
  161. "There was no value supplied for the required "
  162. "keyword argument ':%s'.",
  163. &defined_keyword->value.symbol->data);
  164. return;
  165. }
  166. } else {
  167. // this one does have a default value, lets see if we have
  168. // to use it or if the user supplied his own
  169. if (!was_set) {
  170. try_void sym = Memory::get_symbol(defined_keyword->value.symbol);
  171. if (is_c_function) {
  172. try_void val = arg_spec->keyword.values.data[i];
  173. } else {
  174. try_void val = Memory::copy_lisp_object_except_pairs(arg_spec->keyword.values.data[i]);
  175. }
  176. define_symbol(sym, val);
  177. }
  178. }
  179. }
  180. };
  181. proc read_rest_arg = [&]() -> void {
  182. if (arg_count == 0) {
  183. if (arg_spec->rest) {
  184. define_symbol(arg_spec->rest, Memory::nil);
  185. }
  186. } else {
  187. if (arg_spec->rest) {
  188. Lisp_Object* list;
  189. try_void list = Memory::create_list(next_arg);
  190. Lisp_Object* head = list;
  191. next_arg = cs->data[++arg_start];
  192. --arg_count;
  193. while (arg_count > 0) {
  194. try_void head->value.pair.rest = Memory::create_list(next_arg);
  195. head = head->value.pair.rest;
  196. next_arg = cs->data[++arg_start];
  197. --arg_count;
  198. }
  199. define_symbol(arg_spec->rest, list);
  200. } else {
  201. // rest was not declared but additional arguments were found
  202. create_generic_error(
  203. "A rest argument was not declared "
  204. "but the function was called with additional arguments.");
  205. return;
  206. }
  207. }
  208. };
  209. try read_positional_args();
  210. try read_keyword_args();
  211. try check_keyword_args();
  212. try read_rest_arg();
  213. return new_env;
  214. }
  215. proc apply_arguments_to_function(Lisp_Object* arguments, Lisp_Object* function, bool should_evaluate_args) -> Lisp_Object* {
  216. // profile_this();
  217. // Environment* new_env;
  218. // Lisp_Object* result;
  219. // try new_env = create_extended_environment_for_function_application(arguments, function, should_evaluate_args);
  220. // push_environment(new_env);
  221. // defer {
  222. // pop_environment();
  223. // };
  224. // if (Memory::get_type(function) == Lisp_Object_Type::CFunction)
  225. // // if c function:
  226. // try result = function->value.cFunction->body();
  227. // else
  228. // // if lisp function
  229. // try result = eval_expr(function->value.function->body);
  230. // return result;
  231. return nullptr;
  232. }
  233. proc create_arguments_from_lambda_list_and_inject(Lisp_Object* arguments, Lisp_Object* function) -> void {
  234. /* NOTE This parses the argument specification of funcitons
  235. * into their Function struct. It does this by allocating new
  236. * positional_arguments, keyword_arguments and rest_argument
  237. * and filling it in
  238. */
  239. Arguments* result = &function->value.function->args;;
  240. // first init the fields
  241. result->rest = nullptr;
  242. // okay let's try to read some positional arguments
  243. while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
  244. // if we encounter a keyword or a list (for keywords with
  245. // defualt args), the positionals are done
  246. if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword ||
  247. Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Pair) {
  248. break;
  249. }
  250. // if we encounter something that is neither a symbol nor a
  251. // keyword arg, it's an error
  252. if (Memory::get_type(arguments->value.pair.first) != Lisp_Object_Type::Symbol) {
  253. create_parsing_error("Only symbols and keywords "
  254. "(with or without default args) "
  255. "can be parsed here, but found '%s'",
  256. Lisp_Object_Type_to_string(Memory::get_type(arguments->value.pair.first)));
  257. return;
  258. }
  259. // okay we found an actual symbol
  260. result->positional.symbols.append(arguments->value.pair.first);
  261. arguments = arguments->value.pair.rest;
  262. }
  263. // if we reach here, we are on a keyword or a pair wher a keyword
  264. // should be in first
  265. while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
  266. if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) {
  267. // if we are on a actual keyword (with no default arg)
  268. auto keyword = arguments->value.pair.first;
  269. result->keyword.keywords.append(keyword);
  270. result->keyword.values.append(nullptr);
  271. } else if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Pair) {
  272. // if we are on a keyword with a default value
  273. auto keyword = arguments->value.pair.first->value.pair.first;
  274. if (Memory::get_type(keyword) != Lisp_Object_Type::Keyword) {
  275. create_parsing_error("Default args must be keywords");
  276. }
  277. if (Memory::get_type(arguments->value.pair.first->value.pair.rest)
  278. != Lisp_Object_Type::Pair)
  279. {
  280. create_parsing_error("Default args must be a list of 2.");
  281. }
  282. auto value = arguments->value.pair.first->value.pair.rest->value.pair.first;
  283. try_void value = eval_expr(value);
  284. if (arguments->value.pair.first->value.pair.rest->value.pair.rest != Memory::nil) {
  285. create_parsing_error("Default args must be a list of 2.");
  286. }
  287. result->keyword.keywords.append(keyword);
  288. result->keyword.values.append(value);
  289. }
  290. arguments = arguments->value.pair.rest;
  291. }
  292. // Now we are also done with keyword arguments, lets check for
  293. // if there is a rest argument
  294. if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
  295. if (arguments == Memory::nil)
  296. return;
  297. if (Memory::get_type(arguments) == Lisp_Object_Type::Symbol)
  298. result->rest = arguments;
  299. else
  300. create_parsing_error("The rest argument must be a symbol.");
  301. }
  302. }
  303. proc list_length(Lisp_Object* node) -> int {
  304. if (node == Memory::nil)
  305. return 0;
  306. assert_type(node, Lisp_Object_Type::Pair);
  307. int len = 0;
  308. while (Memory::get_type(node) == Lisp_Object_Type::Pair) {
  309. ++len;
  310. node = node->value.pair.rest;
  311. if (node == Memory::nil)
  312. return len;
  313. }
  314. create_parsing_error("Can't calculate length of ill formed list.");
  315. return 0;
  316. }
  317. proc copy_scl(Source_Code_Location*) -> Source_Code_Location* {
  318. // TODO(Felix):
  319. return nullptr;
  320. }
  321. proc pause() {
  322. printf("\n-----------------------\n"
  323. "Press ENTER to continue\n");
  324. getchar();
  325. }
  326. inline proc maybe_wrap_body_in_begin(Lisp_Object* body) -> Lisp_Object* {
  327. Lisp_Object* begin_symbol = Memory::get_symbol("begin");
  328. if (body->value.pair.rest == Memory::nil)
  329. return body->value.pair.first;
  330. else
  331. return Memory::create_lisp_object_pair(begin_symbol, body);
  332. }
  333. proc nrc_eval(Lisp_Object* expr) -> Lisp_Object* {
  334. using namespace Globals::Current_Execution;
  335. nass.reserve(1);
  336. Array_List<NasAction>* nas = nass.data+(nass.next_index++);
  337. nas->alloc();
  338. defer {
  339. --nass.next_index;
  340. nas->dealloc();
  341. };
  342. proc debug_step = [&] {
  343. return;
  344. // printf("%d\n", cs.next_index);
  345. printf("cs:\n ");
  346. for (auto lo : cs) {
  347. print(lo, true);
  348. printf("\n ");
  349. }
  350. printf("\npcs:\n ");
  351. for (auto lo : pcs) {
  352. print(lo, true);
  353. printf("\n ");
  354. }
  355. printf("\nnnas:\n ");
  356. for (auto nas: nass) {
  357. printf("nas:\n ");
  358. for (auto na : nas) {
  359. printf(" - %s\n ", [&]
  360. {
  361. switch(na) {
  362. case NasAction::Pop_Environment: return "Pop_Environment";
  363. case NasAction::Define_Var: return "Define_Var";
  364. case NasAction::Eval: return "Eval";
  365. case NasAction::Step: return "Step";
  366. case NasAction::TM: return "TM";
  367. case NasAction::Pop: return "Pop";
  368. case NasAction::If: return "If";
  369. }
  370. return "??";
  371. }());
  372. }
  373. }
  374. printf("\nams:\n ");
  375. for (auto am : ams) {
  376. printf("%d\n ", am);
  377. }
  378. // pause();
  379. };
  380. proc push_pc_on_cs = [&] {
  381. for_lisp_list (pcs.data[pcs.next_index-1]) {
  382. cs.append(it);
  383. }
  384. pcs.data[pcs.next_index-1] = Memory::nil;
  385. };
  386. cs.append(expr);
  387. nas->append(NasAction::Eval);
  388. NasAction current_action;
  389. Lisp_Object* pc;
  390. while (nas->next_index > 0) {
  391. debug_step();
  392. current_action = nas->data[--nas->next_index];
  393. switch (current_action) {
  394. case NasAction::Pop: {
  395. --cs.next_index;
  396. } break;
  397. case NasAction::Pop_Environment: {
  398. pop_environment();
  399. } break;
  400. case NasAction::Eval: {
  401. pc = cs.data[cs.next_index-1];
  402. Lisp_Object_Type type = Memory::get_type(pc);
  403. switch (type) {
  404. case Lisp_Object_Type::Symbol: {
  405. cs.data[cs.next_index-1] = lookup_symbol(pc, get_current_environment());
  406. } break;
  407. case Lisp_Object_Type::Pair: {
  408. cs.data[cs.next_index-1] = pc->value.pair.first;
  409. ams.append(cs.next_index-1);
  410. pcs.append(pc->value.pair.rest);
  411. nas->append(NasAction::TM);
  412. nas->append(NasAction::Eval);
  413. } break;
  414. default: {
  415. // NOTE(Felix): others are self evaluating
  416. // so do nothing
  417. }
  418. }
  419. } break;
  420. case NasAction::TM: {
  421. pc = cs.data[cs.next_index-1];
  422. Lisp_Object_Type type = Memory::get_type(pc);
  423. switch (type) {
  424. case Lisp_Object_Type::Function: {
  425. if(pc->value.function->is_c) {
  426. if (pc->value.function->type.c_function_type == C_Function_Type::cMacro) {
  427. try pc->value.function->body.c_macro_body();
  428. } else if(pc->value.function->type.c_function_type == C_Function_Type::cSpecial)
  429. {
  430. // TODO(Felix): Why not call the function
  431. // right away, and instead push step, so
  432. // that step calls it?
  433. push_pc_on_cs();
  434. nas->append(NasAction::Step);
  435. } else {
  436. nas->append(NasAction::Step);
  437. }
  438. } else {
  439. if (pc->value.function->type.lisp_function_type ==
  440. Lisp_Function_Type::Macro)
  441. {
  442. push_pc_on_cs();
  443. nas->append(NasAction::Eval);
  444. nas->append(NasAction::Step);
  445. } else {
  446. nas->append(NasAction::Step);
  447. }
  448. }
  449. } break;
  450. default: {
  451. create_generic_error("The first element of the pair was not a function but: %s",
  452. Lisp_Object_Type_to_string(type));
  453. return nullptr;
  454. }
  455. }
  456. } break;
  457. case NasAction::Step: {
  458. if (pcs.data[pcs.next_index-1] == Memory::nil) {
  459. --pcs.next_index;
  460. int am = ams.data[--ams.next_index];
  461. Lisp_Object* function = cs.data[am];
  462. assert_type(function, Lisp_Object_Type::Function);
  463. Environment* extended_env =
  464. create_extended_environment_for_function_application_nrc(
  465. &cs, function, am+1, cs.next_index-am-1);
  466. cs.next_index = am;
  467. push_environment(extended_env);
  468. if (function->value.function->is_c) {
  469. if (function->value.function->type.c_function_type == C_Function_Type::cMacro)
  470. try function->value.function->body.c_macro_body();
  471. else
  472. try cs.append(function->value.function->body.c_body());
  473. pop_environment();
  474. } else {
  475. nas->append(NasAction::Pop_Environment);
  476. nas->append(NasAction::Eval);
  477. cs.append(function->value.function->body.lisp_body);
  478. }
  479. } else {
  480. cs.append(pcs.data[pcs.next_index-1]->value.pair.first);
  481. pcs.data[pcs.next_index-1] = pcs.data[pcs.next_index-1]->value.pair.rest;
  482. nas->append(NasAction::Step);
  483. nas->append(NasAction::Eval);
  484. }
  485. } break;
  486. case NasAction::If: {
  487. /* | <cond> |
  488. | <then> |
  489. | <else> |
  490. | .... | */
  491. cs.next_index -= 2;
  492. // NOTE(Felix): for false it is sufficent to pop 2 for
  493. // true we have to copy the then part to the new top
  494. // of the stack
  495. if (cs.data[cs.next_index+1] != Memory::nil) {
  496. cs.data[cs.next_index-1] = cs.data[cs.next_index];
  497. }
  498. } break;
  499. case NasAction::Define_Var: {
  500. /* | <thing> |
  501. | <symbol> |
  502. | .... | */
  503. cs.next_index -= 1;
  504. try assert_type(cs.data[cs.next_index-1], Lisp_Object_Type::Symbol);
  505. try define_symbol(cs.data[cs.next_index-1], cs.data[cs.next_index]);
  506. cs.data[cs.next_index-1] = Memory::t;
  507. }
  508. }
  509. }
  510. // debug_step();
  511. return cs.data[--cs.next_index];
  512. }
  513. proc eval_expr(Lisp_Object* node) -> Lisp_Object* {
  514. return nrc_eval(node);
  515. }
  516. proc is_truthy(Lisp_Object* expression) -> bool {
  517. Lisp_Object* result;
  518. try result = eval_expr(expression);
  519. return result != Memory::nil;
  520. }
  521. proc interprete_file (char* file_name) -> Lisp_Object* {
  522. try Memory::init(4096 * 256);
  523. Lisp_Object* result;
  524. try result = built_in_load(Memory::create_string(file_name));
  525. return result;
  526. }
  527. proc interprete_stdin() -> void {
  528. try_void Memory::init(4096 * 256* 100);
  529. printf("Welcome to the lispy interpreter.\n");
  530. char* line;
  531. Lisp_Object* parsed, * evaluated;
  532. while (true) {
  533. delete_error();
  534. fputs("> ", stdout);
  535. line = read_expression();
  536. try_void parsed = Parser::parse_single_expression(line);
  537. free(line);
  538. try_void evaluated = nrc_eval(parsed);
  539. // try_void evaluated = eval_expr(parsed);
  540. if (evaluated != Memory::nil) {
  541. print(evaluated);
  542. fputs("\n", stdout);
  543. }
  544. }
  545. }
  546. }