25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

1155 satır
48 KiB

  1. inline proc maybe_wrap_body_in_begin(Lisp_Object* body) -> Lisp_Object* {
  2. Lisp_Object* begin_symbol = Memory::get_or_create_lisp_object_symbol("begin");
  3. if (body->value.pair.rest == Memory::nil)
  4. return body->value.pair.first;
  5. else
  6. return Memory::create_lisp_object_pair(begin_symbol, body);
  7. }
  8. proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
  9. if (n1 == n2)
  10. return true;
  11. if (Memory::get_type(n1) != Memory::get_type(n2))
  12. return false;
  13. switch (Memory::get_type(n1)) {
  14. case Lisp_Object_Type::CFunction: // if they have the same
  15. // pointer, true is returned a
  16. // few lines above
  17. case Lisp_Object_Type::Function:
  18. case Lisp_Object_Type::Pointer: // TODO(Felix): should a pointer
  19. // object compare the pointer?
  20. case Lisp_Object_Type::Continuation: return false;
  21. case Lisp_Object_Type::T: // code for t and nil should never be
  22. // reached since they are memory unique
  23. case Lisp_Object_Type::Nil: return true;
  24. case Lisp_Object_Type::Number: return n1->value.number == n2->value.number;
  25. case Lisp_Object_Type::String: return string_equal(n1->value.string, n2->value.string);
  26. case Lisp_Object_Type::HashMap:
  27. case Lisp_Object_Type::Pair:
  28. case Lisp_Object_Type::Vector:
  29. create_not_yet_implemented_error();
  30. case Lisp_Object_Type::Symbol:
  31. case Lisp_Object_Type::Keyword:
  32. return false;
  33. }
  34. // we should never reach here
  35. return false;
  36. }
  37. proc built_in_load(String* file_name) -> Lisp_Object* {
  38. // char* full_file_name = find_slime_file(file_name);
  39. char* file_content;
  40. char fullpath[4096];
  41. sprintf(fullpath, "%s", Memory::get_c_str(file_name));
  42. file_content = read_entire_file(Memory::get_c_str(file_name));
  43. if (!file_content) {
  44. // try slime's bin dir
  45. // save the current working directory
  46. // get the direction of the exe
  47. char* exe_path = get_exe_dir();
  48. defer {
  49. free(exe_path);
  50. };
  51. fullpath[0] = '\0';
  52. sprintf(fullpath, "%s%s", exe_path, Memory::get_c_str(file_name));
  53. // printf("Fullpath: %s\n", fullpath);
  54. file_content = read_entire_file(fullpath);
  55. if (!file_content) {
  56. char* cwd = get_cwd();
  57. defer {
  58. free(cwd);
  59. };
  60. create_generic_error("The file to load '%s' was not found: "
  61. "neither in the cwd (%s) "
  62. "nor in slime's exe dir (%s)",
  63. Memory::get_c_str(file_name), cwd, fullpath);
  64. return nullptr;
  65. }
  66. }
  67. Lisp_Object* result = Memory::nil;
  68. Lisp_Object_Array_List program;
  69. try program = Parser::parse_program(Memory::create_string(fullpath), file_content);
  70. for (int i = 0; i < program.next_index; ++i) {
  71. try result = eval_expr(program.data[i]);
  72. }
  73. return result;
  74. }
  75. proc built_in_import(String* file_name) -> Lisp_Object* {
  76. // create new empty environment
  77. Environment* new_env;
  78. try new_env = Memory::create_child_environment(get_root_environment());
  79. append_to_array_list(&get_current_environment()->parents, new_env);
  80. push_environment(new_env);
  81. defer {
  82. pop_environment();
  83. };
  84. Lisp_Object* res = built_in_load(file_name);
  85. return res;
  86. }
  87. proc load_built_ins_into_environment() -> void {
  88. String* file_name_built_ins = Memory::create_string(__FILE__);
  89. #define fetch1(var) \
  90. Lisp_Object* var##_symbol = Memory::get_or_create_lisp_object_symbol(#var); \
  91. Lisp_Object* var = lookup_symbol(var##_symbol, get_current_environment()); \
  92. if (Globals::error) printf("in %s:%d\n", __FILE__, __LINE__)
  93. #define fetch2(var1, var2) fetch1(var1); fetch1(var2)
  94. #define fetch3(var1, var2, var3) fetch2(var1, var2); fetch1(var3)
  95. #define fetch4(var1, var2, var3, var4) fetch3(var1, var2, var3); fetch1(var4)
  96. #define fetch5(var1, var2, var3, var4, var5) fetch4(var1, var2, var3, var4); fetch1(var5)
  97. #define fetch6(var1, var2, var3, var4, var5, var6) fetch5(var1, var2, var3, var4, var5); fetch1(var6)
  98. #define fetch7(var1, var2, var3, var4, var5, var6, var7) fetch6(var1, var2, var3, var4, var5, var6); fetch1(var7)
  99. #define fetch8(var1, var2, var3, var4, var5, var6, var7, var8) fetch7(var1, var2, var3, var4, var5, var6, var7); fetch1(var8)
  100. #define fetch9(var1, var2, var3, var4, var5, var6, var7, var8, var9) fetch8(var1, var2, var3, var4, var5, var6, var7, var8); fetch1(var9)
  101. #define fetch10(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10) fetch9(var1, var2, var3, var4, var5, var6, var7, var8, var9); fetch1(var10)
  102. #define fetch11(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11) fetch10(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10); fetch1(var11)
  103. #define fetch12(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12) fetch11(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11); fetch1(var12)
  104. #define fetch13(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13) fetch12(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12); fetch1(var13)
  105. #define fetch14(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14) fetch13(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13); fetch1(var14)
  106. #define fetch15(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15) fetch14(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14); fetch1(var15)
  107. #define fetch16(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16) fetch15(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15); fetch1(var16)
  108. #define fetch17(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17) fetch16(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16); fetch1(var17)
  109. #define fetch18(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18) fetch17(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17); fetch1(var18)
  110. #define fetch19(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19) fetch18(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18); fetch1(var19)
  111. #define fetch20(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20) fetch19(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19); fetch1(var20)
  112. #define fetch21(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21) fetch20(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20); fetch1(var21)
  113. #define fetch22(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21, var22) fetch21(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21); fetch1(var22)
  114. #define fetch23(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21, var22, var23) fetch22(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21, var22); fetch1(var23)
  115. #define fetch24(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21, var22, var23, var24) fetch23(var1, var2, var3, var4, var5, var6, var7, var8, var9, var10, var11, var12, var13, var14, var15, var16, var17, var18, var19, var20, var21, var22, var23); fetch1(var24)
  116. #define GET_MACRO( \
  117. _1, _2, _3, _4, _5, _6, \
  118. _7, _8, _9, _10, _11, _12, \
  119. _13, _14, _15, _16, _17, _18, \
  120. _19, _20, _21, _22, _23, _24, \
  121. NAME, ...) NAME
  122. #ifdef _MSC_VER
  123. #define EXPAND( x ) x
  124. #define fetch(...) EXPAND( \
  125. GET_MACRO( \
  126. __VA_ARGS__, \
  127. fetch24, fetch23, fetch22, fetch21, fetch20, fetch19, \
  128. fetch18, fetch17, fetch16, fetch15, fetch14, fetch13, \
  129. fetch12, fetch11, fetch10, fetch9, fetch8, fetch7, \
  130. fetch6, fetch5, fetch4, fetch3, fetch2, fetch1 \
  131. )(__VA_ARGS__))
  132. #else
  133. #define fetch(...) \
  134. GET_MACRO( \
  135. __VA_ARGS__, \
  136. fetch24, fetch23, fetch22, fetch21, fetch20, fetch19, \
  137. fetch18, fetch17, fetch16, fetch15, fetch14, fetch13, \
  138. fetch12, fetch11, fetch10, fetch9, fetch8, fetch7, \
  139. fetch6, fetch5, fetch4, fetch3, fetch2, fetch1 \
  140. )(__VA_ARGS__)
  141. #endif
  142. // NOTE(Felix): we have to copy the string because we need
  143. // it to be mutable for the parser to work, because the
  144. // parser relys on being able to temporaily put in markers
  145. // in the code
  146. #define _define_helper(def, docs, special) \
  147. auto label(params,__LINE__) = Parser::parse_single_expression( \
  148. Memory::get_c_str(Memory::create_string(#def)) \
  149. ); \
  150. assert_type(label(params,__LINE__), Lisp_Object_Type::Pair); \
  151. assert_type(label(params,__LINE__)->value.pair.first, Lisp_Object_Type::Symbol); \
  152. auto label(sym,__LINE__) = label(params,__LINE__)->value.pair.first; \
  153. auto label(sfun,__LINE__) = Memory::create_lisp_object_cfunction(special); \
  154. /*NOTE(Felix): for evaluating default args*/ \
  155. /*push_environment(get_root_environment());*/ \
  156. create_arguments_from_lambda_list_and_inject(label(params,__LINE__)->value.pair.rest, label(sfun,__LINE__)); \
  157. /*pop_environment(); */ \
  158. label(sfun,__LINE__)->sourceCodeLocation = new(Source_Code_Location); \
  159. label(sfun,__LINE__)->sourceCodeLocation->file = file_name_built_ins; \
  160. label(sfun,__LINE__)->sourceCodeLocation->line = __LINE__; \
  161. label(sfun,__LINE__)->sourceCodeLocation->column = 0; \
  162. label(sfun,__LINE__)->docstring = Memory::create_string(docs); \
  163. define_symbol(label(sym,__LINE__), label(sfun,__LINE__)); \
  164. label(sfun,__LINE__)->value.cFunction->body = (std::function<Lisp_Object* ()>)[&]() -> Lisp_Object*
  165. #define define(def, docs) _define_helper(def, docs, false)
  166. #define define_special(def, docs) _define_helper(def, docs, true)
  167. #define in_caller_env fluid_let( \
  168. Globals::Current_Execution::envi_stack.next_index, \
  169. Globals::Current_Execution::envi_stack.next_index-1)
  170. define((helper), "") {
  171. return Memory::create_lisp_object_number(101);
  172. };
  173. define((test (:k (helper))), "") {
  174. fetch(k);
  175. return k;
  176. };
  177. define((= . args),
  178. "Takes 0 or more arguments and returns =t= if all arguments are equal "
  179. "and =()= otherwise.")
  180. {
  181. fetch(args);
  182. if (args == Memory::nil)
  183. return Memory::t;
  184. Lisp_Object* first = args->value.pair.first;
  185. for_lisp_list (args) {
  186. if (!lisp_object_equal(it, first))
  187. return Memory::nil;
  188. }
  189. return Memory::t;
  190. };
  191. define((> . args), "TODO")
  192. {
  193. fetch(args);
  194. double last_number = strtod("Inf", NULL);
  195. for_lisp_list (args) {
  196. try assert_type(it, Lisp_Object_Type::Number);
  197. if (it->value.number >= last_number)
  198. return Memory::nil;
  199. last_number = it->value.number;
  200. }
  201. return Memory::t;
  202. };
  203. define((>= . args), "TODO")
  204. {
  205. fetch(args);
  206. double last_number = strtod("Inf", NULL);
  207. for_lisp_list (args) {
  208. try assert_type(it, Lisp_Object_Type::Number);
  209. if (it->value.number > last_number)
  210. return Memory::nil;
  211. last_number = it->value.number;
  212. }
  213. return Memory::t;
  214. };
  215. define((< . args), "TODO")
  216. {
  217. fetch(args);
  218. double last_number = strtod("-Inf", NULL);
  219. for_lisp_list (args) {
  220. try assert_type(it, Lisp_Object_Type::Number);
  221. if (it->value.number <= last_number)
  222. return Memory::nil;
  223. last_number = it->value.number;
  224. }
  225. return Memory::t;
  226. };
  227. define((<= . args), "TODO")
  228. {
  229. fetch(args);
  230. double last_number = strtod("-Inf", NULL);
  231. for_lisp_list (args) {
  232. try assert_type(it, Lisp_Object_Type::Number);
  233. if (it->value.number < last_number)
  234. return Memory::nil;
  235. last_number = it->value.number;
  236. }
  237. return Memory::t;
  238. };
  239. define((+ . args), "TODO")
  240. {
  241. fetch(args);
  242. double sum = 0;
  243. for_lisp_list (args) {
  244. try assert_type(it, Lisp_Object_Type::Number);
  245. sum += it->value.number;
  246. }
  247. return Memory::create_lisp_object_number(sum);
  248. };
  249. define((- . args), "TODO")
  250. {
  251. fetch(args);
  252. if (args == Memory::nil)
  253. return Memory::create_lisp_object_number(0);
  254. try assert_type(args->value.pair.first, Lisp_Object_Type::Number);
  255. double difference = args->value.pair.first->value.number;
  256. if (args->value.pair.rest == Memory::nil) {
  257. return Memory::create_lisp_object_number(-difference);
  258. }
  259. for_lisp_list (args->value.pair.rest) {
  260. try assert_type(it, Lisp_Object_Type::Number);
  261. difference -= it->value.number;
  262. }
  263. return Memory::create_lisp_object_number(difference);
  264. };
  265. define((* . args), "TODO")
  266. {
  267. fetch(args);
  268. if (args == Memory::nil) {
  269. return Memory::create_lisp_object_number(1);
  270. }
  271. double product = 1;
  272. for_lisp_list (args) {
  273. try assert_type(it, Lisp_Object_Type::Number);
  274. product *= it->value.number;
  275. }
  276. return Memory::create_lisp_object_number(product);
  277. };
  278. define((/ . args), "TODO")
  279. {
  280. fetch(args);
  281. if (args == Memory::nil) {
  282. return Memory::create_lisp_object_number(1);
  283. }
  284. try assert_type(args->value.pair.first, Lisp_Object_Type::Number);
  285. double quotient = args->value.pair.first->value.number;
  286. for_lisp_list (args->value.pair.rest) {
  287. try assert_type(it, Lisp_Object_Type::Number);
  288. quotient /= it->value.number;
  289. }
  290. return Memory::create_lisp_object_number(quotient);
  291. };
  292. define((** a b), "TODO") {
  293. fetch(a, b);
  294. try assert_type(a, Lisp_Object_Type::Number);
  295. try assert_type(b, Lisp_Object_Type::Number);
  296. return Memory::create_lisp_object_number(pow(a->value.number,
  297. b->value.number));
  298. };
  299. define((% a b), "TODO") {
  300. fetch(a, b);
  301. try assert_type(a, Lisp_Object_Type::Number);
  302. try assert_type(b, Lisp_Object_Type::Number);
  303. return Memory::create_lisp_object_number((int)a->value.number %
  304. (int)b->value.number);
  305. };
  306. define((get-random-between a b), "TODO") {
  307. fetch(a, b);
  308. try assert_type(a, Lisp_Object_Type::Number);
  309. try assert_type(b, Lisp_Object_Type::Number);
  310. double fa = a->value.number;
  311. double fb = b->value.number;
  312. double x = (double)rand()/(double)(RAND_MAX);
  313. x *= (fb - fa);
  314. x += fa;
  315. return Memory::create_lisp_object_number(x);
  316. };
  317. define_special((bound? var), "TODO") {
  318. fetch(var);
  319. try assert_type(var, Lisp_Object_Type::Symbol);
  320. Lisp_Object* res;
  321. in_caller_env {
  322. res = try_lookup_symbol(var, get_current_environment());
  323. }
  324. if (res)
  325. return Memory::t;
  326. return Memory::nil;
  327. };
  328. define((assert test), "TODO") {
  329. fetch(test);
  330. if (is_truthy(test))
  331. return Memory::t;
  332. create_generic_error("Userland assertion.");
  333. return nullptr;
  334. };
  335. define_special((define-syntax form (:doc "") . body), "TODO") {
  336. fetch(form, doc, body);
  337. // static Lisp_Object *form_symbol = Memory::get_or_create_lisp_object_symbol("form");
  338. // static Lisp_Object *doc_symbol = Memory::get_or_create_lisp_object_symbol("doc");
  339. // static Lisp_Object *body_symbol = Memory::get_or_create_lisp_object_symbol("body");
  340. // printf("\n\nin define-syntax:: envi stack depth: %d\n",
  341. // Globals::Current_Execution::envi_stack.next_index);
  342. // print_environment(get_current_environment());
  343. // Lisp_Object *form = lookup_symbol(form_symbol, get_current_environment());
  344. // Lisp_Object *doc = lookup_symbol(doc_symbol, get_current_environment());
  345. // Lisp_Object *body = lookup_symbol(body_symbol, get_current_environment());
  346. try assert_type(doc, Lisp_Object_Type::String);
  347. // if no doc string, we dont have to store it
  348. if (Memory::get_c_str(doc)[0] == '\0') {
  349. doc = nullptr;
  350. }
  351. if (Memory::get_type(form) != Lisp_Object_Type::Pair) {
  352. create_parsing_error("You can only create function macros.");
  353. return nullptr;
  354. }
  355. Lisp_Object* symbol = form->value.pair.first;
  356. Lisp_Object* lambdalist = form->value.pair.rest;
  357. // creating new lisp object and setting type
  358. Lisp_Object* func;
  359. try func = Memory::create_lisp_object();
  360. Memory::set_type(func, Lisp_Object_Type::Function);
  361. func->value.function.type = Function_Type::Macro;
  362. if (doc) func->docstring = doc->value.string;
  363. in_caller_env {
  364. // setting parent env
  365. func->value.function.parent_environment = get_current_environment();
  366. create_arguments_from_lambda_list_and_inject(lambdalist, func);
  367. func->value.function.body = maybe_wrap_body_in_begin(body);
  368. define_symbol(symbol, func);
  369. }
  370. return Memory::nil;
  371. };
  372. define_special((define definee (:doc "") . body), "TODO") {
  373. fetch(definee, doc, body);
  374. // print_hm(get_current_environment()->hm);
  375. try assert_type(doc, Lisp_Object_Type::String);
  376. // if no doc string, we dont have to store it
  377. if (Memory::get_c_str(doc)[0] == '\0') {
  378. doc = nullptr;
  379. }
  380. if (Memory::get_type(definee) == Lisp_Object_Type::Symbol) {
  381. if (body == Memory::nil) {
  382. create_parsing_error("You at least have to put a value when "
  383. "you are trying to define a variable.");
  384. return nullptr;
  385. } else if (body->value.pair.rest != Memory::nil) {
  386. create_parsing_error("You cannot define more than one thing "
  387. "for one variable.");
  388. return nullptr;
  389. }
  390. auto value = body->value.pair.first;
  391. in_caller_env {
  392. value = eval_expr(value);
  393. define_symbol(definee, value);
  394. }
  395. } else if (Memory::get_type(definee) == Lisp_Object_Type::Pair) {
  396. // definee: (sym . lambdalist)
  397. Lisp_Object* symbol = definee->value.pair.first;
  398. Lisp_Object* lambdalist = definee->value.pair.rest;
  399. // creating new lisp object and setting type
  400. Lisp_Object* func;
  401. try func = Memory::create_lisp_object();
  402. Memory::set_type(func, Lisp_Object_Type::Function);
  403. func->value.function.type = Function_Type::Lambda;
  404. if (doc)
  405. func->docstring = doc->value.string;
  406. in_caller_env {
  407. // setting parent env
  408. func->value.function.parent_environment = get_current_environment();
  409. create_arguments_from_lambda_list_and_inject(lambdalist, func);
  410. func->value.function.body = maybe_wrap_body_in_begin(body);
  411. define_symbol(symbol, func);
  412. }
  413. } else {
  414. create_parsing_error("The to be defined object has to be a "
  415. "symbol or a list. But got a %s.",
  416. Lisp_Object_Type_to_string(
  417. Memory::get_type(definee)));
  418. return nullptr;
  419. }
  420. return Memory::nil;
  421. };
  422. define((mutate target source), "TODO") {
  423. fetch(target, source);
  424. if (target == Memory::nil ||
  425. target == Memory::t ||
  426. Memory::get_type(target) == Lisp_Object_Type::Keyword ||
  427. Memory::get_type(target) == Lisp_Object_Type::Symbol)
  428. {
  429. create_generic_error("You cannot mutate to nil, t, keywords or symbols because they have to be unique");
  430. }
  431. if (source == Memory::nil ||
  432. source == Memory::t ||
  433. Memory::get_type(source) == Lisp_Object_Type::Keyword ||
  434. Memory::get_type(source) == Lisp_Object_Type::Symbol)
  435. {
  436. create_generic_error("You cannot mutate nil, t, keywords or symbols");
  437. }
  438. *target = *source;
  439. return target;
  440. };
  441. define((vector-length v), "TODO") {
  442. fetch(v);
  443. try assert_type(v, Lisp_Object_Type::Vector);
  444. return Memory::create_lisp_object_number((double)v->value.vector.length);
  445. };
  446. define((vector-ref vec idx), "TODO") {
  447. fetch(vec, idx);
  448. try assert_type(vec, Lisp_Object_Type::Vector);
  449. try assert_type(idx, Lisp_Object_Type::Number);
  450. int int_idx = ((int)idx->value.number);
  451. try assert(int_idx >= 0);
  452. try assert(int_idx < vec->value.vector.length);
  453. return vec->value.vector.data+int_idx;
  454. };
  455. define((vector-set! vec idx val), "TODO") {
  456. fetch(vec, idx, val);
  457. try assert_type(vec, Lisp_Object_Type::Vector);
  458. try assert_type(idx, Lisp_Object_Type::Number);
  459. int int_idx = ((int)idx->value.number);
  460. try assert(int_idx >= 0);
  461. try assert(int_idx < vec->value.vector.length);
  462. vec->value.vector.data[int_idx] = *val;
  463. return val;
  464. };
  465. define_special((set! sym val), "TODO") {
  466. fetch(sym, val);
  467. try assert_type(sym, Lisp_Object_Type::Symbol);
  468. Environment* target_env;
  469. in_caller_env {
  470. val = eval_expr(val);
  471. target_env = find_binding_environment(sym, get_current_environment());
  472. if (!target_env)
  473. target_env = get_root_environment();
  474. }
  475. push_environment(target_env);
  476. {
  477. printf("set!ing:: ");
  478. print(sym);
  479. printf(" to ");
  480. print(val);
  481. printf(" in %llu\n", (unsigned long long) target_env);
  482. define_symbol(sym, val);
  483. }
  484. pop_environment();
  485. return val;
  486. };
  487. define((set-car! target source), "TODO") {
  488. fetch(target, source);
  489. try assert_type(target, Lisp_Object_Type::Pair);
  490. *target->value.pair.first = *source;
  491. return source;
  492. };
  493. define((set-cdr! target source), "TODO") {
  494. fetch(target, source);
  495. try assert_type(target, Lisp_Object_Type::Pair);
  496. *target->value.pair.rest = *source;
  497. return source;
  498. };
  499. define_special((if test then_part else_part), "TODO") {
  500. fetch(test, then_part, else_part);
  501. bool truthy;
  502. Lisp_Object* result;
  503. in_caller_env {
  504. try truthy = is_truthy(test);
  505. if (truthy) try result = eval_expr(then_part);
  506. else try result = eval_expr(else_part);
  507. }
  508. return result;
  509. };
  510. define_special((quote datum), "TODO") {
  511. fetch(datum);
  512. return datum;
  513. };
  514. define_special((quasiquote expr), "TODO") {
  515. fetch(expr);
  516. Lisp_Object* unquote_sym = Memory::get_or_create_lisp_object_symbol("unquote");
  517. Lisp_Object* unquote_splicing_sym = Memory::get_or_create_lisp_object_symbol("unquote-splicing");
  518. /* recursive lambdas in lambdas yay!! */
  519. // NOTE(Felix): first we have to initialize the variable
  520. // with a garbage lambda, so that we can then overwrite it
  521. // a recursive lambda
  522. std::function<Lisp_Object*(Lisp_Object*)> unquoteSomeExpressions; // = [] (Lisp_Object* expr) -> Lisp_Object* {return nullptr;};
  523. unquoteSomeExpressions = [&] (Lisp_Object* expr) -> Lisp_Object* {
  524. // if it is an atom, return it
  525. if (Memory::get_type(expr) != Lisp_Object_Type::Pair)
  526. return Memory::copy_lisp_object(expr);
  527. // it is a pair!
  528. Lisp_Object* originalPair = expr->value.pair.first;
  529. if (originalPair == unquote_sym || originalPair == unquote_splicing_sym)
  530. {
  531. // eval replace the stuff
  532. Lisp_Object* ret;
  533. in_caller_env {
  534. ret = eval_expr(expr->value.pair.rest->value.pair.first);
  535. }
  536. return ret;
  537. }
  538. // it is a list but not starting with the symbol
  539. // unquote, so search in there for stuff to unquote.
  540. // While copying the list
  541. //NOTE(Felix): Of fucking course we have to copy the
  542. // list. The quasiquote will be part of the body of a
  543. // funciton, we can't just modify it because otherwise
  544. // we modify the body of the function and would bake
  545. // in the result...
  546. Lisp_Object* newPair = Memory::nil;
  547. Lisp_Object* newPairHead = newPair;
  548. Lisp_Object* head = expr;
  549. while (Memory::get_type(head) == Lisp_Object_Type::Pair) {
  550. // if it is ,@ we have to actually do more work
  551. // and inline the result
  552. if (Memory::get_type(head->value.pair.first) == Lisp_Object_Type::Pair &&
  553. head->value.pair.first->value.pair.first == unquote_splicing_sym)
  554. {
  555. Lisp_Object* spliced = unquoteSomeExpressions(head->value.pair.first);
  556. if (spliced == Memory::nil) {
  557. head = head->value.pair.rest;
  558. continue;
  559. }
  560. try assert_type(spliced, Lisp_Object_Type::Pair);
  561. if (newPair == Memory::nil) {
  562. try newPair = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
  563. newPairHead = newPair;
  564. } else {
  565. try newPairHead->value.pair.rest = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
  566. newPairHead = newPairHead->value.pair.rest;
  567. newPairHead->value.pair.first = spliced->value.pair.first;
  568. newPairHead->value.pair.rest = spliced->value.pair.rest;
  569. // now skip to the end
  570. while (newPairHead->value.pair.rest != Memory::nil) {
  571. newPairHead = newPairHead->value.pair.rest;
  572. }
  573. }
  574. } else {
  575. if (newPair == Memory::nil) {
  576. try newPair = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
  577. newPairHead = newPair;
  578. } else {
  579. try newPairHead->value.pair.rest = Memory::create_lisp_object_pair(Memory::nil, Memory::nil);
  580. newPairHead = newPairHead->value.pair.rest;
  581. }
  582. newPairHead->value.pair.first = unquoteSomeExpressions(head->value.pair.first);
  583. }
  584. // if (Memory::get_type(head->value.pair.rest) != Lisp_Object_Type::Pair) {
  585. // break;
  586. // }
  587. head = head->value.pair.rest;
  588. }
  589. newPairHead->value.pair.rest = Memory::nil;
  590. return newPair;
  591. };
  592. expr = unquoteSomeExpressions(expr);
  593. return expr;
  594. };
  595. define_special((and . args), "TODO") {
  596. fetch(args);
  597. bool result = true;
  598. in_caller_env {
  599. for_lisp_list (args) {
  600. try result &= is_truthy(it);
  601. if (!result)
  602. return Memory::nil;
  603. }
  604. }
  605. return Memory::t;
  606. };
  607. define_special((or . args), "TODO") {
  608. fetch(args);
  609. bool result = false;
  610. in_caller_env {
  611. for_lisp_list (args) {
  612. try result |= is_truthy(it);
  613. if (result)
  614. return Memory::t;
  615. }
  616. }
  617. return Memory::nil;
  618. };
  619. define_special((not test), "TODO") {
  620. fetch(test);
  621. bool truthy;
  622. in_caller_env {
  623. try truthy = is_truthy(test);
  624. }
  625. return (truthy) ? Memory::nil : Memory::t;
  626. };
  627. // // defun("while", "TODO", __LINE__, cLambda {
  628. // // try arguments_length = list_length(arguments);
  629. // // try assert(arguments_length >= 2);
  630. // // Lisp_Object* condition_part = arguments->value.pair.first;
  631. // // Lisp_Object* condition;
  632. // // Lisp_Object* then_part = arguments->value.pair.rest;
  633. // // Lisp_Object* wrapped_then_part;
  634. // // try wrapped_then_part = Memory::create_lisp_object_pair(
  635. // // Memory::get_or_create_lisp_object_symbol("begin"),
  636. // // then_part);
  637. // // Lisp_Object* result = Memory::nil;
  638. // // while (true) {
  639. // // try condition = eval_expr(condition_part);
  640. // // if (condition == Memory::nil)
  641. // // break;
  642. // // try result = eval_expr(wrapped_then_part);
  643. // // }
  644. // // return result;
  645. // // });
  646. define_special((lambda args . body), "TODO") {
  647. fetch(args, body);
  648. Lisp_Object* fun;
  649. try fun = Memory::create_lisp_object();
  650. Memory::set_type(fun, Lisp_Object_Type::Function);
  651. fun->value.function.type = Function_Type::Lambda;
  652. in_caller_env {
  653. fun->value.function.parent_environment = get_current_environment();
  654. }
  655. try create_arguments_from_lambda_list_and_inject(args, fun);
  656. fun->value.function.body = maybe_wrap_body_in_begin(body);
  657. return fun;
  658. };
  659. define_special((special-lambda args . body), "TODO") {
  660. fetch(args, body);
  661. Lisp_Object* fun;
  662. try fun = Memory::create_lisp_object();
  663. Memory::set_type(fun, Lisp_Object_Type::Function);
  664. fun->value.function.type = Function_Type::Special_Lambda;
  665. in_caller_env {
  666. fun->value.function.parent_environment = get_current_environment();
  667. }
  668. try create_arguments_from_lambda_list_and_inject(args, fun);
  669. fun->value.function.body = maybe_wrap_body_in_begin(body);
  670. return fun;
  671. };
  672. define((eval expr), "TODO") {
  673. fetch(expr);
  674. Lisp_Object* result;
  675. in_caller_env {
  676. try result = eval_expr(expr);
  677. }
  678. return result;
  679. };
  680. define_special((begin . args), "TODO") {
  681. fetch(args);
  682. Lisp_Object* result = Memory::nil;
  683. in_caller_env {
  684. for_lisp_list(args) {
  685. try result = eval_expr(it);
  686. }
  687. }
  688. return result;
  689. };
  690. define((list . args), "TODO") {
  691. fetch(args);
  692. return args;
  693. };
  694. define((create-hash-map), "TODO") {
  695. Lisp_Object* ret;
  696. try ret = Memory::create_lisp_object_hash_map();
  697. return ret;
  698. };
  699. define((hash-map-get hm key), "TODO") {
  700. fetch(hm, key);
  701. try assert_type(hm, Lisp_Object_Type::HashMap);
  702. Lisp_Object* ret = (Lisp_Object*)hm_get_object(hm->value.hashMap, key);
  703. if (!ret)
  704. create_symbol_undefined_error("The key was not set in the hashmap");
  705. return ret;
  706. };
  707. define((hash-map-set! hm key value), "TODO") {
  708. fetch(hm, key, value);
  709. try assert_type(hm, Lisp_Object_Type::HashMap);
  710. hm_set(hm->value.hashMap, key, value);
  711. return Memory::nil;
  712. };
  713. define((vector . args), "TODO") {
  714. fetch(args);
  715. Lisp_Object* ret;
  716. int length = list_length(args);
  717. try ret = Memory::create_lisp_object_vector(length, args);
  718. return ret;
  719. };
  720. define((pair car cdr), "TODO") {
  721. fetch(car, cdr);
  722. Lisp_Object* ret;
  723. try ret = Memory::create_lisp_object_pair(car, cdr);
  724. return ret;
  725. };
  726. define((first seq), "TODO") {
  727. fetch(seq);
  728. if (seq == Memory::nil)
  729. return Memory::nil;
  730. try assert_type(seq, Lisp_Object_Type::Pair);
  731. return seq->value.pair.first;
  732. };
  733. define((rest seq), "TODO") {
  734. fetch(seq);
  735. if (seq == Memory::nil)
  736. return Memory::nil;
  737. try assert_type(seq, Lisp_Object_Type::Pair);
  738. return seq->value.pair.rest;
  739. };
  740. define((set-type! node new_type), "TODO") {
  741. fetch(node, new_type);
  742. try assert_type(new_type, Lisp_Object_Type::Keyword);
  743. node->userType = new_type;
  744. return node;
  745. };
  746. define((delete-type! n), "TODO") {
  747. fetch(n);
  748. n->userType = nullptr;
  749. return Memory::t;
  750. };
  751. define((type n), "TODO") {
  752. fetch(n);
  753. if (n->userType) {
  754. return n->userType;
  755. }
  756. Lisp_Object_Type type = Memory::get_type(n);
  757. switch (type) {
  758. case Lisp_Object_Type::Continuation: return Memory::get_or_create_lisp_object_keyword("continuation");
  759. case Lisp_Object_Type::CFunction: return Memory::get_or_create_lisp_object_keyword("cfunction");
  760. case Lisp_Object_Type::Function: {
  761. Function* fun = &n->value.function;
  762. if (fun->type == Function_Type::Lambda)
  763. return Memory::get_or_create_lisp_object_keyword("lambda");
  764. else if (fun->type == Function_Type::Special_Lambda)
  765. return Memory::get_or_create_lisp_object_keyword("special-lambda");
  766. else if (fun->type == Function_Type::Macro)
  767. return Memory::get_or_create_lisp_object_keyword("macro");
  768. else return Memory::get_or_create_lisp_object_keyword("unknown");
  769. }
  770. case Lisp_Object_Type::HashMap: return Memory::get_or_create_lisp_object_keyword("hashmap");
  771. case Lisp_Object_Type::Keyword: return Memory::get_or_create_lisp_object_keyword("keyword");
  772. case Lisp_Object_Type::Nil: return Memory::get_or_create_lisp_object_keyword("nil");
  773. case Lisp_Object_Type::Number: return Memory::get_or_create_lisp_object_keyword("number");
  774. case Lisp_Object_Type::Pair: return Memory::get_or_create_lisp_object_keyword("pair");
  775. case Lisp_Object_Type::Pointer: return Memory::get_or_create_lisp_object_keyword("pointer");
  776. case Lisp_Object_Type::String: return Memory::get_or_create_lisp_object_keyword("string");
  777. case Lisp_Object_Type::Symbol: return Memory::get_or_create_lisp_object_keyword("symbol");
  778. case Lisp_Object_Type::T: return Memory::get_or_create_lisp_object_keyword("t");
  779. case Lisp_Object_Type::Vector: return Memory::get_or_create_lisp_object_keyword("vector");
  780. }
  781. return Memory::get_or_create_lisp_object_keyword("unknown");
  782. };
  783. define((mem-reset), "TODO") {
  784. Memory::reset();
  785. return Memory::nil;
  786. };
  787. // NOTE(Felix): we need to define_special because the docstring is
  788. // attached to the symbol. Because some object are singletons
  789. // (symbols, keyowrds, nil, t) we dont want to store docs on the
  790. // object. Otherwise (define k :doc "hallo" :keyword) would modify
  791. // the global keyword
  792. define_special((info n), "TODO") {
  793. fetch(n);
  794. print(n);
  795. Lisp_Object* type;
  796. Lisp_Object* val;
  797. in_caller_env {
  798. try type = eval_expr(Memory::create_list(Memory::get_or_create_lisp_object_symbol("type"), n));
  799. try val = eval_expr(n);
  800. }
  801. printf(" is of type ");
  802. print(type);
  803. printf(" (internal: %s)", Lisp_Object_Type_to_string(Memory::get_type(val)));
  804. printf("\nand is printed as: ");
  805. print(val);
  806. printf("\n\ndocs: \n %s\n",
  807. (val->docstring)
  808. ? Memory::get_c_str(val->docstring)
  809. : "No docs avaliable");
  810. if (Memory::get_type(val) == Lisp_Object_Type::Function ||
  811. Memory::get_type(val) == Lisp_Object_Type::CFunction)
  812. {
  813. Arguments* args;
  814. if (Memory::get_type(val) == Lisp_Object_Type::Function)
  815. args = &val->value.function.args;
  816. else
  817. args = &val->value.cFunction->args;
  818. printf("Arguments:\n==========\n");
  819. printf("Postitional: {");
  820. if (args->positional.symbols.next_index != 0) {
  821. printf("%s",
  822. Memory::get_c_str(args->positional.symbols.data[0]->value.symbol.identifier));
  823. for (int i = 1; i < args->positional.symbols.next_index; ++i) {
  824. printf(", %s",
  825. Memory::get_c_str(args->positional.symbols.data[i]->value.symbol.identifier));
  826. }
  827. }
  828. printf("}\n");
  829. printf("Keyword: {");
  830. if (args->keyword.values.next_index != 0) {
  831. printf("%s",
  832. Memory::get_c_str(args->keyword.keywords.data[0]->value.symbol.identifier));
  833. if (args->keyword.values.data[0]) {
  834. printf(" (");
  835. print(args->keyword.values.data[0], true);
  836. printf(")");
  837. }
  838. for (int i = 1; i < args->keyword.values.next_index; ++i) {
  839. printf(", %s",
  840. Memory::get_c_str(args->keyword.keywords.data[i]->value.symbol.identifier));
  841. if (args->keyword.values.data[i]) {
  842. printf(" (");
  843. print(args->keyword.values.data[i], true);
  844. printf(")");
  845. }
  846. }
  847. }
  848. printf("}\n");
  849. printf("Rest: {");
  850. if (args->rest)
  851. printf("%s",
  852. Memory::get_c_str(args->rest->value.symbol.identifier));
  853. printf("}\n");
  854. }
  855. return Memory::nil;
  856. };
  857. define((show n), "TODO") {
  858. fetch(n);
  859. try assert_type(n, Lisp_Object_Type::Function);
  860. puts("body:\n");
  861. print(n->value.function.body);
  862. puts("\n");
  863. printf("parent_env: %lld\n",
  864. (long long)n->value.function.parent_environment);
  865. return Memory::nil;
  866. };
  867. define((addr-of var), "TODO") {
  868. fetch(var);
  869. return Memory::create_lisp_object_number(
  870. (float)((u64)&(var)));
  871. };
  872. define((generate-docs file_name), "TODO") {
  873. fetch(file_name);
  874. try assert_type(file_name, Lisp_Object_Type::String);
  875. // try generate_docs(file_name->value.string);
  876. return Memory::t;
  877. };
  878. define((print (:sep " ") (:end "\n") . things), "TODO") {
  879. fetch(sep, end, things);
  880. if (things != Memory::nil) {
  881. print(things->value.pair.first);
  882. for_lisp_list(things->value.pair.rest) {
  883. print(sep);
  884. print(it);
  885. }
  886. }
  887. print(end);
  888. return Memory::nil;
  889. };
  890. define((read (:prompt ">")), "TODO") {
  891. fetch(prompt);
  892. print(prompt);
  893. // TODO(Felix): make read_line return a String*
  894. char* line = read_line();
  895. defer {
  896. free(line);
  897. };
  898. String* strLine = Memory::create_string(line);
  899. return Memory::create_lisp_object_string(strLine);
  900. };
  901. define((exit (:code 0)), "TODO") {
  902. fetch(code);
  903. try assert_type(code, Lisp_Object_Type::Number);
  904. exit((int)code->value.number);
  905. };
  906. define((break), "TODO") {
  907. in_caller_env {
  908. print_environment(get_current_environment());
  909. }
  910. return Memory::nil;
  911. };
  912. define((memstat), "TODO") {
  913. Memory::print_status();
  914. return Memory::nil;
  915. };
  916. define_special((mytry try_part catch_part), "TODO") {
  917. fetch(try_part, catch_part);
  918. Lisp_Object* result;
  919. in_caller_env {
  920. result = eval_expr(try_part);
  921. if (Globals::error) {
  922. delete_error();
  923. try result = eval_expr(catch_part);
  924. }
  925. }
  926. return result;
  927. };
  928. define((load file), "TODO") {
  929. fetch(file);
  930. try assert_type(file, Lisp_Object_Type::String);
  931. Lisp_Object* result;
  932. in_caller_env {
  933. try result = built_in_load(file->value.string);
  934. }
  935. return result;
  936. };
  937. define((import f), "TODO") {
  938. fetch(f);
  939. try assert_type(f, Lisp_Object_Type::String);
  940. Lisp_Object *result;
  941. in_caller_env {
  942. try result = built_in_import(f->value.string);
  943. }
  944. return Memory::t;
  945. };
  946. define((copy obj), "TODO") {
  947. fetch(obj);
  948. // TODO(Felix): if we are copying string nodes, then
  949. // shouldn't the string itself also get copied??
  950. return Memory::copy_lisp_object(obj);
  951. };
  952. define((error type message), "TODO") {
  953. fetch(type, message);
  954. // TODO(Felix): make the error function useful
  955. try assert_type(type, Lisp_Object_Type::Keyword);
  956. try assert_type(message, Lisp_Object_Type::String);
  957. using Globals::error;
  958. error = new(Error);
  959. error->type = type;
  960. error->message = message->value.string;
  961. create_generic_error("Userlanderror");
  962. return nullptr;
  963. };
  964. define((symbol->keyword sym), "TODO") {
  965. fetch(sym);
  966. try assert_type(sym, Lisp_Object_Type::Symbol);
  967. return Memory::get_or_create_lisp_object_keyword(sym->value.symbol.identifier);
  968. };
  969. define((string->symbol str), "TODO") {
  970. fetch(str);
  971. // TODO(Felix): do some sanity checks on the string. For
  972. // example, numbers are not valid symbols.
  973. try assert_type(str, Lisp_Object_Type::String);
  974. return Memory::get_or_create_lisp_object_symbol(
  975. Memory::duplicate_string(str->value.string));
  976. };
  977. define((symbol->string sym), "TODO") {
  978. fetch(sym);
  979. try assert_type(sym, Lisp_Object_Type::Symbol);
  980. return Memory::create_lisp_object_string(
  981. Memory::duplicate_string(sym->value.symbol.identifier));
  982. };
  983. define((concat-strings . strings), "TODO") {
  984. fetch(strings);
  985. int resulting_string_len = 0;
  986. for_lisp_list (strings) {
  987. try assert_type(it, Lisp_Object_Type::String);
  988. resulting_string_len += it->value.string->length;
  989. }
  990. String* resulting_string = Memory::create_string("", resulting_string_len);
  991. int index_in_string = 0;
  992. for_lisp_list (strings) {
  993. strcpy((&resulting_string->data)+index_in_string,
  994. Memory::get_c_str(it->value.string));
  995. index_in_string += it->value.string->length;
  996. }
  997. return Memory::create_lisp_object_string(resulting_string);
  998. };
  999. }