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

502 строки
19 KiB

  1. proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> Lisp_Object* {
  2. Environment* new_env;
  3. try new_env = Memory::create_child_environment(function->parent_environment);
  4. Lisp_Object* sym, *val; // used as temp storage to use `try`
  5. // positional arguments
  6. for (int i = 0; i < function->positional_arguments->next_index; ++i) {
  7. if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
  8. create_wrong_number_of_arguments_error(function->positional_arguments->next_index, i);
  9. return nullptr;
  10. }
  11. // TODO(Felix): here we create new lisp_object_symbols from
  12. // their identifiers but before we converted them to
  13. // strings from symbols... Wo maybe just use the symbols?
  14. try sym = Memory::get_or_create_lisp_object_symbol(function->positional_arguments->identifiers[i]);
  15. define_symbol(sym, arguments->value.pair.first, new_env);
  16. arguments = arguments->value.pair.rest;
  17. }
  18. String_Array_List* read_in_keywords = create_String_array_list();
  19. if (arguments == Memory::nil)
  20. goto checks;
  21. // keyword arguments: use all given ones and keep track of the
  22. // added ones (array list), if end of parameters in encountered or
  23. // something that is not a keyword is encountered or a keyword
  24. // that is not recognized is encoutered, jump out of the loop.
  25. while (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) {
  26. // check if this one is even an accepted keyword
  27. bool accepted = false;
  28. for (int i = 0; i < function->keyword_arguments->next_index; ++i) {
  29. if (string_equal(
  30. arguments->value.pair.first->value.identifier,
  31. function->keyword_arguments->identifiers[i]))
  32. {
  33. accepted = true;
  34. break;
  35. }
  36. }
  37. if (!accepted) {
  38. // TODO(Felix): if we are actually done with all the
  39. // necessary keywords then we have to count the rest
  40. // as :rest here, instead od always creating an error
  41. // (special case with default variables)
  42. create_generic_error(
  43. "The function does not take the keyword argument ':%s'",
  44. &(arguments->value.pair.first->value.identifier));
  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.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_generic_error(
  58. "The function already read the keyword argument ':%s'",
  59. &(arguments->value.pair.first->value.identifier));
  60. return nullptr;
  61. }
  62. }
  63. // okay so we found a keyword that has to be read in and was
  64. // not already read in, is there a next element to actually
  65. // set it to?
  66. if (Memory::get_type(arguments->value.pair.rest) != Lisp_Object_Type::Pair) {
  67. create_generic_error(
  68. "Attempting to set the keyword argument ':%s', but no value was supplied.",
  69. &(arguments->value.pair.first->value.identifier));
  70. return nullptr;
  71. }
  72. // if not set it and then add it to the array list
  73. try sym = Memory::get_or_create_lisp_object_symbol(arguments->value.pair.first->value.identifier),
  74. define_symbol(sym, arguments->value.pair.rest->value.pair.first, new_env);
  75. append_to_array_list(read_in_keywords, arguments->value.pair.first->value.identifier);
  76. // overstep both for next one
  77. arguments = arguments->value.pair.rest->value.pair.rest;
  78. if (arguments == Memory::nil) {
  79. break;
  80. }
  81. }
  82. checks:
  83. // check if all necessary keywords have been read in
  84. for (int i = 0; i < function->keyword_arguments->next_index; ++i) {
  85. String* defined_keyword = function->keyword_arguments->identifiers[i];
  86. bool was_set = false;
  87. for (int j = 0; j < read_in_keywords->next_index; ++j) {
  88. if (string_equal(
  89. read_in_keywords->data[j],
  90. defined_keyword))
  91. {
  92. was_set = true;
  93. break;
  94. }
  95. }
  96. if (function->keyword_arguments->values->data[i] == nullptr) {
  97. // if this one does not have a default value
  98. if (!was_set) {
  99. create_generic_error(
  100. "There was no value supplied for the required "
  101. "keyword argument ':%s'.",
  102. &defined_keyword->data);
  103. return nullptr;
  104. }
  105. } else {
  106. // this one does have a default value, lets see if we have
  107. // to use it or if the user supplied his own
  108. if (!was_set) {
  109. try sym = Memory::get_or_create_lisp_object_symbol(defined_keyword);
  110. try val = Memory::copy_lisp_object(function->keyword_arguments->values->data[i]);
  111. define_symbol(sym, val, new_env);
  112. }
  113. }
  114. }
  115. if (arguments == Memory::nil) {
  116. if (function->rest_argument) {
  117. try sym = Memory::get_or_create_lisp_object_symbol(function->rest_argument);
  118. define_symbol(sym, Memory::nil, new_env);
  119. }
  120. } else {
  121. if (function->rest_argument) {
  122. try sym = Memory::get_or_create_lisp_object_symbol(function->rest_argument);
  123. define_symbol(sym, arguments, new_env);
  124. } else {
  125. // rest was not declared but additional arguments were found
  126. create_generic_error(
  127. "A rest argument was not declared "
  128. "but the function was called with additional arguments.");
  129. return nullptr;
  130. }
  131. }
  132. Lisp_Object* result;
  133. try result = eval_expr(function->body, new_env);
  134. return result;
  135. }
  136. /*
  137. (prog
  138. (define type--before type)
  139. (define type
  140. (lambda (e)
  141. (if (and (= (type--before e) :pair) (= (first e) :my-type))
  142. :my-type
  143. (type--before e))))
  144. )
  145. */
  146. /**
  147. This parses the argument specification of funcitons into their
  148. Function struct. It dois this by allocating new
  149. positional_arguments, keyword_arguments and rest_argument and
  150. filling it in
  151. */
  152. proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
  153. // first init the fields
  154. function->positional_arguments = create_positional_argument_list(16);
  155. function->keyword_arguments = create_keyword_argument_list(16);
  156. function->rest_argument = nullptr;
  157. // okay let's try to read some positional arguments
  158. while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
  159. if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) {
  160. if (string_equal(arguments->value.pair.first->value.identifier, "keys") ||
  161. string_equal(arguments->value.pair.first->value.identifier, "rest"))
  162. break;
  163. else {
  164. create_parsing_error("A non recognized marker was found "
  165. "in the lambda list: ':%s'",
  166. &arguments->value.pair.first->value.identifier);
  167. return;
  168. }
  169. }
  170. if (Memory::get_type(arguments->value.pair.first) != Lisp_Object_Type::Symbol) {
  171. create_parsing_error("Only symbols and keywords can be "
  172. "parsed here, but found '%s'",
  173. Lisp_Object_Type_to_string(Memory::get_type(arguments->value.pair.first)));
  174. return;
  175. }
  176. // okay wow we found an actual symbol
  177. append_to_positional_argument_list(
  178. function->positional_arguments,
  179. arguments->value.pair.first->value.identifier);
  180. arguments = arguments->value.pair.rest;
  181. }
  182. // okay we are done with positional arguments, lets check for
  183. // keywords,
  184. if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
  185. if (arguments != Memory::nil)
  186. create_parsing_error("The lambda list must be nil terminated.");
  187. return;
  188. }
  189. if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword &&
  190. string_equal(arguments->value.pair.first->value.identifier, "keys"))
  191. {
  192. arguments = arguments->value.pair.rest;
  193. if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
  194. create_parsing_error("Actual keys have to follow the :keys indicator.");
  195. }
  196. // if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) {
  197. // create_parsing_error(
  198. // "Only symbols can be parsed here, but found '%s'.",
  199. // Lisp_Object_Type_to_string(arguments->value.pair.first->type));
  200. // return;
  201. // }
  202. while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
  203. if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) {
  204. if (string_equal(arguments->value.pair.first->value.identifier, "rest"))
  205. break;
  206. else {
  207. create_parsing_error(
  208. "Only the :rest keyword can be parsed here, but got ':%s'.",
  209. &arguments->value.pair.first->value.identifier->data);
  210. return;
  211. }
  212. }
  213. if (Memory::get_type(arguments->value.pair.first) != Lisp_Object_Type::Symbol) {
  214. create_parsing_error(
  215. "Only symbols can be parsed here, but found '%s'.",
  216. Lisp_Object_Type_to_string(Memory::get_type(arguments->value.pair.first)));
  217. return;
  218. }
  219. // we found a symbol (arguments->value.pair->first) for
  220. // the keyword args! Let's check if the next arguement is
  221. // :defaults-to
  222. Lisp_Object* next = arguments->value.pair.rest;
  223. if (Memory::get_type(next) == Lisp_Object_Type::Pair &&
  224. Memory::get_type(next->value.pair.first) == Lisp_Object_Type::Keyword &&
  225. string_equal(next->value.pair.first->value.identifier,
  226. "defaults-to"))
  227. {
  228. // check if there is a next argument too, otherwise it
  229. // would be an error
  230. next = next->value.pair.rest;
  231. if (Memory::get_type(next) == Lisp_Object_Type::Pair) {
  232. append_to_keyword_argument_list(function->keyword_arguments,
  233. arguments->value.pair.first->value.identifier,
  234. next->value.pair.first);
  235. arguments = next->value.pair.rest;
  236. } else {
  237. create_parsing_error("Expecting a value after 'defaults-to'");
  238. return;
  239. }
  240. } else {
  241. // No :defaults-to, so just add it to the list
  242. append_to_keyword_argument_list(function->keyword_arguments,
  243. arguments->value.pair.first->value.identifier,
  244. nullptr);
  245. arguments = next;
  246. }
  247. }
  248. }
  249. // Now we are also done with keyword arguments, lets check for
  250. // if there is a rest argument
  251. if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
  252. if (arguments != Memory::nil)
  253. create_parsing_error("The lambda list must be nil terminated.");
  254. return;
  255. }
  256. if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword &&
  257. string_equal(arguments->value.pair.first->value.identifier, "rest"))
  258. {
  259. arguments = arguments->value.pair.rest;
  260. if (// arguments->type != Lisp_Object_Type::Pair ||
  261. Memory::get_type(arguments->value.pair.first) != Lisp_Object_Type::Symbol)
  262. {
  263. create_parsing_error("After the 'rest' marker there must follow a symbol.");
  264. return;
  265. }
  266. function->rest_argument = arguments->value.pair.first->value.identifier;
  267. if (arguments->value.pair.rest != Memory::nil) {
  268. create_parsing_error("The lambda list must end after the rest symbol");
  269. }
  270. } else {
  271. printf("this should not happen?");
  272. create_generic_error("What is happening?");
  273. }
  274. }
  275. proc list_length(Lisp_Object* node) -> int {
  276. if (node == Memory::nil)
  277. return 0;
  278. assert_type(node, Lisp_Object_Type::Pair);
  279. int len = 0;
  280. while (Memory::get_type(node) == Lisp_Object_Type::Pair) {
  281. ++len;
  282. node = node->value.pair.rest;
  283. if (node == Memory::nil)
  284. return len;
  285. }
  286. create_parsing_error("Can't calculate length of ill formed list.");
  287. return 0;
  288. }
  289. proc extract_keyword_value(char* keyword, Parsed_Arguments* args) -> Lisp_Object* {
  290. // NOTE(Felix): This will be a hashmap lookup later
  291. for (int i = 0; i < args->keyword_keys->next_index; ++i) {
  292. if (string_equal(args->keyword_keys->data[i]->value.identifier, keyword))
  293. return args->keyword_values->data[i];
  294. }
  295. return nullptr;
  296. }
  297. proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments_length) -> Lisp_Object* {
  298. int my_out_arguments_length = 0;
  299. if (arguments == Memory::nil) {
  300. *(out_arguments_length) = 0;
  301. return arguments;
  302. }
  303. Lisp_Object* evaluated_arguments;
  304. try evaluated_arguments = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
  305. Lisp_Object* evaluated_arguments_head = evaluated_arguments;
  306. Lisp_Object* current_head = arguments;
  307. while (Memory::get_type(current_head) == Lisp_Object_Type::Pair) {
  308. try evaluated_arguments_head->value.pair.first = eval_expr(current_head->value.pair.first, env);
  309. evaluated_arguments_head->value.pair.first->sourceCodeLocation = current_head->value.pair.first->sourceCodeLocation;
  310. current_head = current_head->value.pair.rest;
  311. if (Memory::get_type(current_head) == Lisp_Object_Type::Pair) {
  312. try evaluated_arguments_head->value.pair.rest = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
  313. evaluated_arguments_head = evaluated_arguments_head->value.pair.rest;
  314. } else if (current_head == Memory::nil) {
  315. evaluated_arguments_head->value.pair.rest = current_head;
  316. } else {
  317. create_parsing_error("Attempting to evaluate ill formed argument list.");
  318. return nullptr;
  319. }
  320. ++my_out_arguments_length;
  321. }
  322. *(out_arguments_length) = my_out_arguments_length;
  323. return evaluated_arguments;
  324. }
  325. proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
  326. Globals::current_source_code = node;
  327. switch (Memory::get_type(node)) {
  328. case Lisp_Object_Type::T:
  329. case Lisp_Object_Type::Nil:
  330. case Lisp_Object_Type::Number:
  331. case Lisp_Object_Type::Keyword:
  332. case Lisp_Object_Type::String:
  333. return node;
  334. case Lisp_Object_Type::Symbol: {
  335. Lisp_Object* symbol;
  336. try symbol = lookup_symbol(node, env);
  337. return symbol;
  338. }
  339. case Lisp_Object_Type::Pair: {
  340. Lisp_Object* lispOperator;
  341. if (Memory::get_type(node->value.pair.first) != Lisp_Object_Type::CFunction &&
  342. Memory::get_type(node->value.pair.first) != Lisp_Object_Type::Function)
  343. {
  344. try lispOperator = eval_expr(node->value.pair.first, env);
  345. } else {
  346. lispOperator = node->value.pair.first;
  347. }
  348. Lisp_Object* arguments = node->value.pair.rest;
  349. int arguments_length;
  350. // check for c function
  351. if (Memory::get_type(lispOperator) == Lisp_Object_Type::CFunction) {
  352. Lisp_Object* result;
  353. try result = lispOperator->value.cFunction->function(arguments, env);
  354. return result;
  355. }
  356. // check for lisp function
  357. if (Memory::get_type(lispOperator) == Lisp_Object_Type::Function) {
  358. // only for lambdas we evaluate the arguments before
  359. // apllying
  360. if (lispOperator->value.function.type == Function_Type::Lambda) {
  361. try arguments = eval_arguments(arguments, env, &arguments_length);
  362. }
  363. Lisp_Object* result;
  364. try result = apply_arguments_to_function(arguments, &lispOperator->value.function);
  365. return result;
  366. }
  367. }
  368. default: {
  369. create_generic_error("%s is not a function.", Lisp_Object_Type_to_string(Memory::get_type(node)));
  370. return nullptr;
  371. }
  372. }
  373. }
  374. proc is_truthy(Lisp_Object* expression, Environment* env) -> bool {
  375. Lisp_Object* result;
  376. try result = eval_expr(expression, env);
  377. return result != Memory::nil;
  378. }
  379. proc interprete_file (char* file_name) -> Lisp_Object* {
  380. Memory::init(4096 * 256, 1024, 4096 * 256);
  381. Environment* root_env = Globals::root_environment;
  382. Environment* user_env;
  383. try user_env = Memory::create_child_environment(root_env);
  384. Parser::environment_for_macros = user_env;
  385. // char* file_content;
  386. // try file_content = read_entire_file(file_name);
  387. built_in_import(Memory::create_string("pre.slime"), user_env);
  388. Lisp_Object* result;
  389. result = built_in_load(Memory::create_string(file_name), user_env);
  390. if (Globals::error) {
  391. log_error();
  392. delete_error();
  393. return nullptr;
  394. }
  395. return result;
  396. }
  397. proc interprete_stdin() -> void {
  398. Memory::init(4096 * 256, 1024, 4096 * 256);
  399. Environment* root_env = Globals::root_environment;
  400. Environment* user_env = Memory::create_child_environment(root_env);
  401. if (Globals::error) {
  402. log_error();
  403. delete_error();
  404. return;
  405. }
  406. Parser::environment_for_macros = user_env;
  407. printf("Welcome to the lispy interpreter.\n");
  408. char* line;
  409. built_in_import(Memory::create_string("pre.slime"), user_env);
  410. if (Globals::error) {
  411. log_error();
  412. delete_error();
  413. }
  414. Lisp_Object* parsed, * evaluated;
  415. while (true) {
  416. printf(">");
  417. line = read_expression();
  418. defer {
  419. free(line);
  420. };
  421. parsed = Parser::parse_single_expression(line);
  422. if (Globals::error) {
  423. log_error();
  424. delete_error();
  425. continue;
  426. }
  427. evaluated = eval_expr(parsed, user_env);
  428. if (Globals::error) {
  429. log_error();
  430. delete_error();
  431. continue;
  432. }
  433. print(evaluated);
  434. printf("\n");
  435. }
  436. }