| @@ -9,11 +9,14 @@ | |||||
| (context-mode 1) | (context-mode 1) | ||||
| (defun start-debugger () | (defun start-debugger () | ||||
| (async-shell-command | |||||
| (concat | |||||
| "cdbg64.exe" " -t " | |||||
| (expand-windows-path (concat (projectile-project-root) | |||||
| "bin/slime.exe"))))) | |||||
| (interactive) | |||||
| (let ((default-directory (expand-windows-path (concat (projectile-project-root) "bin/")))) | |||||
| (unless (process-running-p "remedybg.exe") | |||||
| (start-process "remedy" "*remedyout*" | |||||
| "remedybg.exe" "open-session" | |||||
| (expand-windows-path (concat (projectile-project-root) "bin/slime.rdbg")))) | |||||
| (start-process "remedy" "*remedyout*" "remedybg.exe" "start-debugging"))) | |||||
| (defhydra hydra-context (context-mode-map "<f2>") | (defhydra hydra-context (context-mode-map "<f2>") | ||||
| "Context Actions:" | "Context Actions:" | ||||
| @@ -31,6 +34,4 @@ | |||||
| (c++-mode . ((eval . (company-clang-set-prefix "slime.h")) | (c++-mode . ((eval . (company-clang-set-prefix "slime.h")) | ||||
| (eval . (flycheck-mode 0)) | (eval . (flycheck-mode 0)) | ||||
| (eval . (rainbow-mode 0)) | |||||
| (eval . (setq c-backslash-max-column 99)) | |||||
| ))) | |||||
| (eval . (setq c-backslash-max-column 99))))) | |||||
| @@ -18,6 +18,7 @@ | |||||
| (promise)) | (promise)) | ||||
| (define-syntax (mac a) (list + 1 1)) | (define-syntax (mac a) (list + 1 1)) | ||||
| (define-syntax (add . args) (pair '+ args)) | |||||
| (define-syntax (when condition . body) | (define-syntax (when condition . body) | ||||
| :doc "Special form for when multiple actions should be done if a | :doc "Special form for when multiple actions should be done if a | ||||
| @@ -38,6 +39,7 @@ condition is true. | |||||
| `(if ,condition ,@body nil) | `(if ,condition ,@body nil) | ||||
| `(if ,condition (begin ,@body) nil))) | `(if ,condition (begin ,@body) nil))) | ||||
| (define-syntax (unless condition . body) | (define-syntax (unless condition . body) | ||||
| :doc "Special form for when multiple actions should be done if a | :doc "Special form for when multiple actions should be done if a | ||||
| condition is false." | condition is false." | ||||
| @@ -21,14 +21,14 @@ rem call ..\timecmd cl ^ | |||||
| rem call ..\timecmd clang-cl ../src/main.cpp -o %exeName% /O2 /std:c++latest /W3 /Zi /EHsc | rem call ..\timecmd clang-cl ../src/main.cpp -o %exeName% /O2 /std:c++latest /W3 /Zi /EHsc | ||||
| if %errorlevel% == 0 ( | |||||
| echo. | |||||
| echo ---- Running Tests ---- | |||||
| echo. | |||||
| call slime.exe --run-tests | |||||
| ) else ( | |||||
| echo. | |||||
| echo Fuckin' ell | |||||
| ) | |||||
| rem if %errorlevel% == 0 ( | |||||
| rem echo. | |||||
| rem echo ---- Running Tests ---- | |||||
| rem echo. | |||||
| rem call slime.exe --run-tests | |||||
| rem ) else ( | |||||
| rem echo. | |||||
| rem echo Fuckin' ell | |||||
| rem ) | |||||
| popd | popd | ||||
| @@ -1,5 +1,4 @@ | |||||
| namespace Slime { | namespace Slime { | ||||
| proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool { | proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool { | ||||
| if (n1 == n2) | if (n1 == n2) | ||||
| return true; | return true; | ||||
| @@ -113,6 +112,123 @@ namespace Slime { | |||||
| profile_this(); | profile_this(); | ||||
| String* file_name_built_ins = Memory::create_string(__FILE__); | String* file_name_built_ins = Memory::create_string(__FILE__); | ||||
| // define_macro((apply fun args), "TODO") { | |||||
| // profile_with_name("(apply)"); | |||||
| // }; | |||||
| define_macro((eval expr), | |||||
| "Takes one argument, and evaluates it two times.") | |||||
| { | |||||
| profile_with_name("(eval)"); | |||||
| using namespace Globals::Current_Execution; | |||||
| cs.data[cs.next_index-1] = pcs[--pcs.next_index]->value.pair.first; | |||||
| (nass.end()-1)->append(NasAction::Eval); | |||||
| (nass.end()-1)->append(NasAction::Eval); | |||||
| }; | |||||
| define_macro((begin . rest), | |||||
| "Takes any number of forms. Evaluates them in order, " | |||||
| "and returns the last result.") | |||||
| { | |||||
| profile_with_name("(begin)"); | |||||
| using namespace Globals::Current_Execution; | |||||
| --cs.next_index; | |||||
| --ams.next_index; | |||||
| Lisp_Object* args = pcs[--pcs.next_index]; | |||||
| int length = list_length(args); | |||||
| cs.reserve(length); | |||||
| for_lisp_list(args) { | |||||
| cs.data[cs.next_index - 1 + (length - it_index)] = it; | |||||
| (nass.end()-1)->append(NasAction::Eval); | |||||
| (nass.end()-1)->append(NasAction::Pop); | |||||
| } | |||||
| --(nass.end()-1)->next_index; | |||||
| cs.next_index += length; | |||||
| }; | |||||
| define_macro((if test then_part else_part), | |||||
| "Takes 3 arguments. If the first arguments evaluates to a truthy " | |||||
| "value, the if expression evaluates the second argument, else " | |||||
| "it will evaluete the third one and return them respectively.") | |||||
| { | |||||
| profile_with_name("(if)"); | |||||
| using namespace Globals::Current_Execution; | |||||
| /* | | | <test> | | |||||
| | | -> | <then> | | |||||
| | <if> | | <else> | | |||||
| | .... | | ...... | */ | |||||
| --ams.next_index; | |||||
| Lisp_Object* args = pcs.data[--pcs.next_index]; | |||||
| Lisp_Object* test = args->value.pair.first; | |||||
| args = args->value.pair.rest; | |||||
| try_void assert_type(args, Lisp_Object_Type::Pair); | |||||
| Lisp_Object* consequence = args->value.pair.first; | |||||
| args = args->value.pair.rest; | |||||
| try_void assert_type(args, Lisp_Object_Type::Pair); | |||||
| Lisp_Object* alternative = args->value.pair.first; | |||||
| args = args->value.pair.rest; | |||||
| try_void assert_type(args, Lisp_Object_Type::Nil); | |||||
| --cs.next_index; | |||||
| cs.append(alternative); | |||||
| cs.append(consequence); | |||||
| cs.append(test); | |||||
| (nass.end()-1)->append(NasAction::Eval); | |||||
| (nass.end()-1)->append(NasAction::If); | |||||
| (nass.end()-1)->append(NasAction::Eval); | |||||
| }; | |||||
| define_macro((define definee . args), "") { | |||||
| // NOTE(Felix): define has to be a macro, because we need | |||||
| // to evaluate the value for definee in case it is a | |||||
| // simple variable (not a function). So ebcause we don't | |||||
| // want to recursivly evaluate the value, we use a macro | |||||
| // and a NasAction. | |||||
| profile_with_name("(define)"); | |||||
| using namespace Globals::Current_Execution; | |||||
| --cs.next_index; | |||||
| --ams.next_index; | |||||
| Lisp_Object* form = pcs.data[--pcs.next_index]; | |||||
| Lisp_Object* definee = form->value.pair.first; | |||||
| form = form->value.pair.rest; | |||||
| try_void assert_type(form, Lisp_Object_Type::Pair); | |||||
| Lisp_Object* thing = form->value.pair.first; | |||||
| Lisp_Object* thing_cons = form; | |||||
| form = form->value.pair.rest; | |||||
| Lisp_Object_Type type = Memory::get_type(definee); | |||||
| switch (type) { | |||||
| case Lisp_Object_Type::Symbol: { | |||||
| // BUG(Felix): Defining with doc string crashes | |||||
| if (form != Memory::nil) { | |||||
| Lisp_Object* doc = thing; | |||||
| try_void assert_type(doc, Lisp_Object_Type::String); | |||||
| try_void assert_type(form, Lisp_Object_Type::Pair); | |||||
| form = form->value.pair.rest; | |||||
| thing = form->value.pair.first; | |||||
| try_void assert(form->value.pair.rest == Memory::nil); | |||||
| // TODO docs | |||||
| } | |||||
| cs.append(definee); | |||||
| cs.append(thing); | |||||
| (nass.end()-1)->append(NasAction::Define_Var); | |||||
| (nass.end()-1)->append(NasAction::Eval); | |||||
| } break; | |||||
| case Lisp_Object_Type::Pair: { | |||||
| fflush(stdout); | |||||
| try_void assert_type(definee->value.pair.first, Lisp_Object_Type::Symbol); | |||||
| Lisp_Object* func; | |||||
| try_void func = Memory::create_lisp_object_function(Lisp_Function_Type::Lambda); | |||||
| func->value.function->parent_environment = get_current_environment(); | |||||
| create_arguments_from_lambda_list_and_inject(definee->value.pair.rest, func); | |||||
| func->value.function->body.lisp_body = maybe_wrap_body_in_begin(thing_cons); | |||||
| define_symbol(definee->value.pair.first, func); | |||||
| cs.append(Memory::t); | |||||
| } break; | |||||
| default: { | |||||
| create_generic_error("you can only define symbols"); | |||||
| return; | |||||
| } | |||||
| } | |||||
| }; | |||||
| define((helper), "") { | define((helper), "") { | ||||
| profile_with_name("(helper)"); | profile_with_name("(helper)"); | ||||
| return Memory::create_lisp_object(101.0); | return Memory::create_lisp_object(101.0); | ||||
| @@ -141,8 +257,7 @@ namespace Slime { | |||||
| return Memory::t; | return Memory::t; | ||||
| }; | }; | ||||
| define((> . args), "TODO") | |||||
| { | |||||
| define((> . args), "TODO") { | |||||
| profile_with_name("(>)"); | profile_with_name("(>)"); | ||||
| fetch(args); | fetch(args); | ||||
| double last_number = strtod("Inf", NULL); | double last_number = strtod("Inf", NULL); | ||||
| @@ -347,11 +462,6 @@ namespace Slime { | |||||
| // creating new lisp object and setting type | // creating new lisp object and setting type | ||||
| Lisp_Object* func; | Lisp_Object* func; | ||||
| try func = Memory::create_lisp_object_function(Lisp_Function_Type::Macro); | try func = Memory::create_lisp_object_function(Lisp_Function_Type::Macro); | ||||
| // Lisp_Object* func; | |||||
| // try func = Memory::create_lisp_object(); | |||||
| // Memory::set_type(func, Lisp_Object_Type::Function); | |||||
| // func->value.function->type = Function_Type::Macro; | |||||
| if (doc) func->docstring = doc->value.string; | if (doc) func->docstring = doc->value.string; | ||||
| in_caller_env { | in_caller_env { | ||||
| @@ -363,62 +473,6 @@ namespace Slime { | |||||
| } | } | ||||
| return Memory::nil; | return Memory::nil; | ||||
| }; | }; | ||||
| define_special((define definee (:doc "") . body), "TODO") { | |||||
| profile_with_name("(define)"); | |||||
| fetch(definee, doc, body); | |||||
| // print_hm(get_current_environment()->hm); | |||||
| try assert_type(doc, Lisp_Object_Type::String); | |||||
| // if no doc string, we dont have to store it | |||||
| if (Memory::get_c_str(doc)[0] == '\0') { | |||||
| doc = nullptr; | |||||
| } | |||||
| if (Memory::get_type(definee) == Lisp_Object_Type::Symbol) { | |||||
| if (body == Memory::nil) { | |||||
| create_parsing_error("You at least have to put a value when " | |||||
| "you are trying to define a variable."); | |||||
| return nullptr; | |||||
| } else if (body->value.pair.rest != Memory::nil) { | |||||
| create_parsing_error("You cannot define more than one thing " | |||||
| "for one variable."); | |||||
| return nullptr; | |||||
| } | |||||
| auto value = body->value.pair.first; | |||||
| in_caller_env { | |||||
| try value = eval_expr(value); | |||||
| define_symbol(definee, value); | |||||
| } | |||||
| } else if (Memory::get_type(definee) == Lisp_Object_Type::Pair) { | |||||
| // definee: (sym . lambdalist) | |||||
| Lisp_Object* symbol = definee->value.pair.first; | |||||
| Lisp_Object* lambdalist = definee->value.pair.rest; | |||||
| // creating new lisp object and setting type | |||||
| Lisp_Object* func; | |||||
| try func = Memory::create_lisp_object_function(Lisp_Function_Type::Lambda); | |||||
| if (doc) | |||||
| func->docstring = doc->value.string; | |||||
| in_caller_env { | |||||
| // setting parent env | |||||
| func->value.function->parent_environment = get_current_environment(); | |||||
| create_arguments_from_lambda_list_and_inject(lambdalist, func); | |||||
| func->value.function->body.lisp_body = maybe_wrap_body_in_begin(body); | |||||
| define_symbol(symbol, func); | |||||
| } | |||||
| } else { | |||||
| create_parsing_error("The to be defined object has to be a " | |||||
| "symbol or a list. But got a %s.", | |||||
| Lisp_Object_Type_to_string( | |||||
| Memory::get_type(definee))); | |||||
| return nullptr; | |||||
| } | |||||
| return Memory::nil; | |||||
| }; | |||||
| define((mutate target source), "TODO") { | define((mutate target source), "TODO") { | ||||
| profile_with_name("(mutate)"); | profile_with_name("(mutate)"); | ||||
| fetch(target, source); | fetch(target, source); | ||||
| @@ -516,21 +570,6 @@ namespace Slime { | |||||
| *target->value.pair.rest = *source; | *target->value.pair.rest = *source; | ||||
| return source; | return source; | ||||
| }; | }; | ||||
| define_special((if test then_part else_part), "TODO") { | |||||
| profile_with_name("(if)"); | |||||
| fetch(test, then_part, else_part); | |||||
| bool truthy; | |||||
| Lisp_Object* result; | |||||
| in_caller_env { | |||||
| try truthy = is_truthy(test); | |||||
| if (truthy) try result = eval_expr(then_part); | |||||
| else try result = eval_expr(else_part); | |||||
| } | |||||
| return result; | |||||
| }; | |||||
| define_special((quote datum), "TODO") { | define_special((quote datum), "TODO") { | ||||
| profile_with_name("(quote)"); | profile_with_name("(quote)"); | ||||
| fetch(datum); | fetch(datum); | ||||
| @@ -672,32 +711,32 @@ namespace Slime { | |||||
| } | } | ||||
| return (truthy) ? Memory::nil : Memory::t; | return (truthy) ? Memory::nil : Memory::t; | ||||
| }; | }; | ||||
| // // defun("while", "TODO", __LINE__, cLambda { | |||||
| // // try arguments_length = list_length(arguments); | |||||
| // // try assert(arguments_length >= 2); | |||||
| // // // defun("while", "TODO", __LINE__, cLambda { | |||||
| // // // try arguments_length = list_length(arguments); | |||||
| // // // try assert(arguments_length >= 2); | |||||
| // // Lisp_Object* condition_part = arguments->value.pair.first; | |||||
| // // Lisp_Object* condition; | |||||
| // // Lisp_Object* then_part = arguments->value.pair.rest; | |||||
| // // Lisp_Object* wrapped_then_part; | |||||
| // // // Lisp_Object* condition_part = arguments->value.pair.first; | |||||
| // // // Lisp_Object* condition; | |||||
| // // // Lisp_Object* then_part = arguments->value.pair.rest; | |||||
| // // // Lisp_Object* wrapped_then_part; | |||||
| // // try wrapped_then_part = Memory::create_lisp_object_pair( | |||||
| // // Memory::get_symbol("begin"), | |||||
| // // then_part); | |||||
| // // // try wrapped_then_part = Memory::create_lisp_object_pair( | |||||
| // // // Memory::get_symbol("begin"), | |||||
| // // // then_part); | |||||
| // // Lisp_Object* result = Memory::nil; | |||||
| // // // Lisp_Object* result = Memory::nil; | |||||
| // // while (true) { | |||||
| // // try condition = eval_expr(condition_part); | |||||
| // // // while (true) { | |||||
| // // // try condition = eval_expr(condition_part); | |||||
| // // if (condition == Memory::nil) | |||||
| // // break; | |||||
| // // // if (condition == Memory::nil) | |||||
| // // // break; | |||||
| // // try result = eval_expr(wrapped_then_part); | |||||
| // // } | |||||
| // // return result; | |||||
| // // // try result = eval_expr(wrapped_then_part); | |||||
| // // // } | |||||
| // // // return result; | |||||
| // // }); | |||||
| // // // }); | |||||
| define_special((lambda args . body), "TODO") { | define_special((lambda args . body), "TODO") { | ||||
| profile_with_name("(lambda)"); | profile_with_name("(lambda)"); | ||||
| fetch(args, body); | fetch(args, body); | ||||
| @@ -714,37 +753,6 @@ namespace Slime { | |||||
| func->value.function->body.lisp_body = maybe_wrap_body_in_begin(body); | func->value.function->body.lisp_body = maybe_wrap_body_in_begin(body); | ||||
| return func; | return func; | ||||
| }; | }; | ||||
| define((apply fun args), "TODO") { | |||||
| profile_with_name("(apply)"); | |||||
| fetch(fun, args); | |||||
| Lisp_Object* result; | |||||
| try result = apply_arguments_to_function(args, fun, /*eval_args=*/false); | |||||
| return result; | |||||
| }; | |||||
| define((eval expr), "TODO") { | |||||
| profile_with_name("(eval)"); | |||||
| fetch(expr); | |||||
| Lisp_Object* result; | |||||
| in_caller_env { | |||||
| try result = eval_expr(expr); | |||||
| } | |||||
| return result; | |||||
| }; | |||||
| define_special((begin . args), "TODO") { | |||||
| profile_with_name("(begin)"); | |||||
| fetch(args); | |||||
| Lisp_Object* result = Memory::nil; | |||||
| in_caller_env { | |||||
| for_lisp_list(args) { | |||||
| try result = eval_expr(it); | |||||
| } | |||||
| } | |||||
| return result; | |||||
| }; | |||||
| define((list . args), "TODO") { | define((list . args), "TODO") { | ||||
| profile_with_name("(list)"); | profile_with_name("(list)"); | ||||
| fetch(args); | fetch(args); | ||||
| @@ -875,20 +883,20 @@ namespace Slime { | |||||
| } | } | ||||
| return Memory::get_keyword("unknown"); | return Memory::get_keyword("unknown"); | ||||
| }; | }; | ||||
| define((mem-reset), "TODO") { | |||||
| profile_with_name("(mem-reset)"); | |||||
| Memory::reset(); | |||||
| return Memory::nil; | |||||
| }; | |||||
| // NOTE(Felix): we need to define_special because the docstring is | |||||
| // attached to the symbol. Because some object are singletons | |||||
| // (symbols, keyowrds, nil, t) we dont want to store docs on the | |||||
| // object. Otherwise (define k :doc "hallo" :keyword) would modify | |||||
| // the global keyword | |||||
| define_special((info n), "TODO") { | |||||
| // define((mem-reset), "TODO") { | |||||
| // profile_with_name("(mem-reset)"); | |||||
| // Memory::reset(); | |||||
| // return Memory::nil; | |||||
| // }; | |||||
| define_special((info n), "TODO") | |||||
| { | |||||
| // NOTE(Felix): we need to define_special because the docstring is | |||||
| // attached to the symbol. Because some object are singletons | |||||
| // (symbols, keyowrds, nil, t) we dont want to store docs on the | |||||
| // object. Otherwise (define k :doc "hallo" :keyword) would modify | |||||
| // // the global keyword | |||||
| profile_with_name("(info)"); | profile_with_name("(info)"); | ||||
| fetch(n); | fetch(n); | ||||
| print(n); | print(n); | ||||
| Lisp_Object* type; | Lisp_Object* type; | ||||
| @@ -108,7 +108,7 @@ | |||||
| // mutable for the parser to work, because the parser relys on being | // mutable for the parser to work, because the parser relys on being | ||||
| // able to temporaily put in markers in the code and also it will fill | // able to temporaily put in markers in the code and also it will fill | ||||
| // out the source code location | // out the source code location | ||||
| #define _define_helper(def, docs, type) \ | |||||
| #define _define_helper(def, docs, type, ending) \ | |||||
| Parser::parser_file = file_name_built_ins; \ | Parser::parser_file = file_name_built_ins; \ | ||||
| Parser::parser_line = __LINE__; \ | Parser::parser_line = __LINE__; \ | ||||
| Parser::parser_col = 0; \ | Parser::parser_col = 0; \ | ||||
| @@ -124,11 +124,12 @@ | |||||
| label(sfun,__LINE__)->docstring = Memory::create_string(docs); \ | label(sfun,__LINE__)->docstring = Memory::create_string(docs); \ | ||||
| label(sfun,__LINE__)->value.function->parent_environment = get_current_environment(); \ | label(sfun,__LINE__)->value.function->parent_environment = get_current_environment(); \ | ||||
| define_symbol(label(sym,__LINE__), label(sfun,__LINE__)); \ | define_symbol(label(sym,__LINE__), label(sfun,__LINE__)); \ | ||||
| label(sfun,__LINE__)->value.function->body.c_body = []() -> Lisp_Object* | |||||
| label(sfun,__LINE__)->value.function->body. ending | |||||
| #define define(def, docs) _define_helper(def, docs, Slime::C_Function_Type::cFunction, c_body = []() -> Lisp_Object*) | |||||
| #define define_special(def, docs) _define_helper(def, docs, Slime::C_Function_Type::cSpecial, c_body = []() -> Lisp_Object*) | |||||
| #define define_macro(def, docs) _define_helper(def, docs, Slime::C_Function_Type::cMacro, c_macro_body = []() -> void) | |||||
| #define define(def, docs) _define_helper(def, docs, Slime::C_Function_Type::cFunction) | |||||
| #define define_macro(def, docs) _define_helper(def, docs, Slime::C_Function_Type::cMacro) | |||||
| #define define_special(def, docs) _define_helper(def, docs, Slime::C_Function_Type::cSpecial) | |||||
| #define in_caller_env fluid_let( \ | #define in_caller_env fluid_let( \ | ||||
| Globals::Current_Execution::envi_stack.next_index, \ | Globals::Current_Execution::envi_stack.next_index, \ | ||||
| Globals::Current_Execution::envi_stack.next_index-1) | Globals::Current_Execution::envi_stack.next_index-1) | ||||
| @@ -645,18 +645,15 @@ namespace Slime { | |||||
| proc nrc_eval(Lisp_Object* expr) -> Lisp_Object* { | proc nrc_eval(Lisp_Object* expr) -> Lisp_Object* { | ||||
| using namespace Globals::Current_Execution; | using namespace Globals::Current_Execution; | ||||
| enum struct Action { | |||||
| Eval, | |||||
| Step, | |||||
| TM, | |||||
| Pop, | |||||
| If, | |||||
| Define_Var, | |||||
| Pop_Environment | |||||
| }; | |||||
| Array_List<Action> nas; | |||||
| nas.alloc(); | |||||
| nass.reserve(1); | |||||
| Array_List<NasAction>* nas = nass.data+(nass.next_index++); | |||||
| nas->alloc(); | |||||
| defer { | |||||
| --nass.next_index; | |||||
| nas->data = nullptr; | |||||
| nas->dealloc(); | |||||
| }; | |||||
| proc debug_step = [&] { | proc debug_step = [&] { | ||||
| return; | return; | ||||
| @@ -671,27 +668,30 @@ namespace Slime { | |||||
| print(lo, true); | print(lo, true); | ||||
| printf("\n "); | printf("\n "); | ||||
| } | } | ||||
| printf("\nnas:\n "); | |||||
| for (auto na : nas) { | |||||
| printf("%s\n ", [&] | |||||
| { | |||||
| switch(na) { | |||||
| case Action::Pop_Environment: return "Pop_Environment"; | |||||
| case Action::Define_Var: return "Define_Var"; | |||||
| case Action::Eval: return "Eval"; | |||||
| case Action::Step: return "Step"; | |||||
| case Action::TM: return "TM"; | |||||
| case Action::Pop: return "Pop"; | |||||
| case Action::If: return "If"; | |||||
| } | |||||
| return "??"; | |||||
| }()); | |||||
| printf("\nnnas:\n "); | |||||
| for (auto nas: nass) { | |||||
| printf("nas:\n "); | |||||
| for (auto na : nas) { | |||||
| printf(" - %s\n ", [&] | |||||
| { | |||||
| switch(na) { | |||||
| case NasAction::Pop_Environment: return "Pop_Environment"; | |||||
| case NasAction::Define_Var: return "Define_Var"; | |||||
| case NasAction::Eval: return "Eval"; | |||||
| case NasAction::Step: return "Step"; | |||||
| case NasAction::TM: return "TM"; | |||||
| case NasAction::Pop: return "Pop"; | |||||
| case NasAction::If: return "If"; | |||||
| } | |||||
| return "??"; | |||||
| }()); | |||||
| } | |||||
| } | } | ||||
| printf("\nams:\n "); | printf("\nams:\n "); | ||||
| for (auto am : ams) { | for (auto am : ams) { | ||||
| printf("%d\n ", am); | printf("%d\n ", am); | ||||
| } | } | ||||
| // pause(); | |||||
| pause(); | |||||
| }; | }; | ||||
| proc push_pc_on_cs = [&] { | proc push_pc_on_cs = [&] { | ||||
| @@ -701,110 +701,24 @@ namespace Slime { | |||||
| pcs.data[pcs.next_index-1] = Memory::nil; | pcs.data[pcs.next_index-1] = Memory::nil; | ||||
| }; | }; | ||||
| proc handle_if = [&] { | |||||
| /* | | | <test> | | |||||
| | | -> | <then> | | |||||
| | <if> | | <else> | | |||||
| | .... | | ...... | */ | |||||
| --ams.next_index; | |||||
| Lisp_Object* args = pcs.data[--pcs.next_index]; | |||||
| Lisp_Object* test = args->value.pair.first; | |||||
| args = args->value.pair.rest; | |||||
| try_void assert_type(args, Lisp_Object_Type::Pair); | |||||
| Lisp_Object* consequence = args->value.pair.first; | |||||
| args = args->value.pair.rest; | |||||
| try_void assert_type(args, Lisp_Object_Type::Pair); | |||||
| Lisp_Object* alternative = args->value.pair.first; | |||||
| args = args->value.pair.rest; | |||||
| try_void assert_type(args, Lisp_Object_Type::Nil); | |||||
| --cs.next_index; | |||||
| cs.append(alternative); | |||||
| cs.append(consequence); | |||||
| cs.append(test); | |||||
| nas.append(Action::Eval); | |||||
| nas.append(Action::If); | |||||
| nas.append(Action::Eval); | |||||
| }; | |||||
| proc handle_define = [&] { | |||||
| --cs.next_index; | |||||
| --ams.next_index; | |||||
| Lisp_Object* form = pcs.data[--pcs.next_index]; | |||||
| Lisp_Object* definee = form->value.pair.first; | |||||
| form = form->value.pair.rest; | |||||
| try_void assert_type(form, Lisp_Object_Type::Pair); | |||||
| Lisp_Object* thing = form->value.pair.first; | |||||
| Lisp_Object* thing_cons = form; | |||||
| form = form->value.pair.rest; | |||||
| Lisp_Object_Type type = Memory::get_type(definee); | |||||
| switch (type) { | |||||
| case Lisp_Object_Type::Symbol: { | |||||
| // BUG(Felix): Defining with doc string crashes | |||||
| if (form != Memory::nil) { | |||||
| Lisp_Object* doc = thing; | |||||
| try_void assert_type(doc, Lisp_Object_Type::String); | |||||
| try_void assert_type(form, Lisp_Object_Type::Pair); | |||||
| form = form->value.pair.rest; | |||||
| thing = form->value.pair.first; | |||||
| try_void assert(form->value.pair.rest == Memory::nil); | |||||
| // TODO docs | |||||
| } | |||||
| cs.append(definee); | |||||
| cs.append(thing); | |||||
| nas.append(Action::Define_Var); | |||||
| nas.append(Action::Eval); | |||||
| } break; | |||||
| case Lisp_Object_Type::Pair: { | |||||
| fflush(stdout); | |||||
| try_void assert_type(definee->value.pair.first, Lisp_Object_Type::Symbol); | |||||
| Lisp_Object* func; | |||||
| try_void func = Memory::create_lisp_object_function(Lisp_Function_Type::Lambda); | |||||
| func->value.function->parent_environment = get_current_environment(); | |||||
| create_arguments_from_lambda_list_and_inject(definee->value.pair.rest, func); | |||||
| func->value.function->body.lisp_body = maybe_wrap_body_in_begin(thing_cons); | |||||
| define_symbol(definee->value.pair.first, func); | |||||
| cs.append(Memory::t); | |||||
| } break; | |||||
| default: { | |||||
| create_generic_error("you can only define symbols"); | |||||
| return; | |||||
| } | |||||
| } | |||||
| }; | |||||
| proc handle_begin = [&] { | |||||
| --cs.next_index; | |||||
| --ams.next_index; | |||||
| Lisp_Object* args = pcs[--pcs.next_index]; | |||||
| int length = list_length(args); | |||||
| cs.reserve(length); | |||||
| for_lisp_list(args) { | |||||
| cs.data[cs.next_index - 1 + (length - it_index)] = it; | |||||
| nas.append(Action::Eval); | |||||
| nas.append(Action::Pop); | |||||
| } | |||||
| --nas.next_index; | |||||
| cs.next_index += length; | |||||
| }; | |||||
| cs.append(expr); | cs.append(expr); | ||||
| nas.append(Action::Eval); | |||||
| nas->append(NasAction::Eval); | |||||
| Action current_action; | |||||
| NasAction current_action; | |||||
| Lisp_Object* pc; | Lisp_Object* pc; | ||||
| while (nas.next_index > 0) { | |||||
| while (nas->next_index > 0) { | |||||
| debug_step(); | debug_step(); | ||||
| current_action = nas.data[--nas.next_index]; | |||||
| current_action = nas->data[--nas->next_index]; | |||||
| switch (current_action) { | switch (current_action) { | ||||
| case Action::Pop: { | |||||
| case NasAction::Pop: { | |||||
| --cs.next_index; | --cs.next_index; | ||||
| } break; | } break; | ||||
| case Action::Pop_Environment: { | |||||
| case NasAction::Pop_Environment: { | |||||
| pop_environment(); | pop_environment(); | ||||
| } break; | } break; | ||||
| case Action::Eval: { | |||||
| case NasAction::Eval: { | |||||
| pc = cs.data[cs.next_index-1]; | pc = cs.data[cs.next_index-1]; | ||||
| Lisp_Object_Type type = Memory::get_type(pc); | Lisp_Object_Type type = Memory::get_type(pc); | ||||
| switch (type) { | switch (type) { | ||||
| @@ -815,8 +729,8 @@ namespace Slime { | |||||
| cs.data[cs.next_index-1] = pc->value.pair.first; | cs.data[cs.next_index-1] = pc->value.pair.first; | ||||
| ams.append(cs.next_index-1); | ams.append(cs.next_index-1); | ||||
| pcs.append(pc->value.pair.rest); | pcs.append(pc->value.pair.rest); | ||||
| nas.append(Action::TM); | |||||
| nas.append(Action::Eval); | |||||
| nas->append(NasAction::TM); | |||||
| nas->append(NasAction::Eval); | |||||
| } break; | } break; | ||||
| default: { | default: { | ||||
| // NOTE(Felix): others are self evaluating | // NOTE(Felix): others are self evaluating | ||||
| @@ -824,35 +738,34 @@ namespace Slime { | |||||
| } | } | ||||
| } | } | ||||
| } break; | } break; | ||||
| case Action::TM: { | |||||
| case NasAction::TM: { | |||||
| pc = cs.data[cs.next_index-1]; | pc = cs.data[cs.next_index-1]; | ||||
| Lisp_Object_Type type = Memory::get_type(pc); | Lisp_Object_Type type = Memory::get_type(pc); | ||||
| switch (type) { | switch (type) { | ||||
| case Lisp_Object_Type::Function: { | case Lisp_Object_Type::Function: { | ||||
| if(pc->value.function->is_c) { | if(pc->value.function->is_c) { | ||||
| if (pc->value.function->type.c_function_type == | |||||
| C_Function_Type::cMacro) | |||||
| if (pc->value.function->type.c_function_type == C_Function_Type::cMacro) { | |||||
| try pc->value.function->body.c_macro_body(); | |||||
| } else if(pc->value.function->type.c_function_type == C_Function_Type::cSpecial) | |||||
| { | { | ||||
| if (pc == Memory::_if) try handle_if(); | |||||
| else if (pc == Memory::_begin) try handle_begin(); | |||||
| else if (pc == Memory::_define) try handle_define(); | |||||
| else { | |||||
| push_pc_on_cs(); | |||||
| nas.append(Action::Step); | |||||
| } | |||||
| // TODO(Felix): Why not call the function | |||||
| // right away, and instead push step, so | |||||
| // that step calls it? | |||||
| push_pc_on_cs(); | |||||
| nas->append(NasAction::Step); | |||||
| } else { | } else { | ||||
| nas.append(Action::Step); | |||||
| nas->append(NasAction::Step); | |||||
| } | } | ||||
| } else { | } else { | ||||
| if (pc->value.function->type.lisp_function_type == | if (pc->value.function->type.lisp_function_type == | ||||
| Lisp_Function_Type::Macro) | Lisp_Function_Type::Macro) | ||||
| { | { | ||||
| push_pc_on_cs(); | push_pc_on_cs(); | ||||
| nas.append(Action::Eval); | |||||
| nas.append(Action::Step); | |||||
| nas->append(NasAction::Eval); | |||||
| nas->append(NasAction::Step); | |||||
| } else { | } else { | ||||
| nas.append(Action::Step); | |||||
| nas->append(NasAction::Step); | |||||
| } | } | ||||
| } | } | ||||
| } break; | } break; | ||||
| @@ -864,7 +777,7 @@ namespace Slime { | |||||
| } | } | ||||
| } break; | } break; | ||||
| case Action::Step: { | |||||
| case NasAction::Step: { | |||||
| if (pcs.data[pcs.next_index-1] == Memory::nil) { | if (pcs.data[pcs.next_index-1] == Memory::nil) { | ||||
| --pcs.next_index; | --pcs.next_index; | ||||
| int am = ams.data[--ams.next_index]; | int am = ams.data[--ams.next_index]; | ||||
| @@ -876,21 +789,24 @@ namespace Slime { | |||||
| cs.next_index = am; | cs.next_index = am; | ||||
| push_environment(extended_env); | push_environment(extended_env); | ||||
| if (function->value.function->is_c) { | if (function->value.function->is_c) { | ||||
| try cs.append(function->value.function->body.c_body()); | |||||
| if (function->value.function->type.c_function_type == C_Function_Type::cMacro) | |||||
| try function->value.function->body.c_macro_body(); | |||||
| else | |||||
| try cs.append(function->value.function->body.c_body()); | |||||
| pop_environment(); | pop_environment(); | ||||
| } else { | } else { | ||||
| nas.append(Action::Pop_Environment); | |||||
| nas.append(Action::Eval); | |||||
| nas->append(NasAction::Pop_Environment); | |||||
| nas->append(NasAction::Eval); | |||||
| cs.append(function->value.function->body.lisp_body); | cs.append(function->value.function->body.lisp_body); | ||||
| } | } | ||||
| } else { | } else { | ||||
| cs.append(pcs.data[pcs.next_index-1]->value.pair.first); | cs.append(pcs.data[pcs.next_index-1]->value.pair.first); | ||||
| pcs.data[pcs.next_index-1] = pcs.data[pcs.next_index-1]->value.pair.rest; | pcs.data[pcs.next_index-1] = pcs.data[pcs.next_index-1]->value.pair.rest; | ||||
| nas.append(Action::Step); | |||||
| nas.append(Action::Eval); | |||||
| nas->append(NasAction::Step); | |||||
| nas->append(NasAction::Eval); | |||||
| } | } | ||||
| } break; | } break; | ||||
| case Action::If: { | |||||
| case NasAction::If: { | |||||
| /* | <cond> | | /* | <cond> | | ||||
| | <then> | | | <then> | | ||||
| | <else> | | | <else> | | ||||
| @@ -903,7 +819,7 @@ namespace Slime { | |||||
| cs.data[cs.next_index-1] = cs.data[cs.next_index]; | cs.data[cs.next_index-1] = cs.data[cs.next_index]; | ||||
| } | } | ||||
| } break; | } break; | ||||
| case Action::Define_Var: { | |||||
| case NasAction::Define_Var: { | |||||
| /* | <thing> | | /* | <thing> | | ||||
| | <symbol> | | | <symbol> | | ||||
| | .... | */ | | .... | */ | ||||
| @@ -4,9 +4,10 @@ namespace Slime::Globals { | |||||
| Array_List<void*> load_path; | Array_List<void*> load_path; | ||||
| namespace Current_Execution { | namespace Current_Execution { | ||||
| Array_List<Lisp_Object*> cs; | |||||
| Array_List<Lisp_Object*> pcs; | |||||
| Array_List<int> ams; | |||||
| Array_List<Lisp_Object*> cs; | |||||
| Array_List<Lisp_Object*> pcs; | |||||
| Array_List<int> ams; | |||||
| Array_List<Array_List<NasAction>> nass; | |||||
| // Array_List<Lisp_Object*> call_stack; | // Array_List<Lisp_Object*> call_stack; | ||||
| Array_List<Environment*> envi_stack; | Array_List<Environment*> envi_stack; | ||||
| } | } | ||||
| @@ -181,6 +181,7 @@ namespace Slime::Memory { | |||||
| // Globals::Current_Execution::call_stack.alloc(); | // Globals::Current_Execution::call_stack.alloc(); | ||||
| Globals::Current_Execution::envi_stack.alloc(); | Globals::Current_Execution::envi_stack.alloc(); | ||||
| Globals::Current_Execution::cs.alloc(); | Globals::Current_Execution::cs.alloc(); | ||||
| Globals::Current_Execution::nass.alloc(); | |||||
| Globals::Current_Execution::pcs.alloc(); | Globals::Current_Execution::pcs.alloc(); | ||||
| Globals::Current_Execution::ams.alloc(); | Globals::Current_Execution::ams.alloc(); | ||||
| @@ -211,9 +212,9 @@ namespace Slime::Memory { | |||||
| try_void user_env = Memory::create_child_environment(env); | try_void user_env = Memory::create_child_environment(env); | ||||
| push_environment(user_env); | push_environment(user_env); | ||||
| try_void _if = lookup_symbol(get_symbol("if"), env); | |||||
| /* try_void _if = lookup_symbol(get_symbol("if"), env); | |||||
| try_void _define = lookup_symbol(get_symbol("define"), env); | try_void _define = lookup_symbol(get_symbol("define"), env); | ||||
| try_void _begin = lookup_symbol(get_symbol("begin"), env); | |||||
| try_void _begin = lookup_symbol(get_symbol("begin"), env);*/ | |||||
| } | } | ||||
| proc reset() -> void { | proc reset() -> void { | ||||
| @@ -499,7 +500,7 @@ namespace Slime::Memory { | |||||
| }; | }; | ||||
| try load_built_ins_into_environment(); | try load_built_ins_into_environment(); | ||||
| try built_in_load(Memory::create_string("pre.slime")); | |||||
| // try built_in_load(Memory::create_string("pre.slime")); | |||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -31,11 +31,22 @@ namespace Slime { | |||||
| Under_Construction = 1 << 6, | Under_Construction = 1 << 6, | ||||
| }; | }; | ||||
| enum struct NasAction { | |||||
| Eval, | |||||
| Step, | |||||
| TM, | |||||
| Pop, | |||||
| If, | |||||
| Define_Var, | |||||
| Pop_Environment | |||||
| }; | |||||
| enum struct Lisp_Function_Type { | enum struct Lisp_Function_Type { | ||||
| Lambda, // normal evaluation order | Lambda, // normal evaluation order | ||||
| Macro // args are not evaluated, a new programm is returned | Macro // args are not evaluated, a new programm is returned | ||||
| // that will be executed again | // that will be executed again | ||||
| }; | }; | ||||
| enum struct C_Function_Type { | enum struct C_Function_Type { | ||||
| cFunction, // normal evaluation order | cFunction, // normal evaluation order | ||||
| cSpecial, // args are not evaluated, but result is returned | cSpecial, // args are not evaluated, but result is returned | ||||
| @@ -118,6 +129,7 @@ namespace Slime { | |||||
| union { | union { | ||||
| Lisp_Object* lisp_body; | Lisp_Object* lisp_body; | ||||
| Lisp_Object* (*c_body)(); | Lisp_Object* (*c_body)(); | ||||
| void (*c_macro_body)(); | |||||
| } body; | } body; | ||||
| }; | }; | ||||
| @@ -620,17 +620,17 @@ namespace Slime { | |||||
| // pop_environment(); | // pop_environment(); | ||||
| printf("\n-- Test Files --\n"); | printf("\n-- Test Files --\n"); | ||||
| // invoke_test_script("evaluation_of_default_args"); | |||||
| // invoke_test_script("alists"); | |||||
| // invoke_test_script("case_and_cond"); | |||||
| // invoke_test_script("lexical_scope"); | |||||
| // invoke_test_script("class_macro"); | |||||
| // invoke_test_script("import_and_load"); | |||||
| // invoke_test_script("macro_expand"); | |||||
| // invoke_test_script("automata"); | |||||
| invoke_test_script("evaluation_of_default_args"); | |||||
| invoke_test_script("alists"); | |||||
| invoke_test_script("case_and_cond"); | |||||
| invoke_test_script("lexical_scope"); | |||||
| invoke_test_script("class_macro"); | |||||
| invoke_test_script("import_and_load"); | |||||
| invoke_test_script("macro_expand"); | |||||
| invoke_test_script("automata"); | |||||
| invoke_test_script("sicp"); | invoke_test_script("sicp"); | ||||
| // invoke_test_script("hashmaps"); | |||||
| // invoke_test_script("singular_imports"); | |||||
| invoke_test_script("hashmaps"); | |||||
| invoke_test_script("singular_imports"); | |||||
| return result; | return result; | ||||
| } | } | ||||
| @@ -30,45 +30,45 @@ | |||||
| <VCProjectVersion>15.0</VCProjectVersion> | <VCProjectVersion>15.0</VCProjectVersion> | ||||
| <ProjectGuid>{1A47A3ED-871F-4CB4-875B-8CAA385B1771}</ProjectGuid> | <ProjectGuid>{1A47A3ED-871F-4CB4-875B-8CAA385B1771}</ProjectGuid> | ||||
| <RootNamespace>slime</RootNamespace> | <RootNamespace>slime</RootNamespace> | ||||
| <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion> | |||||
| <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | |||||
| <ProjectName>slime</ProjectName> | <ProjectName>slime</ProjectName> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||||
| <ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
| <UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
| <PlatformToolset>v141</PlatformToolset> | |||||
| <PlatformToolset>v142</PlatformToolset> | |||||
| <CharacterSet>MultiByte</CharacterSet> | <CharacterSet>MultiByte</CharacterSet> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='run tests|Win32'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='run tests|Win32'" Label="Configuration"> | ||||
| <ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
| <UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
| <PlatformToolset>v141</PlatformToolset> | |||||
| <PlatformToolset>v142</PlatformToolset> | |||||
| <CharacterSet>MultiByte</CharacterSet> | <CharacterSet>MultiByte</CharacterSet> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||||
| <ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
| <UseDebugLibraries>false</UseDebugLibraries> | <UseDebugLibraries>false</UseDebugLibraries> | ||||
| <PlatformToolset>v141</PlatformToolset> | |||||
| <PlatformToolset>v142</PlatformToolset> | |||||
| <WholeProgramOptimization>true</WholeProgramOptimization> | <WholeProgramOptimization>true</WholeProgramOptimization> | ||||
| <CharacterSet>MultiByte</CharacterSet> | <CharacterSet>MultiByte</CharacterSet> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | ||||
| <ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
| <UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
| <PlatformToolset>v141</PlatformToolset> | |||||
| <PlatformToolset>v142</PlatformToolset> | |||||
| <CharacterSet>MultiByte</CharacterSet> | <CharacterSet>MultiByte</CharacterSet> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='run tests|x64'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='run tests|x64'" Label="Configuration"> | ||||
| <ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
| <UseDebugLibraries>true</UseDebugLibraries> | <UseDebugLibraries>true</UseDebugLibraries> | ||||
| <PlatformToolset>v141</PlatformToolset> | |||||
| <PlatformToolset>v142</PlatformToolset> | |||||
| <CharacterSet>MultiByte</CharacterSet> | <CharacterSet>MultiByte</CharacterSet> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | ||||
| <ConfigurationType>Application</ConfigurationType> | <ConfigurationType>Application</ConfigurationType> | ||||
| <UseDebugLibraries>false</UseDebugLibraries> | <UseDebugLibraries>false</UseDebugLibraries> | ||||
| <PlatformToolset>v141</PlatformToolset> | |||||
| <PlatformToolset>v142</PlatformToolset> | |||||
| <WholeProgramOptimization>true</WholeProgramOptimization> | <WholeProgramOptimization>true</WholeProgramOptimization> | ||||
| <CharacterSet>MultiByte</CharacterSet> | <CharacterSet>MultiByte</CharacterSet> | ||||
| </PropertyGroup> | </PropertyGroup> | ||||
| @@ -98,6 +98,13 @@ | |||||
| <PropertyGroup Label="UserMacros" /> | <PropertyGroup Label="UserMacros" /> | ||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='run tests|x64'"> | <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='run tests|x64'"> | ||||
| <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> | <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> | ||||
| <IncludePath>$(SolutionDir)..\3rd;$(IncludePath)</IncludePath> | |||||
| </PropertyGroup> | |||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |||||
| <IncludePath>$(SolutionDir)..\3rd;$(IncludePath)</IncludePath> | |||||
| </PropertyGroup> | |||||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||||
| <IncludePath>$(SolutionDir)..\3rd;$(IncludePath)</IncludePath> | |||||
| </PropertyGroup> | </PropertyGroup> | ||||
| <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
| <ClCompile> | <ClCompile> | ||||