瀏覽代碼

singulat t and nil

master
Felix Brendel 7 年之前
父節點
當前提交
1bd77be7f6
共有 7 個文件被更改,包括 164 次插入109 次删除
  1. +7
    -6
      build.sh
  2. +49
    -49
      src/built_ins.cpp
  3. +2
    -2
      src/env.cpp
  4. +10
    -14
      src/eval.cpp
  5. +46
    -25
      src/memory.cpp
  6. +13
    -13
      src/parse.cpp
  7. +37
    -0
      src/testing.cpp

+ 7
- 6
build.sh 查看文件

@@ -1,12 +1,13 @@
TIMEFORMAT=%3lR
SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
pushd $SCRIPTPATH/src > /dev/null
pushd $SCRIPTPATH > /dev/null


clang++ main.cpp -g -o ../bin/slime --std=c++17 || exit 1
time clang++ src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1


echo "" echo ""
echo "--- Output Start ---"
pushd ../bin > /dev/null
./slime --run-tests
pushd ./bin > /dev/null
time ./slime --run-tests
popd > /dev/null popd > /dev/null
echo "--- Output End ---"
popd > /dev/null popd > /dev/null
unset TIMEFORMAT

+ 49
- 49
src/built_ins.cpp 查看文件

@@ -43,7 +43,7 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* { proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* {
char* file_content = read_entire_file(Memory::get_c_str(file_name)); char* file_content = read_entire_file(Memory::get_c_str(file_name));
if (file_content) { if (file_content) {
Lisp_Object* result = Memory::create_lisp_object_nil();
Lisp_Object* result = Memory::nil;
Lisp_Object_Array_List* program; Lisp_Object_Array_List* program;
try { try {
program = Parser::parse_program(file_name, file_content); program = Parser::parse_program(file_name, file_content);
@@ -72,7 +72,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {


proc defun = [&](const char* name, auto fun) { proc defun = [&](const char* name, auto fun) {
define_symbol( define_symbol(
Memory::create_lisp_object_symbol(name),
Memory::get_or_create_lisp_object_symbol(name),
Memory::create_lisp_object_cfunction(fun), Memory::create_lisp_object_cfunction(fun),
env); env);
}; };
@@ -84,17 +84,17 @@ proc load_built_ins_into_environment(Environment* env) -> void {
} }


if (arguments->type == Lisp_Object_Type::Nil) if (arguments->type == Lisp_Object_Type::Nil)
return Memory::create_lisp_object_t();
return Memory::t;


Lisp_Object* first = arguments->value.pair->first; Lisp_Object* first = arguments->value.pair->first;


while (arguments->type == Lisp_Object_Type::Pair) { while (arguments->type == Lisp_Object_Type::Pair) {
if (!lisp_object_equal(arguments->value.pair->first, first)) if (!lisp_object_equal(arguments->value.pair->first, first))
return Memory::create_lisp_object_nil();
return Memory::nil;
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;
} }


return Memory::create_lisp_object_t();
return Memory::t;
}); });
defun(">", cLambda { defun(">", cLambda {
int arguments_length; int arguments_length;
@@ -110,13 +110,13 @@ proc load_built_ins_into_environment(Environment* env) -> void {
} }


if (arguments->value.pair->first->value.number->value >= last_number) if (arguments->value.pair->first->value.number->value >= last_number)
return Memory::create_lisp_object_nil();
return Memory::nil;


last_number = arguments->value.pair->first->value.number->value; last_number = arguments->value.pair->first->value.number->value;
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;
} }


return Memory::create_lisp_object_t();
return Memory::t;
}); });
defun(">=", cLambda { defun(">=", cLambda {
int arguments_length; int arguments_length;
@@ -132,13 +132,13 @@ proc load_built_ins_into_environment(Environment* env) -> void {
} }


if (arguments->value.pair->first->value.number->value > last_number) if (arguments->value.pair->first->value.number->value > last_number)
return Memory::create_lisp_object_nil();
return Memory::nil;


last_number = arguments->value.pair->first->value.number->value; last_number = arguments->value.pair->first->value.number->value;
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;
} }


return Memory::create_lisp_object_t();
return Memory::t;
}); });
defun("<", cLambda { defun("<", cLambda {
int arguments_length; int arguments_length;
@@ -154,13 +154,13 @@ proc load_built_ins_into_environment(Environment* env) -> void {
} }


if (arguments->value.pair->first->value.number->value <= last_number) if (arguments->value.pair->first->value.number->value <= last_number)
return Memory::create_lisp_object_nil();
return Memory::nil;


last_number = arguments->value.pair->first->value.number->value; last_number = arguments->value.pair->first->value.number->value;
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;
} }


return Memory::create_lisp_object_t();
return Memory::t;
}); });
defun("<=", cLambda { defun("<=", cLambda {
int arguments_length; int arguments_length;
@@ -176,13 +176,13 @@ proc load_built_ins_into_environment(Environment* env) -> void {
} }


if (arguments->value.pair->first->value.number->value < last_number) if (arguments->value.pair->first->value.number->value < last_number)
return Memory::create_lisp_object_nil();
return Memory::nil;


last_number = arguments->value.pair->first->value.number->value; last_number = arguments->value.pair->first->value.number->value;
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;
} }


return Memory::create_lisp_object_t();
return Memory::t;
}); });
defun("+", cLambda { defun("+", cLambda {
int arguments_length; int arguments_length;
@@ -407,7 +407,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
try { try {
result = eval_expr(else_part->value.pair->first, env); result = eval_expr(else_part->value.pair->first, env);
} }
else return Memory::create_lisp_object_nil();
else return Memory::nil;
return result; return result;
}); });
defun("quote", cLambda { defun("quote", cLambda {
@@ -474,7 +474,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
newPairHead = newPairHead->value.pair->rest; newPairHead = newPairHead->value.pair->rest;
head = head->value.pair->rest; head = head->value.pair->rest;
} }
newPairHead->value.pair->rest = Memory::create_lisp_object_nil();
newPairHead->value.pair->rest = Memory::nil;


return newPair; return newPair;
}; };
@@ -496,10 +496,10 @@ proc load_built_ins_into_environment(Environment* env) -> void {
} }
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;


if (!result) return Memory::create_lisp_object_nil();
if (!result) return Memory::nil;
} }


return Memory::create_lisp_object_t();
return Memory::t;
}); });
defun("or", cLambda { defun("or", cLambda {
bool result = false; bool result = false;
@@ -512,10 +512,10 @@ proc load_built_ins_into_environment(Environment* env) -> void {
} }
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;


if (result) return Memory::create_lisp_object_t();
if (result) return Memory::t;
} }


return Memory::create_lisp_object_nil();
return Memory::nil;
}); });
defun("not", cLambda { defun("not", cLambda {
try { try {
@@ -530,8 +530,8 @@ proc load_built_ins_into_environment(Environment* env) -> void {
truthy = is_truthy(arguments->value.pair->first, env); truthy = is_truthy(arguments->value.pair->first, env);
} }
if (truthy) if (truthy)
return Memory::create_lisp_object_nil();
return Memory::create_lisp_object_t();
return Memory::nil;
return Memory::t;
}); });
defun("while", cLambda { defun("while", cLambda {
try { try {
@@ -544,7 +544,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
Lisp_Object* condition_part = arguments->value.pair->first; Lisp_Object* condition_part = arguments->value.pair->first;
Lisp_Object* condition; Lisp_Object* condition;
Lisp_Object* then_part = arguments->value.pair->rest; Lisp_Object* then_part = arguments->value.pair->rest;
Lisp_Object* result = Memory::create_lisp_object_nil();
Lisp_Object* result = Memory::nil;


while (true) { while (true) {
try { try {
@@ -659,7 +659,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
// we are now in the function body, just wrap it in an // we are now in the function body, just wrap it in an
// implicit prog // implicit prog
function->body = Memory::create_lisp_object_pair( function->body = Memory::create_lisp_object_pair(
Memory::create_lisp_object_symbol("prog"),
Memory::get_or_create_lisp_object_symbol("prog"),
arguments); arguments);


Lisp_Object* ret = Memory::create_lisp_object(); Lisp_Object* ret = Memory::create_lisp_object();
@@ -709,7 +709,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
// we are now in the function body, just wrap it in an // we are now in the function body, just wrap it in an
// implicit prog // implicit prog
function->body = Memory::create_lisp_object_pair( function->body = Memory::create_lisp_object_pair(
Memory::create_lisp_object_symbol("prog"),
Memory::get_or_create_lisp_object_symbol("prog"),
arguments); arguments);


Lisp_Object* ret = Memory::create_lisp_object(); Lisp_Object* ret = Memory::create_lisp_object();
@@ -774,7 +774,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
report_error(Error_Type::Wrong_Number_Of_Arguments); report_error(Error_Type::Wrong_Number_Of_Arguments);
} }
if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil) if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil)
return Memory::create_lisp_object_nil();
return Memory::nil;
if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::Pair) if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::Pair)
report_error(Error_Type::Type_Missmatch); report_error(Error_Type::Type_Missmatch);


@@ -788,7 +788,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
report_error(Error_Type::Wrong_Number_Of_Arguments); report_error(Error_Type::Wrong_Number_Of_Arguments);
} }
if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil) if (evaluated_arguments->value.pair->first->type == Lisp_Object_Type::Nil)
return Memory::create_lisp_object_nil();
return Memory::nil;
if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::Pair) if (evaluated_arguments->value.pair->first->type != Lisp_Object_Type::Pair)
report_error(Error_Type::Type_Missmatch); report_error(Error_Type::Type_Missmatch);


@@ -821,7 +821,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
report_error(Error_Type::Wrong_Number_Of_Arguments); report_error(Error_Type::Wrong_Number_Of_Arguments);
} }
evaluated_arguments->value.pair->first->userType = nullptr; evaluated_arguments->value.pair->first->userType = nullptr;
return Memory::create_lisp_object_t();
return Memory::t;
}); });
defun("type", cLambda { defun("type", cLambda {
try { try {
@@ -837,26 +837,26 @@ proc load_built_ins_into_environment(Environment* env) -> void {


Lisp_Object_Type type = evaluated_arguments->value.pair->first->type; Lisp_Object_Type type = evaluated_arguments->value.pair->first->type;
switch (type) { switch (type) {
case Lisp_Object_Type::CFunction: return Memory::create_lisp_object_keyword("cfunction");
case Lisp_Object_Type::CFunction: return Memory::get_or_create_lisp_object_keyword("cfunction");
case Lisp_Object_Type::Function: { case Lisp_Object_Type::Function: {
Function* fun = evaluated_arguments->value.pair->first->value.function; Function* fun = evaluated_arguments->value.pair->first->value.function;
if (fun->type == Function_Type::Lambda) if (fun->type == Function_Type::Lambda)
return Memory::create_lisp_object_keyword("lambda");
return Memory::get_or_create_lisp_object_keyword("lambda");
else if (fun->type == Function_Type::Special_Lambda) else if (fun->type == Function_Type::Special_Lambda)
return Memory::create_lisp_object_keyword("special-lambda");
return Memory::get_or_create_lisp_object_keyword("special-lambda");
else if (fun->type == Function_Type::Macro) else if (fun->type == Function_Type::Macro)
return Memory::create_lisp_object_keyword("macro");
else return Memory::create_lisp_object_keyword("unknown");
}
case Lisp_Object_Type::Keyword: return Memory::create_lisp_object_keyword("keyword");
case Lisp_Object_Type::Nil: return Memory::create_lisp_object_keyword("nil");
case Lisp_Object_Type::T: return Memory::create_lisp_object_keyword("t");
case Lisp_Object_Type::Number: return Memory::create_lisp_object_keyword("number");
case Lisp_Object_Type::Pair: return Memory::create_lisp_object_keyword("pair");
case Lisp_Object_Type::String: return Memory::create_lisp_object_keyword("string");
case Lisp_Object_Type::Symbol: return Memory::create_lisp_object_keyword("symbol");
}
return Memory::create_lisp_object_keyword("unknown");
return Memory::get_or_create_lisp_object_keyword("macro");
else return Memory::get_or_create_lisp_object_keyword("unknown");
}
case Lisp_Object_Type::Keyword: return Memory::get_or_create_lisp_object_keyword("keyword");
case Lisp_Object_Type::Nil: return Memory::get_or_create_lisp_object_keyword("nil");
case Lisp_Object_Type::T: return Memory::get_or_create_lisp_object_keyword("t");
case Lisp_Object_Type::Number: return Memory::get_or_create_lisp_object_keyword("number");
case Lisp_Object_Type::Pair: return Memory::get_or_create_lisp_object_keyword("pair");
case Lisp_Object_Type::String: return Memory::get_or_create_lisp_object_keyword("string");
case Lisp_Object_Type::Symbol: return Memory::get_or_create_lisp_object_keyword("symbol");
}
return Memory::get_or_create_lisp_object_keyword("unknown");
}); });
defun("info", cLambda { defun("info", cLambda {
try { try {
@@ -871,8 +871,8 @@ proc load_built_ins_into_environment(Environment* env) -> void {


Lisp_Object* type = eval_expr( Lisp_Object* type = eval_expr(
Memory::create_lisp_object_pair( Memory::create_lisp_object_pair(
Memory::create_lisp_object_symbol("type"),
Memory::create_lisp_object_pair(arguments->value.pair->first, Memory::create_lisp_object_nil())),
Memory::get_or_create_lisp_object_symbol("type"),
Memory::create_lisp_object_pair(arguments->value.pair->first, Memory::nil)),
env); env);


if (type) { if (type) {
@@ -936,7 +936,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
delete_error(); delete_error();
} }


return Memory::create_lisp_object_nil();
return Memory::nil;
}); });
defun("print", cLambda { defun("print", cLambda {
try { try {
@@ -947,7 +947,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
} }
print(evaluated_arguments->value.pair->first); print(evaluated_arguments->value.pair->first);
// printf("\n"); // printf("\n");
return Memory::create_lisp_object_nil();
return Memory::nil;
}); });
defun("read", cLambda { defun("read", cLambda {
try { try {
@@ -991,11 +991,11 @@ proc load_built_ins_into_environment(Environment* env) -> void {
defun("break", cLambda { defun("break", cLambda {
print_environment(env); print_environment(env);
debug_break(); debug_break();
return Memory::create_lisp_object_nil();
return Memory::nil;
}); });
defun("memstat", cLambda { defun("memstat", cLambda {
Memory::print_status(); Memory::print_status();
return Memory::create_lisp_object_nil();
return Memory::nil;
}); });
defun("try", cLambda { defun("try", cLambda {
try { try {
@@ -1089,7 +1089,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
report_error(Error_Type::Type_Missmatch); report_error(Error_Type::Type_Missmatch);
} }


return Memory::create_lisp_object_symbol(Memory::duplicate_string(source->value.string));
return Memory::get_or_create_lisp_object_symbol(Memory::duplicate_string(source->value.string));
}); });
defun("symbol->string", cLambda { defun("symbol->string", cLambda {
try { try {


+ 2
- 2
src/env.cpp 查看文件

@@ -39,10 +39,10 @@ proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
} }


if (string_equal(Memory::get_c_str(sym->identifier), "nil")) { if (string_equal(Memory::get_c_str(sym->identifier), "nil")) {
return Memory::create_lisp_object_nil();
return Memory::nil;
} }
if (string_equal(Memory::get_c_str(sym->identifier), "t")) { if (string_equal(Memory::get_c_str(sym->identifier), "t")) {
return Memory::create_lisp_object_t();
return Memory::t;
} }


create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation); create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation);


+ 10
- 14
src/eval.cpp 查看文件

@@ -8,7 +8,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
// their identifiers but before we converted them to // their identifiers but before we converted them to
// strings from symbols... Wo maybe just use the symbols? // strings from symbols... Wo maybe just use the symbols?
define_symbol( define_symbol(
Memory::create_lisp_object_symbol(function->positional_arguments->identifiers[i]),
Memory::get_or_create_lisp_object_symbol(function->positional_arguments->identifiers[i]),
arguments->value.pair->first, new_env); arguments->value.pair->first, new_env);
} else { } else {


@@ -69,7 +69,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->


// if not set it and then add it to the array list // if not set it and then add it to the array list
define_symbol( define_symbol(
Memory::create_lisp_object_symbol(arguments->value.pair->first->value.keyword->identifier),
Memory::get_or_create_lisp_object_symbol(arguments->value.pair->first->value.keyword->identifier),
arguments->value.pair->rest->value.pair->first, arguments->value.pair->rest->value.pair->first,
new_env); new_env);


@@ -108,7 +108,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
// to use it or if the user supplied his own // to use it or if the user supplied his own
if (!was_set) { if (!was_set) {
define_symbol( define_symbol(
Memory::create_lisp_object_symbol(defined_keyword),
Memory::get_or_create_lisp_object_symbol(defined_keyword),
Memory::copy_lisp_object(function->keyword_arguments->values->data[i]), new_env); Memory::copy_lisp_object(function->keyword_arguments->values->data[i]), new_env);
} }
} }
@@ -118,13 +118,13 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
if (arguments->type == Lisp_Object_Type::Nil) { if (arguments->type == Lisp_Object_Type::Nil) {
if (function->rest_argument) { if (function->rest_argument) {
define_symbol( define_symbol(
Memory::create_lisp_object_symbol(function->rest_argument),
Memory::create_lisp_object_nil(), new_env);
Memory::get_or_create_lisp_object_symbol(function->rest_argument),
Memory::nil, new_env);
} }
} else { } else {
if (function->rest_argument) { if (function->rest_argument) {
define_symbol( define_symbol(
Memory::create_lisp_object_symbol(function->rest_argument),
Memory::get_or_create_lisp_object_symbol(function->rest_argument),
arguments, new_env); arguments, new_env);
} else { } else {
// rest was not declared but additional arguments were found // rest was not declared but additional arguments were found
@@ -353,12 +353,12 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
return nullptr; \ return nullptr; \
} }


if (error)
return nullptr;

switch (node->type) { switch (node->type) {
case Lisp_Object_Type::T: case Lisp_Object_Type::T:
case Lisp_Object_Type::Nil: case Lisp_Object_Type::Nil:
case Lisp_Object_Type::Number:
case Lisp_Object_Type::Keyword:
case Lisp_Object_Type::String:
return node; return node;
case Lisp_Object_Type::Symbol: { case Lisp_Object_Type::Symbol: {
Lisp_Object* symbol; Lisp_Object* symbol;
@@ -367,10 +367,6 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
} }
return symbol; return symbol;
} }
case Lisp_Object_Type::Number:
case Lisp_Object_Type::Keyword:
case Lisp_Object_Type::String:
return node;
case Lisp_Object_Type::Pair: { case Lisp_Object_Type::Pair: {
Lisp_Object* lispOperator; Lisp_Object* lispOperator;
if (node->value.pair->first->type != Lisp_Object_Type::CFunction && if (node->value.pair->first->type != Lisp_Object_Type::CFunction &&
@@ -448,7 +444,7 @@ proc interprete_file (char* file_name) -> Lisp_Object* {
Memory::create_string(file_name), file_content); Memory::create_string(file_name), file_content);
} }


Lisp_Object* result = Memory::create_lisp_object_nil();
Lisp_Object* result = Memory::nil;
for (int i = 0; i < program->next_index; ++i) { for (int i = 0; i < program->next_index; ++i) {
try { try {
result = eval_expr(program->data[i], env); result = eval_expr(program->data[i], env);


+ 46
- 25
src/memory.cpp 查看文件

@@ -19,15 +19,12 @@ namespace Memory {
String* string_memory; String* string_memory;
String* next_free_spot_in_string_memory; String* next_free_spot_in_string_memory;


proc init() {
free_spots_in_object_memory = create_Int_array_list();
free_spots_in_string_memory = create_Void_Ptr_array_list();


object_memory = (Lisp_Object*)malloc(object_memory_size * sizeof(Lisp_Object));
string_memory = (String*)malloc(object_memory_size * sizeof(Lisp_Object));
next_free_spot_in_string_memory = string_memory;
}
// ------------------
// immutables
// ------------------
Lisp_Object* nil = nullptr;
Lisp_Object* t = nullptr;


proc print_status() { proc print_status() {
printf("Memory Status:\n" printf("Memory Status:\n"
@@ -99,20 +96,40 @@ namespace Memory {
return object; return object;
} }


proc create_lisp_object_nil() -> Lisp_Object* {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Nil;
node->value.pair = nullptr;
return node;
}
proc init() {
free_spots_in_object_memory = create_Int_array_list();
free_spots_in_string_memory = create_Void_Ptr_array_list();


proc create_lisp_object_t() -> Lisp_Object* {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::T;
node->value.pair = nullptr;
return node;
object_memory = (Lisp_Object*)malloc(object_memory_size * sizeof(Lisp_Object));
string_memory = (String*)malloc(object_memory_size * sizeof(Lisp_Object));

next_free_spot_in_string_memory = string_memory;

// init nil
nil = create_lisp_object();
nil->type = Lisp_Object_Type::Nil;
nil->value.pair = nullptr;

// init t
t = create_lisp_object();
t->type = Lisp_Object_Type::T;
t->value.pair = nullptr;
} }


// proc get_lisp_object_nil() -> Lisp_Object* {
// Lisp_Object* node = create_lisp_object();
// node->type = Lisp_Object_Type::Nil;
// node->value.pair = nullptr;
// return node;
// }

// proc get_lisp_object_t() -> Lisp_Object* {
// Lisp_Object* node = create_lisp_object();
// node->type = Lisp_Object_Type::T;
// node->value.pair = nullptr;
// return node;
// }

proc create_lisp_object_number(double number) -> Lisp_Object* { proc create_lisp_object_number(double number) -> Lisp_Object* {
Lisp_Object* node = create_lisp_object(); Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Number; node->type = Lisp_Object_Type::Number;
@@ -128,7 +145,9 @@ namespace Memory {
return node; return node;
} }


proc create_lisp_object_symbol(String* identifier) -> Lisp_Object* {
proc get_or_create_lisp_object_symbol(String* identifier) -> Lisp_Object* {
// TODO(Felix): if we already have it stored somewhere then
// reuse it and dont create new one
Lisp_Object* node = create_lisp_object(); Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Symbol; node->type = Lisp_Object_Type::Symbol;
node->value.symbol = new(Symbol); node->value.symbol = new(Symbol);
@@ -136,12 +155,14 @@ namespace Memory {
return node; return node;
} }


proc create_lisp_object_symbol(const char* identifier) -> Lisp_Object* {
return create_lisp_object_symbol(
proc get_or_create_lisp_object_symbol(const char* identifier) -> Lisp_Object* {
return get_or_create_lisp_object_symbol(
Memory::create_string(identifier)); Memory::create_string(identifier));
} }


proc create_lisp_object_keyword(String* keyword) -> Lisp_Object* {
proc get_or_create_lisp_object_keyword(String* keyword) -> Lisp_Object* {
// TODO(Felix): if we already have it stored somewhere then
// reuse it and dont create new one
Lisp_Object* node = create_lisp_object(); Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Keyword; node->type = Lisp_Object_Type::Keyword;
node->value.keyword = new(Keyword); node->value.keyword = new(Keyword);
@@ -149,8 +170,8 @@ namespace Memory {
return node; return node;
} }


proc create_lisp_object_keyword(const char* keyword) -> Lisp_Object* {
return create_lisp_object_keyword(
proc get_or_create_lisp_object_keyword(const char* keyword) -> Lisp_Object* {
return get_or_create_lisp_object_keyword(
Memory::create_string(keyword)); Memory::create_string(keyword));
} }




+ 13
- 13
src/parse.cpp 查看文件

@@ -119,7 +119,7 @@ namespace Parser {
++(*index_in_text); ++(*index_in_text);
++parser_col; ++parser_col;
String* str_keyword = read_atom(text, index_in_text); String* str_keyword = read_atom(text, index_in_text);
Lisp_Object* ret = Memory::create_lisp_object_keyword(str_keyword);
Lisp_Object* ret = Memory::get_or_create_lisp_object_keyword(str_keyword);


inject_scl(ret); inject_scl(ret);
return ret; return ret;
@@ -128,7 +128,7 @@ namespace Parser {
proc parse_symbol(char* text, int* index_in_text) -> Lisp_Object* { proc parse_symbol(char* text, int* index_in_text) -> Lisp_Object* {
// we are now at the first char of the symbol // we are now at the first char of the symbol
String* str_symbol = read_atom(text, index_in_text); String* str_symbol = read_atom(text, index_in_text);
Lisp_Object* ret = Memory::create_lisp_object_symbol(str_symbol);
Lisp_Object* ret = Memory::get_or_create_lisp_object_symbol(str_symbol);
inject_scl(ret); inject_scl(ret);
return ret; return ret;
} }
@@ -243,16 +243,16 @@ namespace Parser {


if (quoteType == '\'') if (quoteType == '\'')
return Memory::create_lisp_object_pair( return Memory::create_lisp_object_pair(
Memory::create_lisp_object_symbol("quote"),
Memory::create_lisp_object_pair(result, Memory::create_lisp_object_nil()));
Memory::get_or_create_lisp_object_symbol("quote"),
Memory::create_lisp_object_pair(result, Memory::nil));
else if (quoteType == '`') else if (quoteType == '`')
return Memory::create_lisp_object_pair( return Memory::create_lisp_object_pair(
Memory::create_lisp_object_symbol("quasiquote"),
Memory::create_lisp_object_pair(result, Memory::create_lisp_object_nil()));
Memory::get_or_create_lisp_object_symbol("quasiquote"),
Memory::create_lisp_object_pair(result, Memory::nil));
// it has to be an unquote // it has to be an unquote
return Memory::create_lisp_object_pair( return Memory::create_lisp_object_pair(
Memory::create_lisp_object_symbol("unquote"),
Memory::create_lisp_object_pair(result, Memory::create_lisp_object_nil()));
Memory::get_or_create_lisp_object_symbol("unquote"),
Memory::create_lisp_object_pair(result, Memory::nil));
} }




@@ -267,7 +267,7 @@ namespace Parser {
if (text[(*index_in_text)] == ')') { if (text[(*index_in_text)] == ')') {
++(*index_in_text); ++(*index_in_text);
++parser_col; ++parser_col;
return Memory::create_lisp_object_nil();
return Memory::nil;
} }


// okay there is something // okay there is something
@@ -299,7 +299,7 @@ namespace Parser {




if (text[(*index_in_text)] == ')') { if (text[(*index_in_text)] == ')') {
head->value.pair->rest = Memory::create_lisp_object_nil();
head->value.pair->rest = Memory::nil;
++parser_col; ++parser_col;
++(*index_in_text); ++(*index_in_text);
break; break;
@@ -384,7 +384,7 @@ namespace Parser {
// we are now in the function body, just wrap it in an // we are now in the function body, just wrap it in an
// implicit prog // implicit prog
function->body = Memory::create_lisp_object_pair( function->body = Memory::create_lisp_object_pair(
Memory::create_lisp_object_symbol("prog"),
Memory::get_or_create_lisp_object_symbol("prog"),
arguments); arguments);


Lisp_Object* macro = Memory::create_lisp_object(); Lisp_Object* macro = Memory::create_lisp_object();
@@ -393,7 +393,7 @@ namespace Parser {
define_symbol(symbol_for_macro, macro, environment_for_macros); define_symbol(symbol_for_macro, macro, environment_for_macros);


// print_environment(environment_for_macros); // print_environment(environment_for_macros);
return Memory::create_lisp_object_nil();
return Memory::nil;


} else if (string_equal("delete-syntax", expression->value.pair->first->value.symbol->identifier)) { } else if (string_equal("delete-syntax", expression->value.pair->first->value.symbol->identifier)) {
/* --- deleting an existing macro --- */ /* --- deleting an existing macro --- */
@@ -449,7 +449,7 @@ namespace Parser {
Lisp_Object* result; Lisp_Object* result;
eat_until_code(text, &index_in_text); eat_until_code(text, &index_in_text);
if (text[(index_in_text)] == '\0') if (text[(index_in_text)] == '\0')
return Memory::create_lisp_object_nil();
return Memory::nil;
if (text[index_in_text] == '(' || if (text[index_in_text] == '(' ||
text[index_in_text] == '\'' || text[index_in_text] == '\'' ||
text[index_in_text] == '`' || text[index_in_text] == '`' ||


+ 37
- 0
src/testing.cpp 查看文件

@@ -425,6 +425,41 @@ proc test_built_in_type() -> testresult {
return pass; return pass;
} }


proc test_singular_t_and_nil() -> testresult {
Environment* env = Memory::create_built_ins_environment();

// nil testing
char exp_string1[] = "()";
char exp_string2[] = "nil";
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
Lisp_Object* result = eval_expr(expression, env);

assert_no_error();
assert_not_null(result);
assert_equal_type(result, Lisp_Object_Type::Nil);
assert_equal_int(expression, result);

Lisp_Object* expression2 = Parser::parse_single_expression(exp_string2);
Lisp_Object* result2 = eval_expr(expression2, env);

assert_no_error();
assert_not_null(result);
assert_equal_type(result, Lisp_Object_Type::Nil);
assert_equal_int(result, result2);
assert_equal_int(expression, Memory::nil);

// t testing
char exp_string3[] = "t";
Lisp_Object* expression3 = Parser::parse_single_expression(exp_string3);
Lisp_Object* result3 = eval_expr(expression3, env);

assert_no_error();
assert_not_null(result3);
assert_equal_int(result3, Memory::t);

return pass;
}

proc run_all_tests() -> void { proc run_all_tests() -> void {
log_level = Log_Level::None; log_level = Log_Level::None;
Memory::init(); Memory::init();
@@ -449,6 +484,8 @@ proc run_all_tests() -> void {
invoke_test(test_built_in_type); invoke_test(test_built_in_type);


printf("\n-- Memory management --\n"); printf("\n-- Memory management --\n");
invoke_test(test_singular_t_and_nil);

printf("\n-- Lexical scope --\n"); printf("\n-- Lexical scope --\n");
printf("\n-- Macros --\n"); printf("\n-- Macros --\n");




Loading…
取消
儲存