unquote splicing and implemented slime side list comprehensions
This commit is contained in:
+21
-2
@@ -461,7 +461,8 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
// it is a pair!
|
||||
Lisp_Object* originalPair = expr->value.pair.first;
|
||||
if (Memory::get_type(originalPair) == Lisp_Object_Type::Symbol &&
|
||||
string_equal(originalPair->value.symbol.identifier, "unquote"))
|
||||
(string_equal(originalPair->value.symbol.identifier, "unquote") ||
|
||||
string_equal(originalPair->value.symbol.identifier, "unquote-splicing")))
|
||||
{
|
||||
// eval replace the stuff
|
||||
return eval_expr(expr->value.pair.rest->value.pair.first, env);
|
||||
@@ -481,7 +482,25 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
Lisp_Object* newPairHead = newPair;
|
||||
Lisp_Object* head = expr;
|
||||
while (Memory::get_type(head) == Lisp_Object_Type::Pair) {
|
||||
newPairHead->value.pair.first = unquoteSomeExpressions(head->value.pair.first);
|
||||
// if it is ,@ we have to actually do more work
|
||||
// and inline the result
|
||||
if (Memory::get_type(head->value.pair.first) == Lisp_Object_Type::Pair &&
|
||||
Memory::get_type(head->value.pair.first->value.pair.first) == Lisp_Object_Type::Symbol &&
|
||||
string_equal(head->value.pair.first->value.pair.first->value.symbol.identifier, "unquote-splicing"))
|
||||
{
|
||||
Lisp_Object* spliced = unquoteSomeExpressions(head->value.pair.first);
|
||||
|
||||
try assert_type(spliced, Lisp_Object_Type::Pair);
|
||||
newPairHead->value.pair.first = spliced->value.pair.first;
|
||||
newPairHead->value.pair.rest = spliced->value.pair.rest;
|
||||
|
||||
// now skip to the end
|
||||
while (newPairHead->value.pair.rest != Memory::nil) {
|
||||
newPairHead = newPairHead->value.pair.rest;
|
||||
}
|
||||
} else {
|
||||
newPairHead->value.pair.first = unquoteSomeExpressions(head->value.pair.first);
|
||||
}
|
||||
|
||||
if (Memory::get_type(head->value.pair.rest) != Lisp_Object_Type::Pair)
|
||||
break;
|
||||
|
||||
+15
-13
@@ -246,8 +246,10 @@ namespace Parser {
|
||||
proc parse_expression(char* text, int* index_in_text) -> Lisp_Object* {
|
||||
|
||||
// if it is quoted
|
||||
// TODO(Felix): This looks totally broken..
|
||||
if (text[*index_in_text] == '\'' ||
|
||||
text[*index_in_text] == '`' ||
|
||||
text[*index_in_text] == '@' ||
|
||||
text[*index_in_text] == ',')
|
||||
{
|
||||
char quoteType = text[*index_in_text];
|
||||
@@ -257,15 +259,12 @@ namespace Parser {
|
||||
if (text[*index_in_text] == '(' ||
|
||||
text[*index_in_text] == '\'' ||
|
||||
text[*index_in_text] == '`' ||
|
||||
text[*index_in_text] == '@' ||
|
||||
text[*index_in_text] == ',')
|
||||
{
|
||||
try {
|
||||
result = parse_expression(text, index_in_text);
|
||||
}
|
||||
try result = parse_expression(text, index_in_text);
|
||||
} else {
|
||||
try {
|
||||
result = parse_atom(text, index_in_text);
|
||||
}
|
||||
try result = parse_atom(text, index_in_text);
|
||||
}
|
||||
|
||||
Lisp_Object* ret = nullptr;
|
||||
@@ -278,10 +277,14 @@ namespace Parser {
|
||||
try ret = Memory::create_lisp_object_pair(
|
||||
Memory::get_or_create_lisp_object_symbol("quasiquote"),
|
||||
Memory::create_lisp_object_pair(result, Memory::nil));
|
||||
else if (quoteType == ',') {
|
||||
else if (quoteType == ',')
|
||||
try ret = Memory::create_lisp_object_pair(
|
||||
Memory::get_or_create_lisp_object_symbol("unquote"),
|
||||
Memory::create_lisp_object_pair(result, Memory::nil));
|
||||
else if (quoteType == '@') {
|
||||
try ret = Memory::create_lisp_object_pair(
|
||||
Memory::get_or_create_lisp_object_symbol("unquote-splicing"),
|
||||
Memory::create_lisp_object_pair(result, Memory::nil));
|
||||
}
|
||||
if (ret) {
|
||||
inject_scl(ret);
|
||||
@@ -316,15 +319,12 @@ namespace Parser {
|
||||
if (text[*index_in_text] == '(' ||
|
||||
text[*index_in_text] == '\''||
|
||||
text[*index_in_text] == '`' ||
|
||||
text[*index_in_text] == '@' ||
|
||||
text[*index_in_text] == ',')
|
||||
{
|
||||
try {
|
||||
head->value.pair.first = parse_expression(text, index_in_text);
|
||||
}
|
||||
try head->value.pair.first = parse_expression(text, index_in_text);
|
||||
} else {
|
||||
try {
|
||||
head->value.pair.first = parse_atom(text, index_in_text);
|
||||
}
|
||||
try head->value.pair.first = parse_atom(text, index_in_text);
|
||||
}
|
||||
|
||||
eat_until_code(text, index_in_text);
|
||||
@@ -475,6 +475,7 @@ namespace Parser {
|
||||
return Memory::nil;
|
||||
if (text[index_in_text] == '(' ||
|
||||
text[index_in_text] == '\'' ||
|
||||
text[index_in_text] == '@' ||
|
||||
text[index_in_text] == '`' ||
|
||||
text[index_in_text] == ',')
|
||||
{
|
||||
@@ -507,6 +508,7 @@ namespace Parser {
|
||||
return Memory::nil;
|
||||
if (text[index_in_text] == '(' ||
|
||||
text[index_in_text] == '\'' ||
|
||||
text[index_in_text] == '@' ||
|
||||
text[index_in_text] == '`' ||
|
||||
text[index_in_text] == ',')
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user