reader.js
function read(lexer, precedence) {

  precedence = precedence || 0;

  var form = read_via_closest_dialect(lexer);

  // are we a prefix unary operator?
  var leftForm = form;
  if(sl.isAtom(form)) {
    var opSpec = getOperatorSpecFor(form, lexer.dialects);
    if(opSpec && isEnabled(opSpec.prefix) && opSpec.prefix.transform &&
      // "nospace" prefix ops must butt up against their arg so
      // "--i" not "-- i" this way we can't confuse e.g. (- x y)
      //  with (-x y)
      (!opSpec.options || !opSpec.options.nospace || !lexer.onwhitespace(-1)))
    {
      leftForm = opSpec.prefix.transform(lexer, opSpec.prefix, form);
    }
  }

  // note flipped check below from < to > because our precedences
  // are currently as you see them here: http://www.scriptingmaster.com/javascript/operator-precedence.asp
  // not as you see them here:  http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
  var token, opSpecObj;
  while(!lexer.eos() && (token = lexer.peek_token()) &&
    (opSpecObj = getOperatorSpecFor(token.text, lexer.dialects)) &&
    opSpecObj && (isEnabled(opSpecObj.infix) || isEnabled(opSpecObj.postfix)))
  {
    // make sure we don't misinterpet e.g. "(get ++i)" as "(get++ i)"
   if(opSpecObj.prefix && opSpecObj.postfix &&
     (lexer.onwhitespace(-1) && !lexer.onwhitespace(token.text.length)))
   {
     break; // let it be prefix next time round
   }

    // we don't distinguish infix from postfix below:
    var opSpec = opSpecObj.infix || opSpecObj.postfix;

    // we only keep scanning if we're hitting *higher* precedence
    if((opSpec.precedence || 0) <= precedence) {
      trace("read of infix/postfix stopping because op precedence " + (opSpec.precedence || 0) +
            " is <= the current precendence of " + precedence);
      break; // stop scanning
    }

    token = lexer.next_token();
    leftForm = opSpec.transform(lexer, opSpec, leftForm, sl.atom(token));
  }

  if(sl.isList(leftForm)) {
    // now that we've finished reading the list,
    // pop any local dialects whose scope has ended
    pop_local_dialects(lexer, leftForm);
  }

  return leftForm;
}
function read(lexer, precedence) {

  precedence = precedence || 0;

  var form = read_via_closest_dialect(lexer);

  // are we a prefix unary operator?
  var leftForm = form;
  if(sl.isAtom(form)) {
    var opSpec = getOperatorSpecFor(form, lexer.dialects);
    if(opSpec && isEnabled(opSpec.prefix) && opSpec.prefix.transform &&
      // "nospace" prefix ops must butt up against their arg so
      // "--i" not "-- i" this way we can't confuse e.g. (- x y)
      //  with (-x y)
      (!opSpec.options || !opSpec.options.nospace || !lexer.onwhitespace(-1)))
    {
      leftForm = opSpec.prefix.transform(lexer, opSpec.prefix, form);
    }
  }

  // note flipped check below from < to > because our precedences
  // are currently as you see them here: http://www.scriptingmaster.com/javascript/operator-precedence.asp
  // not as you see them here:  http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
  var token, opSpecObj;
  while(!lexer.eos() && (token = lexer.peek_token()) &&
    (opSpecObj = getOperatorSpecFor(token.text, lexer.dialects)) &&
    opSpecObj && (isEnabled(opSpecObj.infix) || isEnabled(opSpecObj.postfix)))
  {
    // make sure we don't misinterpet e.g. "(get ++i)" as "(get++ i)"
   if(opSpecObj.prefix && opSpecObj.postfix &&
     (lexer.onwhitespace(-1) && !lexer.onwhitespace(token.text.length)))
   {
     break; // let it be prefix next time round
   }

    // we don't distinguish infix from postfix below:
    var opSpec = opSpecObj.infix || opSpecObj.postfix;

    // we only keep scanning if we're hitting *higher* precedence
    if((opSpec.precedence || 0) <= precedence) {
      trace("read of infix/postfix stopping because op precedence " + (opSpec.precedence || 0) +
            " is <= the current precendence of " + precedence);
      break; // stop scanning
    }

    token = lexer.next_token();
    leftForm = opSpec.transform(lexer, opSpec, leftForm, sl.atom(token));
  }

  if(sl.isList(leftForm)) {
    // now that we've finished reading the list,
    // pop any local dialects whose scope has ended
    pop_local_dialects(lexer, leftForm);
  }

  return leftForm;
}
function read ( lexer , precedence ) { precedence = precedence || 0 ; var form = read_via_closest_dialect ( lexer ) ; // are we a prefix unary operator? var leftForm = form ; if ( sl . isAtom ( form ) ) { var opSpec = getOperatorSpecFor ( form , lexer . dialects ) ; if ( opSpec && isEnabled ( opSpec . prefix ) && opSpec . prefix . transform && // "nospace" prefix ops must butt up against their arg so // "--i" not "-- i" this way we can't confuse e.g. (- x y) //  with (-x y) ( ! opSpec . options || ! opSpec . options . nospace || ! lexer . onwhitespace ( - 1 ) ) ) { leftForm = opSpec . prefix . transform ( lexer , opSpec . prefix , form ) ; } } // note flipped check below from < to > because our precedences // are currently as you see them here: http://www.scriptingmaster.com/javascript/operator-precedence.asp // not as you see them here:  http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/ var token , opSpecObj ; while ( ! lexer . eos ( ) && ( token = lexer . peek_token ( ) ) && ( opSpecObj = getOperatorSpecFor ( token . text , lexer . dialects ) ) && opSpecObj && ( isEnabled ( opSpecObj . infix ) || isEnabled ( opSpecObj . postfix ) ) ) { // make sure we don't misinterpet e.g. "(get ++i)" as "(get++ i)" if ( opSpecObj . prefix && opSpecObj . postfix && ( lexer . onwhitespace ( - 1 ) && ! lexer . onwhitespace ( token . text . length ) ) ) { break ; // let it be prefix next time round } // we don't distinguish infix from postfix below: var opSpec = opSpecObj . infix || opSpecObj . postfix ; // we only keep scanning if we're hitting *higher* precedence if ( ( opSpec . precedence || 0 ) <= precedence ) { trace ( "read of infix/postfix stopping because op precedence " + ( opSpec . precedence || 0 ) + " is <= the current precendence of " + precedence ) ; break ; // stop scanning } token = lexer . next_token ( ) ; leftForm = opSpec . transform ( lexer , opSpec , leftForm , sl . atom ( token ) ) ; } if ( sl . isList ( leftForm ) ) { // now that we've finished reading the list, // pop any local dialects whose scope has ended pop_local_dialects ( lexer , leftForm ) ; } return leftForm ; }
Read the form at the current position in the source.
@param lexer = the lexer that is reading the source file.
@param precedence = internal use only (don't pass)
@return the list (see sl-types) for the expression that was read.
Read the form at the current position in the source .