@@ -97,7 +97,7 @@ inline ExprPtr or_(MExprPtr const& mexpr)
97
97
return std::make_shared<Or>(parseActions (mexpr));
98
98
}
99
99
100
- inline auto parseAsQuoted (MExprPtr const & mexpr, bool quasi ) -> ExprPtr;
100
+ inline auto parseAsQuoted (MExprPtr const & mexpr, std::optional< int32_t > quasiquoteLevel ) -> ExprPtr;
101
101
102
102
inline MExprPtr assertIsLastAndGet (MExprPtr const & mexpr)
103
103
{
@@ -113,12 +113,12 @@ inline MExprPtr assertIsLastAndGet(MExprPtr const& mexpr)
113
113
114
114
inline ExprPtr quote (MExprPtr const & mexpr)
115
115
{
116
- return parseAsQuoted (assertIsLastAndGet (mexpr), /* quasi = */ false );
116
+ return parseAsQuoted (assertIsLastAndGet (mexpr), /* quasiquoteLevel = */ {} );
117
117
}
118
118
119
119
inline ExprPtr quasiquote (MExprPtr const & mexpr)
120
120
{
121
- return parseAsQuoted (assertIsLastAndGet (mexpr), /* quasi = */ true );
121
+ return parseAsQuoted (assertIsLastAndGet (mexpr), /* quasiquoteLevel = */ 1 );
122
122
}
123
123
124
124
inline ExprPtr definition (MExprPtr const & mexpr)
@@ -321,10 +321,10 @@ inline auto atomicToQuoted(ExprPtr const& expr)
321
321
322
322
inline ExprPtr unquote (MExprPtr const & mexpr)
323
323
{
324
- return ExprPtr{ new Unquote{ assertIsLastAndGet (mexpr)}} ;
324
+ return parse ( assertIsLastAndGet (mexpr)) ;
325
325
}
326
326
327
- inline auto consToQuoted (MExprPtr const & mexpr, bool quasi ) -> ExprPtr
327
+ inline auto consToQuoted (MExprPtr const & mexpr, std::optional< int32_t > quasiquoteLevel ) -> ExprPtr
328
328
{
329
329
if (mexpr == MNil::instance ())
330
330
{
@@ -334,21 +334,34 @@ inline auto consToQuoted(MExprPtr const& mexpr, bool quasi) -> ExprPtr
334
334
ASSERT (cons);
335
335
auto car = cons->car ();
336
336
auto cdr = cons->cdr ();
337
- if (quasi && car->toString () == " unquote" )
337
+ auto carStr = car->toString ();
338
+ if (quasiquoteLevel)
338
339
{
339
- return unquote (cdr);
340
+ if (carStr == " unquote" )
341
+ {
342
+ if ( quasiquoteLevel.value () == 1 )
343
+ {
344
+ return unquote (cdr);
345
+ }
346
+ --(*quasiquoteLevel);
347
+ }
348
+ else if (carStr == " quasiquote" )
349
+ {
350
+ ++(*quasiquoteLevel);
351
+ }
340
352
}
341
- return ExprPtr{new Cons{parseAsQuoted (car, quasi ), consToQuoted (cdr, quasi )}};
353
+ return ExprPtr{new Cons{parseAsQuoted (car, quasiquoteLevel ), consToQuoted (cdr, quasiquoteLevel )}};
342
354
}
343
355
344
- inline auto parseAsQuoted (MExprPtr const & mexpr, bool quasi) -> ExprPtr
356
+ // TODO: change quasi to quote level.
357
+ inline auto parseAsQuoted (MExprPtr const & mexpr, std::optional<int32_t > quasiquoteLevel) -> ExprPtr
345
358
{
346
359
if (auto atomic = tryMAtomic (mexpr))
347
360
{
348
361
return atomicToQuoted (atomic);
349
362
}
350
363
351
364
// else mexpr is cons, map quote on it
352
- return consToQuoted (mexpr, quasi );
365
+ return consToQuoted (mexpr, quasiquoteLevel );
353
366
}
354
367
#endif // LISP_PARSER_H
0 commit comments