public static Pair expand(VM vm, ArcObject body, Map[] lexicalBindings) { List result = new LinkedList(); while (!(body instanceof Nil) && body instanceof Pair) { ArcObject next = body.car(); body = body.cdr(); result.add(Compiler.compile(vm, next, lexicalBindings).reduce()); } return (Pair) Pair.buildFrom(result, Compiler.compile(vm, body, lexicalBindings).reduce()); }
private static ArcObject replaceBoundSymbols( Map<Symbol, Integer> lexicalBindings, ArcObject expr, int nesting) { if (isUnQuote(expr)) { if (nesting == 1) { return Pair.buildFrom(UNQUOTE, expr.cdr().car().replaceBoundSymbols(lexicalBindings)); } else { return Pair.buildFrom( UNQUOTE, replaceBoundSymbols(lexicalBindings, expr.cdr().car(), nesting - 1)); } } else if (isUnQuoteSplicing(expr)) { if (nesting == 1) { return Pair.buildFrom( UNQUOTE_SPLICING, expr.cdr().car().replaceBoundSymbols(lexicalBindings)); } else { return Pair.buildFrom( UNQUOTE_SPLICING, replaceBoundSymbols(lexicalBindings, expr.cdr().car(), nesting - 1)); } } else if (isQuasiQuote(expr)) { return Pair.buildFrom( QUASIQUOTE, replaceBoundSymbols(lexicalBindings, expr.cdr().car(), nesting + 1)); } else if (expr.isNotPair()) { return expr; } List list = new ArrayList(); ArcObject last = NIL; while (!expr.isNotPair()) { if (isUnQuote(expr) || isQuasiQuote(expr)) { // catch post-dot unquotes last = replaceBoundSymbols(lexicalBindings, expr, nesting); expr = expr.cdr().cdr(); } else { final ArcObject current = expr.car(); expr = expr.cdr(); if (isUnQuoteSplicing(current) || isUnQuote(current) || isQuasiQuote(current) || isPair(current)) { list.add(replaceBoundSymbols(lexicalBindings, current, nesting)); } else { list.add(current); } } } if (!(expr instanceof Nil)) { last = expr; } return Pair.buildFrom(list, last); }
private static ArcObject inline( StackSymbol p, ArcObject arg, int paramIndex, ArcObject expr, int nesting) { if (isUnQuote(expr)) { if (nesting == 1) { return Pair.buildFrom(UNQUOTE, expr.cdr().car().inline(p, arg, paramIndex)); } else { return Pair.buildFrom(UNQUOTE, inline(p, arg, paramIndex, expr.cdr().car(), nesting - 1)); } } else if (isUnQuoteSplicing(expr)) { if (nesting == 1) { return Pair.buildFrom(UNQUOTE_SPLICING, expr.cdr().car().inline(p, arg, paramIndex)); } else { return Pair.buildFrom( UNQUOTE_SPLICING, inline(p, arg, paramIndex, expr.cdr().car(), nesting - 1)); } } else if (isQuasiQuote(expr)) { return Pair.buildFrom(QUASIQUOTE, inline(p, arg, paramIndex, expr.cdr().car(), nesting + 1)); } else if (expr.isNotPair()) { return expr; } List list = new ArrayList(); ArcObject last = NIL; while (!expr.isNotPair()) { if (isUnQuote(expr) || isQuasiQuote(expr)) { // catch post-dot unquotes last = inline(p, arg, paramIndex, expr, nesting); expr = expr.cdr().cdr(); } else { final ArcObject current = expr.car(); expr = expr.cdr(); if (isUnQuoteSplicing(current)) { list.add(inline(p, arg, paramIndex, current, nesting)); } else if (isUnQuote(current) || isQuasiQuote(current) || isPair(current)) { list.add(inline(p, arg, paramIndex, current, nesting)); } else { list.add(current); } } } if (!(expr instanceof Nil)) { last = expr; } return Pair.buildFrom(list, last); }
protected ArcObject invoke(Pair args) { checkMaxArgCount(args, getClass(), 1); double result = Math.acos(ArcNumber.cast(args.car(), this).toDouble()); return new Real(result); }