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

549 строки
20 KiB

  1. proc create_extended_environment_for_function_application(
  2. Lisp_Object* unevaluated_arguments,
  3. Lisp_Object* function,
  4. bool should_evaluate) -> Environment*
  5. {
  6. profile_this;
  7. bool is_c_function = Memory::get_type(function) == Lisp_Object_Type::CFunction;
  8. Environment* new_env;
  9. Lisp_Object* arguments = unevaluated_arguments;
  10. Arguments* arg_spec;
  11. // NOTE(Felix): Step 1.
  12. // - setting the parent environment
  13. // - setting the arg_spec
  14. // - potentially evaluating the arguments
  15. if (is_c_function) {
  16. new_env = Memory::create_child_environment(get_root_environment());
  17. arg_spec = &function->value.cFunction->args;
  18. } else {
  19. new_env = Memory::create_child_environment(function->value.function.parent_environment);
  20. arg_spec = &function->value.function.args;
  21. }
  22. if (should_evaluate) {
  23. try arguments = eval_arguments(arguments);
  24. }
  25. // NOTE(Felix): Even though we will return the environment at the
  26. // end, for defining symbols here for the parameters, it has to be
  27. // on the envi stack.
  28. push_environment(new_env);
  29. defer {
  30. pop_environment();
  31. };
  32. // NOTE(Felix): Step 2.
  33. // Reading the argument spec and fill in the environment
  34. // for the function call
  35. Lisp_Object* sym, *val; // used as temp storage to use `try`
  36. Lisp_Object_Array_List read_in_keywords;
  37. int obligatory_keywords_count = 0;
  38. int read_obligatory_keywords_count = 0;
  39. proc read_positional_args = [&]() -> void {
  40. for (int i = 0; i < arg_spec->positional.symbols.next_index; ++i) {
  41. if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
  42. create_wrong_number_of_arguments_error(arg_spec->positional.symbols.next_index, i);
  43. return;
  44. }
  45. // NOTE(Felix): We have to copy all the arguments,
  46. // otherwise we change the program code. XXX(Felix): T C
  47. // functions we pass by reference...
  48. try_void sym = arg_spec->positional.symbols.data[i];
  49. if (is_c_function) {
  50. define_symbol(sym, arguments->value.pair.first);
  51. } else {
  52. define_symbol(
  53. sym,
  54. Memory::copy_lisp_object_except_pairs(arguments->value.pair.first));
  55. }
  56. arguments = arguments->value.pair.rest;
  57. }
  58. };
  59. proc read_keyword_args = [&]() -> void {
  60. // keyword arguments: use all given ones and keep track of the
  61. // added ones (array list), if end of parameters in encountered or
  62. // something that is not a keyword is encountered or a keyword
  63. // that is not recognized is encoutered, jump out of the loop.
  64. read_in_keywords = create_Lisp_Object_array_list();
  65. if (arguments == Memory::nil)
  66. return;
  67. // find out how many keyword args we /have/ to read
  68. for (int i = 0; i < arg_spec->keyword.values.next_index; ++i) {
  69. if (arg_spec->keyword.values.data[i] == nullptr)
  70. ++obligatory_keywords_count;
  71. else
  72. break;
  73. }
  74. while (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) {
  75. // check if this one is even an accepted keyword
  76. bool accepted = false;
  77. for (int i = 0; i < arg_spec->keyword.values.next_index; ++i) {
  78. if (arguments->value.pair.first == arg_spec->keyword.keywords.data[i])
  79. {
  80. accepted = true;
  81. break;
  82. }
  83. }
  84. if (!accepted) {
  85. // NOTE(Felix): if we are actually done with all the
  86. // necessary keywords then we have to count the rest
  87. // as :rest here, instead od always creating an error
  88. // (special case with default variables)
  89. if (read_obligatory_keywords_count == obligatory_keywords_count)
  90. return;
  91. create_generic_error(
  92. "The function does not take the keyword argument ':%s'\n"
  93. "and not all required keyword arguments have been read\n"
  94. "in to potentially count it as the rest argument.",
  95. &(arguments->value.pair.first->value.symbol.identifier->data));
  96. return;
  97. }
  98. // check if it was already read in
  99. for (int i = 0; i < read_in_keywords.next_index; ++i) {
  100. if (arguments->value.pair.first == read_in_keywords.data[i])
  101. {
  102. // NOTE(Felix): if we are actually done with all the
  103. // necessary keywords then we have to count the rest
  104. // as :rest here, instead od always creating an error
  105. // (special case with default variables)
  106. if (read_obligatory_keywords_count == obligatory_keywords_count)
  107. return;
  108. create_generic_error(
  109. "The function already read the keyword argument ':%s'",
  110. &(arguments->value.pair.first->value.symbol.identifier->data));
  111. return;
  112. }
  113. }
  114. // okay so we found a keyword that has to be read in and was
  115. // not already read in, is there a next element to actually
  116. // set it to?
  117. if (Memory::get_type(arguments->value.pair.rest) != Lisp_Object_Type::Pair) {
  118. create_generic_error(
  119. "Attempting to set the keyword argument ':%s', but no value was supplied.",
  120. &(arguments->value.pair.first->value.symbol.identifier->data));
  121. return;
  122. }
  123. // if not set it and then add it to the array list
  124. try_void sym = Memory::get_or_create_lisp_object_symbol(arguments->value.pair.first->value.symbol.identifier);
  125. // NOTE(Felix): It seems we do not need to evaluate the argument here...
  126. if (is_c_function) {
  127. try_void define_symbol(sym, arguments->value.pair.rest->value.pair.first);
  128. } else {
  129. try_void define_symbol(
  130. sym,
  131. Memory::copy_lisp_object_except_pairs(arguments->value.pair.rest->value.pair.first));
  132. }
  133. append_to_array_list(&read_in_keywords, arguments->value.pair.first);
  134. ++read_obligatory_keywords_count;
  135. // overstep both for next one
  136. arguments = arguments->value.pair.rest->value.pair.rest;
  137. if (arguments == Memory::nil) {
  138. break;
  139. }
  140. }
  141. };
  142. proc check_keyword_args = [&]() -> void {
  143. // check if all necessary keywords have been read in
  144. for (int i = 0; i < arg_spec->keyword.values.next_index; ++i) {
  145. auto defined_keyword = arg_spec->keyword.keywords.data[i];
  146. bool was_set = false;
  147. for (int j = 0; j < read_in_keywords.next_index; ++j) {
  148. // TODO(Felix): Later compare the keywords, not their strings!!
  149. if (read_in_keywords.data[j] == defined_keyword)
  150. {
  151. was_set = true;
  152. break;
  153. }
  154. }
  155. if (arg_spec->keyword.values.data[i] == nullptr) {
  156. // if this one does not have a default value
  157. if (!was_set) {
  158. create_generic_error(
  159. "There was no value supplied for the required "
  160. "keyword argument ':%s'.",
  161. &defined_keyword->value.symbol.identifier->data);
  162. return;
  163. }
  164. } else {
  165. // this one does have a default value, lets see if we have
  166. // to use it or if the user supplied his own
  167. if (!was_set) {
  168. try_void sym = Memory::get_or_create_lisp_object_symbol(defined_keyword->value.symbol.identifier);
  169. if (is_c_function) {
  170. try_void val = arg_spec->keyword.values.data[i];
  171. } else {
  172. try_void val = Memory::copy_lisp_object_except_pairs(arg_spec->keyword.values.data[i]);
  173. }
  174. define_symbol(sym, val);
  175. }
  176. }
  177. }
  178. };
  179. proc read_rest_arg = [&]() -> void {
  180. if (arguments == Memory::nil) {
  181. if (arg_spec->rest) {
  182. define_symbol(arg_spec->rest, Memory::nil);
  183. }
  184. } else {
  185. if (arg_spec->rest) {
  186. define_symbol(
  187. arg_spec->rest,
  188. // NOTE(Felix): arguments will be a list, and I THINK
  189. // we do not need to copy it...
  190. arguments);
  191. } else {
  192. // rest was not declared but additional arguments were found
  193. create_generic_error(
  194. "A rest argument was not declared "
  195. "but the function was called with additional arguments.");
  196. return;
  197. }
  198. }
  199. };
  200. try read_positional_args();
  201. try read_keyword_args();
  202. try check_keyword_args();
  203. try read_rest_arg();
  204. return new_env;
  205. }
  206. proc apply_arguments_to_function(Lisp_Object* arguments, Lisp_Object* function, bool should_evaluate_args) -> Lisp_Object* {
  207. profile_this;
  208. Environment* new_env;
  209. Lisp_Object* result;
  210. try new_env = create_extended_environment_for_function_application(arguments, function, should_evaluate_args);
  211. push_environment(new_env);
  212. defer {
  213. pop_environment();
  214. };
  215. // if c function:
  216. if (Memory::get_type(function) == Lisp_Object_Type::CFunction)
  217. try result = function->value.cFunction->body();
  218. else // if lisp function
  219. try result = eval_expr(function->value.function.body);
  220. return result;
  221. }
  222. /**
  223. This parses the argument specification of funcitons into their
  224. Function struct. It does this by allocating new
  225. positional_arguments, keyword_arguments and rest_argument and
  226. filling it in
  227. */
  228. proc create_arguments_from_lambda_list_and_inject(Lisp_Object* arguments, Lisp_Object* function) -> void {
  229. Arguments* result;
  230. if (Memory::get_type(function) == Lisp_Object_Type::CFunction) {
  231. result = &function->value.cFunction->args;
  232. } else {
  233. result = &function->value.function.args;
  234. }
  235. // first init the fields
  236. result->positional = create_positional_argument_list(16);
  237. result->keyword = create_keyword_argument_list(16);
  238. result->rest = nullptr;
  239. // okay let's try to read some positional arguments
  240. while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
  241. // if we encounter a keyword or a list (for keywords with
  242. // defualt args), the positionals are done
  243. if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword ||
  244. Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Pair) {
  245. break;
  246. }
  247. // if we encounter something that is neither a symbol nor a
  248. // keyword arg, it's an error
  249. if (Memory::get_type(arguments->value.pair.first) != Lisp_Object_Type::Symbol) {
  250. create_parsing_error("Only symbols and keywords "
  251. "(with or without default args) "
  252. "can be parsed here, but found '%s'",
  253. Lisp_Object_Type_to_string(Memory::get_type(arguments->value.pair.first)));
  254. return;
  255. }
  256. // okay we found an actual symbol
  257. append_to_positional_argument_list(
  258. &result->positional,
  259. arguments->value.pair.first);
  260. arguments = arguments->value.pair.rest;
  261. }
  262. // if we reach here, we are on a keyword or a pair wher a keyword
  263. // should be in first
  264. while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
  265. if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) {
  266. // if we are on a actual keyword (with no default arg)
  267. auto keyword = arguments->value.pair.first;
  268. append_to_keyword_argument_list(&result->keyword, keyword, nullptr);
  269. } else if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Pair) {
  270. // if we are on a keyword with a default value
  271. auto keyword = arguments->value.pair.first->value.pair.first;
  272. if (Memory::get_type(keyword) != Lisp_Object_Type::Keyword) {
  273. create_parsing_error("Default args must be keywords");
  274. }
  275. if (Memory::get_type(arguments->value.pair.first->value.pair.rest)
  276. != Lisp_Object_Type::Pair)
  277. {
  278. create_parsing_error("Default args must be a list of 2.");
  279. }
  280. auto value = arguments->value.pair.first->value.pair.rest->value.pair.first;
  281. value = eval_expr(value);
  282. if (arguments->value.pair.first->value.pair.rest->value.pair.rest != Memory::nil) {
  283. create_parsing_error("Default args must be a list of 2.");
  284. }
  285. append_to_keyword_argument_list(&result->keyword, keyword, value);
  286. }
  287. arguments = arguments->value.pair.rest;
  288. }
  289. // Now we are also done with keyword arguments, lets check for
  290. // if there is a rest argument
  291. if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
  292. if (arguments == Memory::nil)
  293. return;
  294. if (Memory::get_type(arguments) == Lisp_Object_Type::Symbol)
  295. result->rest = arguments;
  296. else
  297. create_parsing_error("The rest argument must be a symbol.");
  298. }
  299. }
  300. proc list_length(Lisp_Object* node) -> int {
  301. if (node == Memory::nil)
  302. return 0;
  303. assert_type(node, Lisp_Object_Type::Pair);
  304. int len = 0;
  305. while (Memory::get_type(node) == Lisp_Object_Type::Pair) {
  306. ++len;
  307. node = node->value.pair.rest;
  308. if (node == Memory::nil)
  309. return len;
  310. }
  311. create_parsing_error("Can't calculate length of ill formed list.");
  312. return 0;
  313. }
  314. proc eval_arguments(Lisp_Object* arguments) -> Lisp_Object* {
  315. profile_this;
  316. // int my_out_arguments_length = 0;
  317. if (arguments == Memory::nil) {
  318. // *(out_arguments_length) = 0;
  319. return arguments;
  320. }
  321. Lisp_Object* evaluated_arguments;
  322. try evaluated_arguments = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
  323. Lisp_Object* evaluated_arguments_head = evaluated_arguments;
  324. Lisp_Object* current_head = arguments;
  325. while (Memory::get_type(current_head) == Lisp_Object_Type::Pair) {
  326. try evaluated_arguments_head->value.pair.first = eval_expr(current_head->value.pair.first);
  327. evaluated_arguments_head->value.pair.first->sourceCodeLocation = current_head->value.pair.first->sourceCodeLocation;
  328. current_head = current_head->value.pair.rest;
  329. if (Memory::get_type(current_head) == Lisp_Object_Type::Pair) {
  330. try evaluated_arguments_head->value.pair.rest = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
  331. evaluated_arguments_head = evaluated_arguments_head->value.pair.rest;
  332. } else if (current_head == Memory::nil) {
  333. evaluated_arguments_head->value.pair.rest = current_head;
  334. } else {
  335. create_parsing_error("Attempting to evaluate ill formed argument list.");
  336. return nullptr;
  337. }
  338. // ++my_out_arguments_length;
  339. }
  340. // *(out_arguments_length) = my_out_arguments_length;
  341. return evaluated_arguments;
  342. }
  343. proc eval_expr(Lisp_Object* node) -> Lisp_Object* {
  344. profile_this;
  345. using namespace Globals::Current_Execution;
  346. append_to_array_list(&call_stack, node);
  347. defer {
  348. // NOTE(Felix): We only delete the current entry from the call
  349. // stack, if we did not encounter an error, otherwise we neet
  350. // to preserve the callstack to print it later. it will be
  351. // cleared in log_error().
  352. if (!Globals::error)
  353. --call_stack.next_index;
  354. };
  355. switch (Memory::get_type(node)) {
  356. case Lisp_Object_Type::T:
  357. case Lisp_Object_Type::Nil:
  358. case Lisp_Object_Type::Number:
  359. case Lisp_Object_Type::Keyword:
  360. case Lisp_Object_Type::String:
  361. case Lisp_Object_Type::Function:
  362. case Lisp_Object_Type::CFunction:
  363. return node;
  364. case Lisp_Object_Type::Symbol: {
  365. Lisp_Object* value;
  366. try value = lookup_symbol(node, get_current_environment());
  367. return value;
  368. }
  369. case Lisp_Object_Type::Pair: {
  370. Lisp_Object* lispOperator;
  371. if (Memory::get_type(node->value.pair.first) != Lisp_Object_Type::CFunction &&
  372. Memory::get_type(node->value.pair.first) != Lisp_Object_Type::Function)
  373. {
  374. try lispOperator = eval_expr(node->value.pair.first);
  375. } else {
  376. lispOperator = node->value.pair.first;
  377. }
  378. Lisp_Object* arguments = node->value.pair.rest;
  379. // check for c function
  380. if (Memory::get_type(lispOperator) == Lisp_Object_Type::CFunction) {
  381. Lisp_Object* result;
  382. try result = apply_arguments_to_function(
  383. arguments,
  384. lispOperator,
  385. !lispOperator->value.cFunction->is_special_form);
  386. return result;
  387. }
  388. // check for lisp function
  389. if (Memory::get_type(lispOperator) == Lisp_Object_Type::Function) {
  390. // only for lambdas we evaluate the arguments before
  391. // apllying, for the other types, special-lambda and macro
  392. // we do not need.
  393. Lisp_Object* result;
  394. try result = apply_arguments_to_function(
  395. arguments,
  396. lispOperator,
  397. lispOperator->value.function.type == Function_Type::Lambda);
  398. // NOTE(Felix): The parser does not understnad (import ..)
  399. // so it cannot expand imported macros at read time
  400. // (because at read time, they are not imported yet, this
  401. // is done at runtime...). That is why we sometimes have
  402. // stray macros fying around, in that case, we expand them
  403. // and bake them in, so they do not have to be expanded
  404. // later again. We will call this "lazy macro expansion"
  405. if (lispOperator->value.function.type == Function_Type::Macro) {
  406. // bake in the macro expansion:
  407. *node = *result;
  408. // eval again because macro
  409. try result = eval_expr(result);
  410. }
  411. return result;
  412. }
  413. }
  414. default: {
  415. create_generic_error("%s is not a function.", Lisp_Object_Type_to_string(Memory::get_type(node)));
  416. return nullptr;
  417. }
  418. }
  419. }
  420. proc is_truthy(Lisp_Object* expression) -> bool {
  421. Lisp_Object* result;
  422. try result = eval_expr(expression);
  423. return result != Memory::nil;
  424. }
  425. proc interprete_file (char* file_name) -> Lisp_Object* {
  426. Memory::init(4096 * 256, 1024, 4096 * 256);
  427. Environment* root_env = get_root_environment();
  428. Environment* user_env;
  429. try user_env = Memory::create_child_environment(root_env);
  430. push_environment(user_env);
  431. defer {
  432. pop_environment();
  433. };
  434. Lisp_Object* result = built_in_load(Memory::create_string(file_name));
  435. if (Globals::error) {
  436. log_error();
  437. delete_error();
  438. return nullptr;
  439. }
  440. return result;
  441. }
  442. proc interprete_stdin() -> void {
  443. Memory::init(4096 * 256, 1024, 4096 * 256);
  444. Environment* root_env = get_root_environment();
  445. Environment* user_env = Memory::create_child_environment(root_env);
  446. push_environment(user_env);
  447. defer {
  448. pop_environment();
  449. };
  450. if (Globals::error) {
  451. log_error();
  452. delete_error();
  453. return;
  454. }
  455. printf("Welcome to the lispy interpreter.\n");
  456. char* line;
  457. Lisp_Object* parsed, * evaluated;
  458. while (true) {
  459. printf("> ");
  460. line = read_expression();
  461. defer {
  462. free(line);
  463. };
  464. parsed = Parser::parse_single_expression(line);
  465. if (Globals::error) {
  466. log_error();
  467. delete_error();
  468. continue;
  469. }
  470. evaluated = eval_expr(parsed);
  471. if (Globals::error) {
  472. log_error();
  473. delete_error();
  474. continue;
  475. }
  476. if (evaluated != Memory::nil) {
  477. print(evaluated);
  478. printf("\n");
  479. }
  480. }
  481. }