Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

546 linhas
20 KiB

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