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

495 строки
19 KiB

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