<commit_before>/*
 * Copyright (c) 2015 Mansi Shah, Santosh Rajan
*/

var ast = {
        type: "Program",
        body: []
    }

module.exports = function(src) {

    var spaceRegEx = /^[ \t\r\n\b\f]+/,
        newLineRegEx = /\r?\n/g,
        nullRegEx = /^null\b/i,
        booleanRegEx = /^(true|false)\b/i,
        numberRegEx = /^[-+]?(\d+(\.\d*)?|\.\d+)([e][+-]?\d+)?/i,
        stringRegEx = /^('|").*?[^\\]\1/,
        identifierRegEx = /^[a-z\~]+[a-z0-9_\[\]\.\*]*/i,
        restParamRegEx = /^\.\.\.[a-z]+[a-z0-9_\[\]\.\*]*/i,
        openParanthesesRegEx = /^\(/,
        closingParanthesesRegEx = /^\)/,
        operatorRegEx = /^(\*|\+|\-|\/|\%)/,
        functionKeywordRegEx = /^(\()(\s)*function/,
        macroKeywordRegEx = /^(\()(\s)*macro\b/,
        varKeywordRegEx = /^(\()?(\s)*var/,
        ifKeywordRegEx = /^\((\s)*if/,
        fatArrowRegEx = /^\(\=\>/,
        line = 1
        macros = {}

    function consumer(regex, process) {
        return function() {
            var matches = regex.exec(src)
            if(!matches) return null
            // console.info("Matched "+regex)
            src = src.slice(matches[0].length)
            spaceParser()
            if(process)    return process(matches[0])
            return matches[0]
        }
    }

    function parserFactory() {
        var parsers = arguments
        return function() {
            for(index in parsers){
                var parser = parsers[index]
                spaceParser()
                var result = parser()
                if(result){
                    // console.info("Consumed as "+result.type)
                    return result
                }
            }
            return null
        }
    }

    var spaceParser = consumer(spaceRegEx, function(val){
            var match = val.match(newLineRegEx)
            var l = (match)? match.length : 0
            line+=l
            return true
        }),
        nullParser = consumer(nullRegEx, function(){
            return {type: "Literal", value: null}
        }),
        booleanParser = consumer(booleanRegEx, function(val){
            return {type: "Literal", value: val}
        }),
        numberParser = consumer(numberRegEx, function(val){
            return {type: "Literal", value: Number(val)}
        }),
        stringParser = consumer(stringRegEx, function(val){
            return {type: "Literal", value: val.slice(1,val.length-1)}
        }),
        literalParser = parserFactory(nullParser, booleanParser, numberParser, stringParser),
        identifierParser = consumer(identifierRegEx, function(val) {
            return {type: "Identifier", name: val}
        }),
        restParamParser = consumer(restParamRegEx, function(val) {
            var temp = src
            src = val.slice(3)  //Stripping the '...'
            argument = statementParser()
            src = temp
            return {type: "RestElement", argument: argument}
        }),
        elementParser = parserFactory(literalParser, identifierParser, restParamParser),
        openParanthesesParser = consumer(openParanthesesRegEx, function(val){
            return true
        }),
        closingParanthesesParser = consumer(closingParanthesesRegEx, function(val){
            return true
        }),
        operatorParser = consumer(operatorRegEx),
        varKeywordParser = consumer(varKeywordRegEx),
        functionKeywordParser = consumer(functionKeywordRegEx),
        ifKeywordParser = consumer(ifKeywordRegEx),
        macroKeywordParser = consumer(macroKeywordRegEx),
        fatArrowParser = consumer(fatArrowRegEx)

    function argumentsParser() {
        var args = []
        spaceParser()
        if(src.length > 0){
            while(!closingParanthesesParser()){
                // console.info("Parsing args "+src)
                arg = argStatementParser()
                if (!arg)
                    throw new SyntaxError("argumentsParser : Unexpected character at line: "+line)
                args.push(arg)
                spaceParser()
            }
            spaceParser()
            if (args.length > 0)
                return args
        }
        return []
    }

    function expressionParser() {
        if (!openParanthesesParser()) return null
        // console.info("ExpressionParser "+src)
        return callExpressionParser() || binaryExpressionParser() || statementParser()
    }

    function expressionStatementParser() {
        spaceParser()
        if (closingParanthesesParser())  return null
        // console.info("ExpressionStatementParser "+src)
        return combinator({type: "ExpressionStatement"}, ["expression", expressionParser])
    }

    function macroCallParser() {
        var temp = src
        if(!openParanthesesParser()) return null
        if (macroId = identifierParser()) {
        // console.info("MacroCallParser "+src)
            if (macro = macros[macroId.name]) {
                var macroArgs = getArguments() || []
                var macroBody = macro.body
                for(param in macro.params){
                    var regex = new RegExp('~'+param.replace(/\./g,'\\.'), 'gi')
                    if(!Array.isArray(macro.params[param]))
                        val = macroArgs.shift()
                    else
                        val = macroArgs.join(" ")
                    macroBody = macroBody.replace(regex,val)
                }
                var temp = src
                src = macroBody
                var macroExpr = []
                while(src.length > 0){
                    // console.info("Parsing Macro Body "+src)
                    var rslt = statementParser()
                    if(rslt)    macroExpr.push(rslt)
                    else    throw new SyntaxError("Cannot parse macro body")
                }
                src = temp
                return macroExpr
            }
        }
        src = temp
        return null
    }

    function callExpressionParser() {
        // console.info("callExpressionParser "+src)
        return combinator({type: "CallExpression"}, ["callee", statementParser], ["arguments", argumentsParser])
    }

    function binaryExpressionParser() {
        // console.info("binaryExpressionParser "+src)
        return combinator({type: "BinaryExpression"}, ["operator", operatorParser], ["left", elementParser], ["right", elementParser], ["", closingParanthesesParser])
    }

    function extractExpression() {
        var found = false, parantheses = 1, i = 0
        while(!found){
            // console.info("Inside extractExpression "+src)
            if (src[i] == '(')
                parantheses++
            if (src[i] == ')')
                parantheses--
            if (parantheses == 0)
                found = true
            i++
        }

        return src.slice(0,i)
    }

    function getArguments(){
        var args = []
        while(!closingParanthesesParser()){
            // console.info("Inside getArguments "+src)
            if(matches = /^[a-z0-9]*\b/.exec(src) || stringRegEx.exec(src)){
                args.push(matches[0])
            }
            else if(openParanthesesParser()){
                matches = [extractExpression()]
                args.push('('+matches[0])
            }
            if(matches) src = src.slice(matches[0].length)
            else    throw new SyntaxError("Unknown character at line: "+line)
            spaceParser()
        }
        return args
    }

    function macroDeclarationParser() {
        if (!macroKeywordParser())    return null
        // console.info("macroDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        spaceParser()

        //id
        if (id = identifierParser())
            macroId = id.name
        else
            throw new SyntaxError("Expecting a macro identifier")
        spaceParser()

        //params
        if (!openParanthesesParser())
            throw new SyntaxError("Expecting '(' after " + macroId)

        var macro = {}
        macro.params = {}
        while(!closingParanthesesParser()){
            if (param = identifierParser().name) {
                macro.params[param.toString()] = null
            }
        }
        macro.params["...rest"] = []

        //body
        macro.body = src.slice(0,src.length-1)

        src = rest
        spaceParser()

        macros[macroId.toString()] = macro
        return null

    }

    function combinator(expr){
        for(var i=1; i<arguments.length; i++){
            var attr = arguments[i][0]
            var parser = arguments[i][1]
            var args = arguments[i][2]
            if(typeof parser == "function"){
                if(Array.isArray(args)){
                    var result = parser(args[0],args[1])
                }
                else
                    var result = parser()
                if(result == null) return null
            }
            else
                result = parser

            if(attr){
                expr[attr] = result
            }
        }
        return expr
    }

    function functionDeclarationParser() {
        if (!functionKeywordParser())    return null
        // console.info("functionDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "FunctionDeclaration"}, ["id", identifierParser], ["",openParanthesesParser], ["params",argumentsParser], ["defaults", []], ["body", blockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function variableDeclarationParser() {
        if (!varKeywordParser()) return null
        // console.info("variableDeclarationParser "+src)
        var expr = {type: "VariableDeclaration", declarations: [], kind: "var"}
        var innerExpr = combinator({type: "VariableDeclarator"}, ["id", identifierParser], ["init", argStatementParser], ["", closingParanthesesParser])
        expr.declarations.push(innerExpr)
        closingParanthesesParser()
        return expr
    }

    function blockStatementParser() {
        return combinator({type: "BlockStatement"}, ["body", functionBodyParser])
    }

    function arrowFunctionParser() {
        if (!fatArrowParser())   return null
        // console.info("arrowFunctionParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "ArrowFunctionExpression"}, ["id", null], ["", openParanthesesParser], ["params", argumentsParser], ["defaults", []], ["body", blockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function ifStatementParser() {
        if (!ifKeywordParser())   return null
        // console.info("ifStatementParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "IfStatement"}, ["", openParanthesesParser], ["test", argStatementParser], ["", closingParanthesesParser], ["", openParanthesesParser], ["consequent", blockStatementParser], ["", openParanthesesParser], ["alternate", blockStatementParser])
        src = rest
        return expr
    }

    function functionBodyParser() {
        var stmts = []
        while(!closingParanthesesParser()){
            // console.info("Parsing Function Body "+src)
            var stmt = argStatementParser()
            stmts.push(stmt)
        }
        stmts[stmts.length-1] = {type: "ReturnStatement", argument: stmts[stmts.length-1]}

        return stmts
    }

    function statementParser() {
        // console.info("statementParser "+src)
        return ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || macroCallParser() || expressionStatementParser()
    }

    function argStatementParser() {
        // console.info("argStatementParser "+src)
        return ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || expressionParser()
    }

    function bodyParser() {
        var body = []
        while(src.length != 0){
            spaceParser()
            var stmt = statementParser()
            // console.info("Output: ",stmt)
            if (!stmt)
                throw new SyntaxError("Cannot parse statement at line: " + line)
            if(Array.isArray(stmt))
                stmt.forEach(function(s){body.push(s)})
            else
                body.push(stmt)

        }
        return body
    }

    ast.body = bodyParser()
    return ast
}<commit_msg>Fixes booleanParser<commit_after>/*
 * Copyright (c) 2015 Mansi Shah, Santosh Rajan
*/

var ast = {
        type: "Program",
        body: []
    }

module.exports = function(src) {

    var spaceRegEx = /^[ \t\r\n\b\f]+/,
        newLineRegEx = /\r?\n/g,
        nullRegEx = /^null\b/i,
        booleanRegEx = /^(true|false)\b/i,
        numberRegEx = /^[-+]?(\d+(\.\d*)?|\.\d+)([e][+-]?\d+)?/i,
        stringRegEx = /^('|").*?[^\\]\1/,
        identifierRegEx = /^[a-z\~]+[a-z0-9_\[\]\.\*]*/i,
        restParamRegEx = /^\.\.\.[a-z]+[a-z0-9_\[\]\.\*]*/i,
        openParanthesesRegEx = /^\(/,
        closingParanthesesRegEx = /^\)/,
        operatorRegEx = /^(\*|\+|\-|\/|\%)/,
        functionKeywordRegEx = /^(\()(\s)*function/,
        macroKeywordRegEx = /^(\()(\s)*macro\b/,
        varKeywordRegEx = /^(\()?(\s)*var/,
        ifKeywordRegEx = /^\((\s)*if/,
        fatArrowRegEx = /^\(\=\>/,
        line = 1
        macros = {}

    function consumer(regex, process) {
        return function() {
            var matches = regex.exec(src)
            if(!matches) return null
            // console.info("Matched "+regex)
            src = src.slice(matches[0].length)
            spaceParser()
            if(process)    return process(matches[0])
            return matches[0]
        }
    }

    function parserFactory() {
        var parsers = arguments
        return function() {
            for(index in parsers){
                var parser = parsers[index]
                spaceParser()
                var result = parser()
                if(result){
                    // console.info("Consumed as "+result.type)
                    return result
                }
            }
            return null
        }
    }

    var spaceParser = consumer(spaceRegEx, function(val){
            var match = val.match(newLineRegEx)
            var l = (match)? match.length : 0
            line+=l
            return true
        }),
        nullParser = consumer(nullRegEx, function(){
            return {type: "Literal", value: null}
        }),
        booleanParser = consumer(booleanRegEx, function(val){
            if(val === 'true')
                return {type: "Literal", value: true}
            else
                return {type: "Literal", value: false}
        }),
        numberParser = consumer(numberRegEx, function(val){
            return {type: "Literal", value: Number(val)}
        }),
        stringParser = consumer(stringRegEx, function(val){
            return {type: "Literal", value: val.slice(1,val.length-1)}
        }),
        literalParser = parserFactory(nullParser, booleanParser, numberParser, stringParser),
        identifierParser = consumer(identifierRegEx, function(val) {
            return {type: "Identifier", name: val}
        }),
        restParamParser = consumer(restParamRegEx, function(val) {
            var temp = src
            src = val.slice(3)  //Stripping the '...'
            argument = statementParser()
            src = temp
            return {type: "RestElement", argument: argument}
        }),
        elementParser = parserFactory(literalParser, identifierParser, restParamParser),
        openParanthesesParser = consumer(openParanthesesRegEx, function(val){
            return true
        }),
        closingParanthesesParser = consumer(closingParanthesesRegEx, function(val){
            return true
        }),
        operatorParser = consumer(operatorRegEx),
        varKeywordParser = consumer(varKeywordRegEx),
        functionKeywordParser = consumer(functionKeywordRegEx),
        ifKeywordParser = consumer(ifKeywordRegEx),
        macroKeywordParser = consumer(macroKeywordRegEx),
        fatArrowParser = consumer(fatArrowRegEx)

    function argumentsParser() {
        var args = []
        spaceParser()
        if(src.length > 0){
            while(!closingParanthesesParser()){
                // console.info("Parsing args "+src)
                arg = argStatementParser()
                if (!arg)
                    throw new SyntaxError("argumentsParser : Unexpected character at line: "+line)
                args.push(arg)
                spaceParser()
            }
            spaceParser()
            if (args.length > 0)
                return args
        }
        return []
    }

    function expressionParser() {
        if (!openParanthesesParser()) return null
        // console.info("ExpressionParser "+src)
        return callExpressionParser() || binaryExpressionParser() || statementParser()
    }

    function expressionStatementParser() {
        spaceParser()
        if (closingParanthesesParser())  return null
        // console.info("ExpressionStatementParser "+src)
        return combinator({type: "ExpressionStatement"}, ["expression", expressionParser])
    }

    function macroCallParser() {
        var temp = src
        if(!openParanthesesParser()) return null
        if (macroId = identifierParser()) {
        // console.info("MacroCallParser "+src)
            if (macro = macros[macroId.name]) {
                var macroArgs = getArguments() || []
                var macroBody = macro.body
                for(param in macro.params){
                    var regex = new RegExp('~'+param.replace(/\./g,'\\.'), 'gi')
                    if(!Array.isArray(macro.params[param]))
                        val = macroArgs.shift()
                    else
                        val = macroArgs.join(" ")
                    macroBody = macroBody.replace(regex,val)
                }
                var temp = src
                src = macroBody
                var macroExpr = []
                while(src.length > 0){
                    // console.info("Parsing Macro Body "+src)
                    var rslt = statementParser()
                    if(rslt)    macroExpr.push(rslt)
                    else    throw new SyntaxError("Cannot parse macro body")
                }
                src = temp
                return macroExpr
            }
        }
        src = temp
        return null
    }

    function callExpressionParser() {
        // console.info("callExpressionParser "+src)
        return combinator({type: "CallExpression"}, ["callee", statementParser], ["arguments", argumentsParser])
    }

    function binaryExpressionParser() {
        // console.info("binaryExpressionParser "+src)
        return combinator({type: "BinaryExpression"}, ["operator", operatorParser], ["left", elementParser], ["right", elementParser], ["", closingParanthesesParser])
    }

    function extractExpression() {
        var found = false, parantheses = 1, i = 0
        while(!found){
            // console.info("Inside extractExpression "+src)
            if (src[i] == '(')
                parantheses++
            if (src[i] == ')')
                parantheses--
            if (parantheses == 0)
                found = true
            i++
        }

        return src.slice(0,i)
    }

    function getArguments(){
        var args = []
        while(!closingParanthesesParser()){
            // console.info("Inside getArguments "+src)
            if(matches = /^[a-z0-9]*\b/.exec(src) || stringRegEx.exec(src)){
                args.push(matches[0])
            }
            else if(openParanthesesParser()){
                matches = [extractExpression()]
                args.push('('+matches[0])
            }
            if(matches) src = src.slice(matches[0].length)
            else    throw new SyntaxError("Unknown character at line: "+line)
            spaceParser()
        }
        return args
    }

    function macroDeclarationParser() {
        if (!macroKeywordParser())    return null
        // console.info("macroDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        spaceParser()

        //id
        if (id = identifierParser())
            macroId = id.name
        else
            throw new SyntaxError("Expecting a macro identifier")
        spaceParser()

        //params
        if (!openParanthesesParser())
            throw new SyntaxError("Expecting '(' after " + macroId)

        var macro = {}
        macro.params = {}
        while(!closingParanthesesParser()){
            if (param = identifierParser().name) {
                macro.params[param.toString()] = null
            }
        }
        macro.params["...rest"] = []

        //body
        macro.body = src.slice(0,src.length-1)

        src = rest
        spaceParser()

        macros[macroId.toString()] = macro
        return null

    }

    function combinator(expr){
        for(var i=1; i<arguments.length; i++){
            var attr = arguments[i][0]
            var parser = arguments[i][1]
            var args = arguments[i][2]
            if(typeof parser == "function"){
                if(Array.isArray(args)){
                    var result = parser(args[0],args[1])
                }
                else
                    var result = parser()
                if(result == null) return null
            }
            else
                result = parser

            if(attr){
                expr[attr] = result
            }
        }
        return expr
    }

    function functionDeclarationParser() {
        if (!functionKeywordParser())    return null
        // console.info("functionDeclarationParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "FunctionDeclaration"}, ["id", identifierParser], ["",openParanthesesParser], ["params",argumentsParser], ["defaults", []], ["body", blockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function variableDeclarationParser() {
        if (!varKeywordParser()) return null
        // console.info("variableDeclarationParser "+src)
        var expr = {type: "VariableDeclaration", declarations: [], kind: "var"}
        var innerExpr = combinator({type: "VariableDeclarator"}, ["id", identifierParser], ["init", argStatementParser], ["", closingParanthesesParser])
        expr.declarations.push(innerExpr)
        closingParanthesesParser()
        return expr
    }

    function blockStatementParser() {
        return combinator({type: "BlockStatement"}, ["body", functionBodyParser])
    }

    function arrowFunctionParser() {
        if (!fatArrowParser())   return null
        // console.info("arrowFunctionParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "ArrowFunctionExpression"}, ["id", null], ["", openParanthesesParser], ["params", argumentsParser], ["defaults", []], ["body", blockStatementParser], ["generator", false], ["expression", false])
        src = rest
        return expr
    }

    function ifStatementParser() {
        if (!ifKeywordParser())   return null
        // console.info("ifStatementParser "+src)
        var snippet = extractExpression()
        var rest = src.slice(snippet.length)
        src = snippet
        var expr = combinator({type: "IfStatement"}, ["", openParanthesesParser], ["test", argStatementParser], ["", closingParanthesesParser], ["", openParanthesesParser], ["consequent", blockStatementParser], ["", openParanthesesParser], ["alternate", blockStatementParser])
        src = rest
        return expr
    }

    function functionBodyParser() {
        var stmts = []
        while(!closingParanthesesParser()){
            // console.info("Parsing Function Body "+src)
            var stmt = argStatementParser()
            stmts.push(stmt)
        }
        stmts[stmts.length-1] = {type: "ReturnStatement", argument: stmts[stmts.length-1]}

        return stmts
    }

    function statementParser() {
        // console.info("statementParser "+src)
        return ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || macroCallParser() || expressionStatementParser()
    }

    function argStatementParser() {
        // console.info("argStatementParser "+src)
        return ifStatementParser() || arrowFunctionParser() || macroDeclarationParser()|| functionDeclarationParser() || variableDeclarationParser() || elementParser() || expressionParser()
    }

    function bodyParser() {
        var body = []
        while(src.length != 0){
            spaceParser()
            var stmt = statementParser()
            // console.info("Output: ",stmt)
            if (!stmt)
                throw new SyntaxError("Cannot parse statement at line: " + line)
            if(Array.isArray(stmt))
                stmt.forEach(function(s){body.push(s)})
            else
                body.push(stmt)

        }
        return body
    }

    ast.body = bodyParser()
    return ast
}<|endoftext|>


<commit_before>var Assert = require('assert');
var Scanner = require(__dirname + '/scanner');

var parse = exports.parse = function parse(input) {
  var tokens = Scanner.tokenize(input);
  var currentPosition = -1;

  function peekToken() {
    if ((tokens.length - 1) > currentPosition) {
      return tokens[currentPosition + 1];
    } else {
      return 'EOF';
    }
  }

  function nextToken() {
    var token = peekToken();
    currentPosition += 1;
    return token;
  }

  function buildAST(node) {
    var token = nextToken();
    var astToken = {};

    if (token.type === 'L_PAREN') {
      astToken.type = 'PAIR';
      astToken.value = [];
      astToken.parent = node;
      node.value.push(astToken);
      buildAST(astToken);
      return astToken;
    } else if (token.type === 'R_PAREN') {
      Assert.ok(node.parent, 'Matching parenthesis expected!');
      buildAST(node.parent);
      delete node.parent;
      return;
    } else if (token.type === 'NUMBER') {
      astToken.type = 'NUMBER';
      astToken.value = token.token;
      node.value.push(astToken);
      buildAST(node);
      return;
    } else if (token.type === 'STRING') {
      astToken.type = 'STRING';
      astToken.value = token.token;
      node.value.push(astToken);
      buildAST(node);
      return;
    } else if (token.type === 'SYMBOL') {
      astToken.type = 'SYMBOL';
      astToken.value = token.token;
      node.value.push(astToken);
      buildAST(node);
      return;
    }
  }

  return buildAST({ value: [] });
};
<commit_msg>I accidentally the whole parser<commit_after>/*!
 * parser.js
 *
 * Builds an abstract syntax tree from a token
 * stream generated by the scanner
 */

var Assert = require('assert');
var Lisp = require('./lisp');
var TokenStream = require('./tokenstream');
var Scanner = require('./scanner');

var parse = exports.parse = function parse(input, pair) {

  var stream = TokenStream.createStream(Scanner.tokenize(input));

  function buildAST(depth) {
    var token = stream.next();
    var skip = false;
    var parsed;

    switch (token.type) {
    case 'L_PAREN':
      parsed = buildAST(depth + 1);
      break;

    case 'R_PAREN':
      depth -= 1;
      parsed = Lisp.nil();
      skip = true;
      break;

    case 'DOT':
      parsed = buildAST(depth - 1);
      depth -= 1;
      break;

    case 'NUMBER':
      parsed = Lisp.number(token.token);
      break;

    case 'STRING':
      parsed = Lisp.string(token.token);
      break;

    case 'SYMBOL':
      parsed = Lisp.symbol(token.token);
      break;

    default:
      parsed = Lisp.nil();
    }

    if (depth === 0 || skip) {
      return parsed;
    }

    return Lisp.pair(parsed, buildAST(depth));
  }

  return buildAST(0);
};
<|endoftext|>


<commit_before>'use strict';

var CHAR = Object.freeze({
    EMPTY: '',
    NEWLINE: '\n',
    QUOTE: '\'',
    SEMICOLON: ';',
    SPACE: ' ',
    TAB: '    '
});

var GRAMMAR = Object.freeze({
    COLOR: 'paint',
    CREATE_START: 'create',
    CREATE_END: 'leave',
    NOTE: 'note',
    PROGRAM: 'program',
    USAGE: 'usage'
});

var indentLevel = 0;

var generateIndentation = function (level) {
    var indent = '';

    for (var i = 0; i < level; i++) {
        indent += CHAR.TAB;
    }

    return indent;
};

var generateVesselName = function (keys) {
    keys.shift();

    return keys.join('_');
};

var generatePropertyValue = function (keys) {
    keys.shift();

    return keys.join(' ');
};

module.exports = function parse (line) {
    line = line.replace(/[^A-Z0-9\,\. ]/gi, '');

    var keys = line.match(/'[^']+'|\S+/g);
    var statement = '';

    if (keys === null) {
        return line + '\n';
    }

    if (keys[0] === GRAMMAR.CREATE_START) {
        var vesselName = generateVesselName(keys);

        statement += generateIndentation(indentLevel) + 'function ' + vesselName  + ' () {' + CHAR.NEWLINE;

        indentLevel++;

        statement += generateIndentation(indentLevel) + 'this.name = ' + CHAR.QUOTE + vesselName + CHAR.QUOTE + CHAR.SEMICOLON + CHAR.NEWLINE;
    }

    if (keys[0] === GRAMMAR.CREATE_END) {
        indentLevel--;

        statement += generateIndentation(indentLevel) + '}' + CHAR.NEWLINE;
    }

    if (keys[0] === GRAMMAR.NOTE || keys[0] === GRAMMAR.PROGRAM || keys[0] === GRAMMAR.USAGE) {
        var propertyName = keys[0];
        var propertyValue = generatePropertyValue(keys);

        statement += generateIndentation(indentLevel) + 'this.' + propertyName + ' = ' + CHAR.QUOTE + propertyValue + CHAR.QUOTE + CHAR.SEMICOLON + CHAR.NEWLINE;
    }

    return statement;
};
<commit_msg>Fix function declaration spacing<commit_after>'use strict';

var CHAR = Object.freeze({
    EMPTY: '',
    NEWLINE: '\n',
    QUOTE: '\'',
    SEMICOLON: ';',
    SPACE: ' ',
    TAB: '    '
});

var GRAMMAR = Object.freeze({
    COLOR: 'paint',
    CREATE_START: 'create',
    CREATE_END: 'leave',
    NOTE: 'note',
    PROGRAM: 'program',
    USAGE: 'usage'
});

var indentLevel = 0;

var generateIndentation = function (level) {
    var indent = '';

    for (var i = 0; i < level; i++) {
        indent += CHAR.TAB;
    }

    return indent;
};

var generateVesselName = function (keys) {
    keys.shift();

    return keys.join('_');
};

var generatePropertyValue = function (keys) {
    keys.shift();

    return keys.join(' ');
};

module.exports = function parse(line) {
    line = line.replace(/[^A-Z0-9\,\. ]/gi, '');

    var keys = line.match(/'[^']+'|\S+/g);
    var statement = '';

    if (keys === null) {
        return line + '\n';
    }

    if (keys[0] === GRAMMAR.CREATE_START) {
        var vesselName = generateVesselName(keys);

        statement += generateIndentation(indentLevel) + 'function ' + vesselName  + ' () {' + CHAR.NEWLINE;

        indentLevel++;

        statement += generateIndentation(indentLevel) + 'this.name = ' + CHAR.QUOTE + vesselName + CHAR.QUOTE + CHAR.SEMICOLON + CHAR.NEWLINE;
    }

    if (keys[0] === GRAMMAR.CREATE_END) {
        indentLevel--;

        statement += generateIndentation(indentLevel) + '}' + CHAR.NEWLINE;
    }

    if (keys[0] === GRAMMAR.NOTE || keys[0] === GRAMMAR.PROGRAM || keys[0] === GRAMMAR.USAGE) {
        var propertyName = keys[0];
        var propertyValue = generatePropertyValue(keys);

        statement += generateIndentation(indentLevel) + 'this.' + propertyName + ' = ' + CHAR.QUOTE + propertyValue + CHAR.QUOTE + CHAR.SEMICOLON + CHAR.NEWLINE;
    }

    return statement;
};
<|endoftext|>


<commit_before>/**
 * This module provides RQL parsing. For example:
 * var parsed = require("./parser").parse("b=3&le(c,5)");
 */
require.def||(require.def=function(deps, factory){module.exports = factory(require, exports);});
require.def(["require", "exports"], function(require, exports){

exports.jsonQueryCompatible = true;
var operatorMap = {
	"=": "eq",
	"==": "eq",
	">": "gt",
	">=": "ge",
	"<": "lt",
	"<=": "le",
	"!=": "ne"
};

var parseQuery = exports.parse = exports.parseQuery = function(/*String|Object*/query, parameters){
	if (query === undefined)
		query = '';
	var term = new Query();
	var topTerm = term;
	if(typeof query === "object"){
		if(query instanceof Query){
			return query;
		}
		for(var i in query){
			var term = new Query();
			topTerm.args.push(term);
			term.name = "eq";
			term.args = [i, query[i]];
		}
		return topTerm;
	}
	if(query.charAt(0) == "?"){
		throw new URIError("Query must not start with ?");
	}
	if(exports.jsonQueryCompatible){
		query = query.replace(/%3C=/g,"=le=").replace(/%3E=/g,"=ge=").replace(/%3C/g,"=lt=").replace(/%3E/g,"=gt=");
	}
	// convert FIQL to normalized call syntax form
	query = query.replace(/([\+\*\-:\w%\._]+)([<>!]?=(?:[\w]*=)?|>|<)(\([\+\*\$\-:\w%\._,]+\)|[\+\*\$\-:\w%\._]*|)/g,
	                     //<--- property ---><------  operator -----><----------------   value ------------------>
			function(t, property, operator, value){
		if(operator.length < 3){
			if(!operatorMap[operator]){
				throw new URIError("Illegal operator " + operator);
			}
			operator = operatorMap[operator];
		}
		else{
			operator = operator.substring(1, operator.length - 1);
		}
		return operator + '(' + property + "," + value + ")";
	});
	if(query.charAt(0)=="?"){
		query = query.substring(1);
	}
	var leftoverCharacters = query.replace(/(\))|([&\|,])?([\+\*\$\-:\w%\._]*)(\(?)/g,
	                       //    <-closedParan->|<-delim-- propertyOrValue -----(> |
		function(t, closedParan, delim, propertyOrValue, openParan){
			if(delim){
				if(delim === "&"){
					setConjunction("and");
				}
				if(delim === "|"){
					setConjunction("or");
				}
			}
			if(openParan){
				var newTerm = new Query();
				newTerm.name = propertyOrValue,
				newTerm.parent = term;
				call(newTerm);
			}
			else if(closedParan){
				var isArray = !term.name;
				term = term.parent;
				if(!term){
					throw new URIError("Closing paranthesis without an opening paranthesis");
				}
				if(isArray){
					term.args.push(term.args.pop().args);
				}
			}
			else if(propertyOrValue || delim === ','){
				term.args.push(stringToValue(propertyOrValue, parameters));
			}
			return "";
		});
	if(term.parent){
		throw new URIError("Opening paranthesis without a closing paranthesis");
	}
	if(leftoverCharacters){
		// any extra characters left over from the replace indicates invalid syntax
		throw new URIError("Illegal character in query string encountered " + leftoverCharacters);
	}

	function call(newTerm){
		term.args.push(newTerm);
		term = newTerm;
	}
	function setConjunction(operator){
		if(!term.name){
			term.name = operator;
		}
		else if(term.name !== operator){
			throw new Error("Can not mix conjunctions within a group, use paranthesis around each set of same conjuctions (& and |)");
		}
	}
    function removeParentProperty(obj) {
    	if(obj && obj.args){
	    	delete obj.parent;
	    	obj.args.forEach(removeParentProperty);
    	}
        return obj;
    };
    removeParentProperty(topTerm);
    return topTerm;
};

exports.commonOperatorMap = {
	"and" : "&",
	"or" : "|",
	"eq" : "=",
	"ne" : "!=",
	"le" : "<=",
	"ge" : ">=",
	"lt" : "<",
	"gt" : ">"
}
function stringToValue(string, parameters){
	var converter = exports.converters['default'];
	if(string.charAt(0) === "$"){
		var param_index = parseInt(string.substring(1)) - 1;
		return param_index >= 0 && parameters ? parameters[param_index] : undefined;
	}
	if(string.indexOf(":") > -1){
		var parts = string.split(":",2);
		converter = exports.converters[parts[0]];
		if(!converter){
			throw new URIError("Unknown converter " + parts[0]);
		}
		string = parts[1];
	}
	return converter(string);
};

var autoConverted = exports.autoConverted = {
	"true": true,
	"false": false,
	"null": null,
	"undefined": undefined,
	"Infinity": Infinity,
	"-Infinity": -Infinity
};

exports.converters = {
	auto: function(string){
		if(autoConverted.hasOwnProperty(string)){
			return autoConverted[string];
		}
		var number = +string;
		if(isNaN(number) || number.toString() !== string){
/*			var isoDate = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(date);
			if (isoDate) {
				return new Date(Date.UTC(+isoDate[1], +isoDate[2] - 1, +isoDate[3], +isoDate[4], +isoDate[5], +isoDate[6]));
			}*/
			string = decodeURIComponent(string);
			if(exports.jsonQueryCompatible){
				if(string.charAt(0) == "'" && string.charAt(string.length-1) == "'"){
					return JSON.parse('"' + string.substring(1,string.length-1) + '"');
				}
			}
			return string;
		}
		return number;
	},
	number: function(x){
		var number = +x;
		if(isNaN(number)){
			throw new URIError("Invalid number " + number);
		}
		return number;
	},
	epoch: function(x){
		var date = new Date(+x);
		if (isNaN(date.getTime())) {
			throw new URIError("Invalid date " + x);
		}
		return date;
	},
	isodate: function(x){
		// four-digit year
		var date = '0000'.substr(0,4-x.length)+x;
		// pattern for partial dates
		date += '0000-01-01T00:00:00Z'.substring(date.length);
		return exports.converters.date(date);
	},
	date: function(x){
		var isoDate = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(x);
		if (isoDate) {
			date = new Date(Date.UTC(+isoDate[1], +isoDate[2] - 1, +isoDate[3], +isoDate[4], +isoDate[5], +isoDate[6]));
		}else{
			date = new Date(x);
		}
		if (isNaN(date.getTime())){
			throw new URIError("Invalid date " + x);
		}
		return date;

	},
	"boolean": function(x){
		return x === "true";
	},
	string: function(string){
		return decodeURIComponent(string);
	}
};

// exports.converters["default"] can be changed to a different converter if you want
// a different default converter, for example:
// RP = require("rql/parser");
// RP.converters["default"] = RQ.converter.string;
exports.converters["default"] = exports.converters.auto;

var Query = require("./query").Query;
return exports;
});<commit_msg>cache primary key exact match rule<commit_after>/**
 * This module provides RQL parsing. For example:
 * var parsed = require("./parser").parse("b=3&le(c,5)");
 */
require.def||(require.def=function(deps, factory){module.exports = factory(require, exports);});
require.def(["require", "exports"], function(require, exports){

exports.jsonQueryCompatible = true;
var operatorMap = {
	"=": "eq",
	"==": "eq",
	">": "gt",
	">=": "ge",
	"<": "lt",
	"<=": "le",
	"!=": "ne"
};

exports.primaryKeyName = 'id';

var parseQuery = exports.parse = exports.parseQuery = function(/*String|Object*/query, parameters){
	if (query === undefined)
		query = '';
	var term = new Query();
	var topTerm = term;
	if(typeof query === "object"){
		if(query instanceof Query){
			return query;
		}
		for(var i in query){
			var term = new Query();
			topTerm.args.push(term);
			term.name = "eq";
			term.args = [i, query[i]];
		}
		return topTerm;
	}
	if(query.charAt(0) == "?"){
		throw new URIError("Query must not start with ?");
	}
	if(exports.jsonQueryCompatible){
		query = query.replace(/%3C=/g,"=le=").replace(/%3E=/g,"=ge=").replace(/%3C/g,"=lt=").replace(/%3E/g,"=gt=");
	}
	// convert FIQL to normalized call syntax form
	query = query.replace(/([\+\*\-:\w%\._]+)([<>!]?=(?:[\w]*=)?|>|<)(\([\+\*\$\-:\w%\._,]+\)|[\+\*\$\-:\w%\._]*|)/g,
	                     //<--- property ---><------  operator -----><----------------   value ------------------>
			function(t, property, operator, value){
		if(operator.length < 3){
			if(!operatorMap[operator]){
				throw new URIError("Illegal operator " + operator);
			}
			operator = operatorMap[operator];
		}
		else{
			operator = operator.substring(1, operator.length - 1);
		}
		return operator + '(' + property + "," + value + ")";
	});
	if(query.charAt(0)=="?"){
		query = query.substring(1);
	}
	var leftoverCharacters = query.replace(/(\))|([&\|,])?([\+\*\$\-:\w%\._]*)(\(?)/g,
	                       //    <-closedParan->|<-delim-- propertyOrValue -----(> |
		function(t, closedParan, delim, propertyOrValue, openParan){
			if(delim){
				if(delim === "&"){
					setConjunction("and");
				}
				if(delim === "|"){
					setConjunction("or");
				}
			}
			if(openParan){
				var newTerm = new Query();
				newTerm.name = propertyOrValue;
				newTerm.parent = term;
				call(newTerm);
			}
			else if(closedParan){
				var isArray = !term.name;
				term = term.parent;
				if(!term){
					throw new URIError("Closing paranthesis without an opening paranthesis");
				}
				if(isArray){
					term.args.push(term.args.pop().args);
				}
			}
			else if(propertyOrValue || delim === ','){
				term.args.push(stringToValue(propertyOrValue, parameters));
				// cache the last seen id equality
				if (term.name === 'eq' && term.args[0] === exports.primaryKeyName) {
					topTerm.id = term.args.slice(1).toString();
				}
			}
			return "";
		});
	if(term.parent){
		throw new URIError("Opening paranthesis without a closing paranthesis");
	}
	if(leftoverCharacters){
		// any extra characters left over from the replace indicates invalid syntax
		throw new URIError("Illegal character in query string encountered " + leftoverCharacters);
	}

	function call(newTerm){
		term.args.push(newTerm);
		term = newTerm;
	}
	function setConjunction(operator){
		if(!term.name){
			term.name = operator;
		}
		else if(term.name !== operator){
			throw new Error("Can not mix conjunctions within a group, use paranthesis around each set of same conjuctions (& and |)");
		}
	}
    function removeParentProperty(obj) {
    	if(obj && obj.args){
	    	delete obj.parent;
	    	obj.args.forEach(removeParentProperty);
    	}
        return obj;
    };
    removeParentProperty(topTerm);
    return topTerm;
};

exports.commonOperatorMap = {
	"and" : "&",
	"or" : "|",
	"eq" : "=",
	"ne" : "!=",
	"le" : "<=",
	"ge" : ">=",
	"lt" : "<",
	"gt" : ">"
}
function stringToValue(string, parameters){
	var converter = exports.converters['default'];
	if(string.charAt(0) === "$"){
		var param_index = parseInt(string.substring(1)) - 1;
		return param_index >= 0 && parameters ? parameters[param_index] : undefined;
	}
	if(string.indexOf(":") > -1){
		var parts = string.split(":",2);
		converter = exports.converters[parts[0]];
		if(!converter){
			throw new URIError("Unknown converter " + parts[0]);
		}
		string = parts[1];
	}
	return converter(string);
};

var autoConverted = exports.autoConverted = {
	"true": true,
	"false": false,
	"null": null,
	"undefined": undefined,
	"Infinity": Infinity,
	"-Infinity": -Infinity
};

exports.converters = {
	auto: function(string){
		if(autoConverted.hasOwnProperty(string)){
			return autoConverted[string];
		}
		var number = +string;
		if(isNaN(number) || number.toString() !== string){
/*			var isoDate = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(date);
			if (isoDate) {
				return new Date(Date.UTC(+isoDate[1], +isoDate[2] - 1, +isoDate[3], +isoDate[4], +isoDate[5], +isoDate[6]));
			}*/
			string = decodeURIComponent(string);
			if(exports.jsonQueryCompatible){
				if(string.charAt(0) == "'" && string.charAt(string.length-1) == "'"){
					return JSON.parse('"' + string.substring(1,string.length-1) + '"');
				}
			}
			return string;
		}
		return number;
	},
	number: function(x){
		var number = +x;
		if(isNaN(number)){
			throw new URIError("Invalid number " + number);
		}
		return number;
	},
	epoch: function(x){
		var date = new Date(+x);
		if (isNaN(date.getTime())) {
			throw new URIError("Invalid date " + x);
		}
		return date;
	},
	isodate: function(x){
		// four-digit year
		var date = '0000'.substr(0,4-x.length)+x;
		// pattern for partial dates
		date += '0000-01-01T00:00:00Z'.substring(date.length);
		return exports.converters.date(date);
	},
	date: function(x){
		var isoDate = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(x);
		if (isoDate) {
			date = new Date(Date.UTC(+isoDate[1], +isoDate[2] - 1, +isoDate[3], +isoDate[4], +isoDate[5], +isoDate[6]));
		}else{
			date = new Date(x);
		}
		if (isNaN(date.getTime())){
			throw new URIError("Invalid date " + x);
		}
		return date;

	},
	"boolean": function(x){
		return x === "true";
	},
	string: function(string){
		return decodeURIComponent(string);
	}
};

// exports.converters["default"] can be changed to a different converter if you want
// a different default converter, for example:
// RP = require("rql/parser");
// RP.converters["default"] = RQ.converter.string;
exports.converters["default"] = exports.converters.auto;

var Query = require("./query").Query;
return exports;
});
<|endoftext|>


<commit_before>'use strict';

var CHAR = Object.freeze({
    COMMA: ',',
    EMPTY: '',
    NEWLINE: '\n',
    QUOTE: '\'',
    SEMICOLON: ';',
    SPACE: ' ',
    TAB: '    '
});

var GRAMMAR = Object.freeze({
    COLOR: 'paint',
    COMMENT: '#',
    CREATE_START: 'create',
    CREATE_END: 'leave',
    FEEDBACK: 'feedback',
    NAME: 'name',
    NOTE: 'note',
    PROGRAM: 'program',
    USAGE: 'usage'
});

var indentLevel;

var generateIndent = function () {
    var indent = '';

    for (var i = 0; i < indentLevel; i++) {
        indent += CHAR.TAB;
    }

    return indent;
};

var generateVesselName = function (keys) {
    keys.shift();

    return keys.join('_');
};

var generatePropertyName = function (vessel, property) {
    return vessel + '_' + property;
};

var generatePropertyValue = function (keys) {
    keys.shift();

    return keys.join(' ');
};

var generateTernaryStatement = function (cond, tExpression, fExpression) {
    return cond + ' ? ' + tExpression + ' : ' + fExpression;
};

var generateUndefinedCheck = function (variable, tExpression, fExpression) {
    return generateTernaryStatement('typeof ' + variable + ' === ' + CHAR.QUOTE + 'undefined' + CHAR.QUOTE, tExpression, fExpression);
};

var parentVessel;

var getParentVessel = function () {
    return parentVessel[parentVessel.length - 1];
};

var currentVessel;
var children;

var Parser = function () {
    this.parse = function (line) {
        line = line.replace(/[^A-Z0-9#\,\.\s]/gi, '');

        var keys = line.match(/'[^']+'|\S+/g);
        var statement = '';

        if (keys === null) {
            return line + CHAR.NEWLINE;
        }

        if (keys[0] === GRAMMAR.COMMENT) {
            return CHAR.EMPTY;
        }

        if (keys[0] === GRAMMAR.CREATE_START) {
            var vesselName = generateVesselName(keys);

            if (currentVessel) {
                parentVessel.push(currentVessel);
            }

            currentVessel = vesselName;

            if (getParentVessel()) {
                if (typeof children[getParentVessel()] === 'undefined') {
                    children[getParentVessel()] = [];
                }

                children[getParentVessel()].push(currentVessel);
            }

            if (indentLevel === 0) {
                statement += generateIndent() + '(function () {' + CHAR.NEWLINE;
            } else {
                statement += generateIndent() + 'var ' + vesselName  + ' = (function () {' + CHAR.NEWLINE;
            }

            indentLevel++;

            statement += generateIndent() + 'var ' + generatePropertyName(currentVessel, GRAMMAR.NAME) + ' = ' + CHAR.QUOTE + vesselName + CHAR.QUOTE + CHAR.SEMICOLON + CHAR.NEWLINE;
        }

        if (keys[0] === GRAMMAR.CREATE_END) {

            statement += generateIndent() + 'return {' + CHAR.NEWLINE;

            indentLevel++;

            var properties = [GRAMMAR.NAME, GRAMMAR.NOTE, GRAMMAR.PROGRAM, GRAMMAR.USAGE];

            for (var i in properties) {
                statement += generateIndent() + properties[i] + ': ' + generateUndefinedCheck(generatePropertyName(currentVessel, properties[i]), CHAR.QUOTE + CHAR.QUOTE, currentVessel + '_' + properties[i]) + CHAR.NEWLINE;
            }

            statement += generateIndent() + 'children' + ': ' + '[' + CHAR.NEWLINE;

            indentLevel++;

            for (var i in children[currentVessel]) {
                statement += generateIndent() + children[currentVessel][i] + CHAR.COMMA + CHAR.NEWLINE;
            }

            currentVessel = parentVessel.pop();

            indentLevel--;

            statement += generateIndent() + ']' + CHAR.NEWLINE

            indentLevel--;

            statement += generateIndent() + '}' + CHAR.SEMICOLON + CHAR.NEWLINE;

            indentLevel--;

            statement += generateIndent() + '})();' + CHAR.NEWLINE;
        }

        if (keys[0] === GRAMMAR.FEEDBACK || keys[0] === GRAMMAR.NOTE || keys[0] === GRAMMAR.PROGRAM || keys[0] === GRAMMAR.USAGE) {
            var propertyName = keys[0];
            var propertyValue = generatePropertyValue(keys);

            statement += generateIndent() + 'var ' + generatePropertyName(currentVessel, propertyName) + ' = ' + CHAR.QUOTE + propertyValue + CHAR.QUOTE + CHAR.SEMICOLON + CHAR.NEWLINE;
        }

        return statement;
    };

    this.reset = function () {
        indentLevel = 0;
        parentVessel = [];
        currentVessel = null;
        children = {};
    };

    this.reset();
};

module.exports = Parser;
<commit_msg>Switch to shorter constructor name<commit_after>'use strict';

var CHAR = Object.freeze({
    COMMA: ',',
    EMPTY: '',
    NEWLINE: '\n',
    QUOTE: '\'',
    SEMICOLON: ';',
    SPACE: ' ',
    TAB: '    '
});

var GRAMMAR = Object.freeze({
    COLOR: 'paint',
    COMMENT: '#',
    CREATE_START: 'create',
    CREATE_END: 'leave',
    FEEDBACK: 'feedback',
    NAME: 'name',
    NOTE: 'note',
    PROGRAM: 'program',
    USAGE: 'usage'
});

var indentLevel;

var createIndent = function () {
    var indent = '';

    for (var i = 0; i < indentLevel; i++) {
        indent += CHAR.TAB;
    }

    return indent;
};

var createVesselName = function (keys) {
    keys.shift();

    return keys.join('_');
};

var createPropertyName = function (vessel, property) {
    return vessel + '_' + property;
};

var createPropertyValue = function (keys) {
    keys.shift();

    return keys.join(' ');
};

var createTernaryStatement = function (cond, tExpression, fExpression) {
    return cond + ' ? ' + tExpression + ' : ' + fExpression;
};

var createUndefinedCheck = function (variable, tExpression, fExpression) {
    return createTernaryStatement('typeof ' + variable + ' === ' + CHAR.QUOTE + 'undefined' + CHAR.QUOTE, tExpression, fExpression);
};

var parentVessel;

var getParentVessel = function () {
    return parentVessel[parentVessel.length - 1];
};

var currentVessel;
var children;

var Parser = function () {
    this.parse = function (line) {
        line = line.replace(/[^A-Z0-9#\,\.\s]/gi, '');

        var keys = line.match(/'[^']+'|\S+/g);
        var statement = '';

        if (keys === null) {
            return line + CHAR.NEWLINE;
        }

        if (keys[0] === GRAMMAR.COMMENT) {
            return CHAR.EMPTY;
        }

        if (keys[0] === GRAMMAR.CREATE_START) {
            var vesselName = createVesselName(keys);

            if (currentVessel) {
                parentVessel.push(currentVessel);
            }

            currentVessel = vesselName;

            if (getParentVessel()) {
                if (typeof children[getParentVessel()] === 'undefined') {
                    children[getParentVessel()] = [];
                }

                children[getParentVessel()].push(currentVessel);
            }

            if (indentLevel === 0) {
                statement += createIndent() + '(function () {' + CHAR.NEWLINE;
            } else {
                statement += createIndent() + 'var ' + vesselName  + ' = (function () {' + CHAR.NEWLINE;
            }

            indentLevel++;

            statement += createIndent() + 'var ' + createPropertyName(currentVessel, GRAMMAR.NAME) + ' = ' + CHAR.QUOTE + vesselName + CHAR.QUOTE + CHAR.SEMICOLON + CHAR.NEWLINE;
        }

        if (keys[0] === GRAMMAR.CREATE_END) {

            statement += createIndent() + 'return {' + CHAR.NEWLINE;

            indentLevel++;

            var properties = [GRAMMAR.NAME, GRAMMAR.NOTE, GRAMMAR.PROGRAM, GRAMMAR.USAGE];

            for (var i in properties) {
                statement += createIndent() + properties[i] + ': ' + createUndefinedCheck(createPropertyName(currentVessel, properties[i]), CHAR.QUOTE + CHAR.QUOTE, currentVessel + '_' + properties[i]) + CHAR.NEWLINE;
            }

            statement += createIndent() + 'children' + ': ' + '[' + CHAR.NEWLINE;

            indentLevel++;

            for (var i in children[currentVessel]) {
                statement += createIndent() + children[currentVessel][i] + CHAR.COMMA + CHAR.NEWLINE;
            }

            currentVessel = parentVessel.pop();

            indentLevel--;

            statement += createIndent() + ']' + CHAR.NEWLINE

            indentLevel--;

            statement += createIndent() + '}' + CHAR.SEMICOLON + CHAR.NEWLINE;

            indentLevel--;

            statement += createIndent() + '})();' + CHAR.NEWLINE;
        }

        if (keys[0] === GRAMMAR.FEEDBACK || keys[0] === GRAMMAR.NOTE || keys[0] === GRAMMAR.PROGRAM || keys[0] === GRAMMAR.USAGE) {
            var propertyName = keys[0];
            var propertyValue = createPropertyValue(keys);

            statement += createIndent() + 'var ' + createPropertyName(currentVessel, propertyName) + ' = ' + CHAR.QUOTE + propertyValue + CHAR.QUOTE + CHAR.SEMICOLON + CHAR.NEWLINE;
        }

        return statement;
    };

    this.reset = function () {
        indentLevel = 0;
        parentVessel = [];
        currentVessel = null;
        children = {};
    };

    this.reset();
};

module.exports = Parser;
<|endoftext|>


<commit_before>function Player(context){
  this.x = 16;
  this.y = 10;
  this.direction = 0;
  this.rotation = 0;
  this.speed = 0;
  this.moveSpeed = 0.18;
  this.rotSpeed = 6;
  this.pillCount = 0;
  this.ctx = context;
}

Player.prototype.move = function(map){
  var moveStep = this.speed * this.moveSpeed;
  this.rotation += this.direction * this.rotSpeed * Math.PI / 180;

  // var newX = this.calcMovement(this.x, Math.cos);
  // var newY = this.calcMovement(this.y, Math.sin);
  var newX = this.x + Math.cos(this.rotation) * moveStep;
  var newY = this.y + Math.sin(this.rotation) * moveStep;

  if (this.blockCheck(newX, this.y, map).type <= 0) { this.x = newX; };
  if (this.blockCheck(this.x, newY, map).type <= 0) { this.y = newY; };
}

// pass this in during gameplay loop
var scale = 12;

Player.prototype.draw = function(){
  this.ctx.fillStyle = "red";
  this.ctx.fillRect(this.x * scale - 2, this.y * scale - 2, 4, 4);

  this.ctx.beginPath();
  this.ctx.moveTo(this.x * scale, this.y * scale);
  this.ctx.lineTo(
    (this.x + Math.cos(this.rotation) * 4) * scale,
    (this.y + Math.sin(this.rotation) * 4) * scale
  );
  this.ctx.closePath();
  this.ctx.stroke();
}

// need to un-tangle map and player into clean game class
Player.prototype.update = function(map){
  this.move(map);

  // if (this.blockCheck(this.x, this.y, map) < 0) { console.log('pill!'); };
  if (this.blockCheck(this.x, this.y, map).type < 0) {
    this.blockCheck(this.x, this.y, map).changeType();
    this.pillCount++;
  };

  this.draw();
}

Player.prototype.blockCheck = function(x, y, map){
  return map.grid[Math.floor(y)][Math.floor(x)];
}

Player.prototype.calcMovement = function(position, calc){
  var moveStep = this.speed * this.moveSpeed;
  this.rotation += this.direction * this.rotSpeed * Math.PI / 180;
  return position + calc(this.rotation) * moveStep;
}

module.exports = Player;
<commit_msg>Remove unneeded calcMovement function<commit_after>function Player(context){
  this.x = 16;
  this.y = 10;
  this.direction = 0;
  this.rotation = 0;
  this.speed = 0;
  this.moveSpeed = 0.18;
  this.rotSpeed = 6;
  this.pillCount = 0;
  this.ctx = context;
}

Player.prototype.move = function(map){
  var moveStep = this.speed * this.moveSpeed;
  this.rotation += this.direction * this.rotSpeed * Math.PI / 180;

  var newX = this.x + Math.cos(this.rotation) * moveStep;
  var newY = this.y + Math.sin(this.rotation) * moveStep;

  if (this.blockCheck(newX, this.y, map).type <= 0) { this.x = newX; };
  if (this.blockCheck(this.x, newY, map).type <= 0) { this.y = newY; };
}

// pass this in during gameplay loop
var scale = 12;

Player.prototype.draw = function(){
  this.ctx.fillStyle = "red";
  this.ctx.fillRect(this.x * scale - 2, this.y * scale - 2, 4, 4);

  this.ctx.beginPath();
  this.ctx.moveTo(this.x * scale, this.y * scale);
  this.ctx.lineTo(
    (this.x + Math.cos(this.rotation) * 4) * scale,
    (this.y + Math.sin(this.rotation) * 4) * scale
  );
  this.ctx.closePath();
  this.ctx.stroke();
}

// need to un-tangle map and player into clean game class
Player.prototype.update = function(map){
  this.move(map);

  // if (this.blockCheck(this.x, this.y, map) < 0) { console.log('pill!'); };
  if (this.blockCheck(this.x, this.y, map).type < 0) {
    this.blockCheck(this.x, this.y, map).changeType();
    this.pillCount++;
  };

  this.draw();
}

Player.prototype.blockCheck = function(x, y, map){
  return map.grid[Math.floor(y)][Math.floor(x)];
}

module.exports = Player;
<|endoftext|>


<commit_before>var _ = require('underscore'),
    path = require('path');
const corePlugins = [
    'mixin',
    'styles-output', 'scripts-output', 'static-output',
    'scope', 'router', 'template', 'inline-styles',
    'coffee-script', 'stylus', 'handlebars',
    'module-map', 'package-config', 'stylus-config',
    'update-externals',
    'inline-styles-resources', 'styles', 'scripts', 'static'];
var fileUtils = require("./fileUtil");

var globalPlugins = {};

exports.plugin = function(name, plugin) {
  globalPlugins[name] = plugin;
  plugin.id = name;
};

exports.plugin('module-map', require('./plugins/module-map'));
exports.plugin('package-config', require('./plugins/package-config'));
exports.plugin('router', require('./plugins/router'));
exports.plugin('scope', require('./plugins/scope'));
exports.plugin('stylus', require('./plugins/stylus'));
exports.plugin('stylus-config', require('./plugins/stylus-config'));
exports.plugin('coffee-script', require('./plugins/coffee-script'));
exports.plugin('handlebars', require('./plugins/handlebars'));
exports.plugin('inline-styles', require('./plugins/inline-styles'));
exports.plugin('inline-styles-resources', require('./plugins/inline-styles-resources'));
exports.plugin('mixin', require('./plugins/mixin'));
exports.plugin('update-externals', require('./plugins/update-externals'));
exports.plugin('template', require('./plugins/template'));
exports.plugin('styles', require('./plugins/styles.js'));
exports.plugin('scripts', require('./plugins/scripts.js'));
exports.plugin('static', require('./plugins/static.js'));
exports.plugin('styles-output', require('./plugins/styles-output.js'));
exports.plugin('scripts-output', require('./plugins/scripts-output.js'));
exports.plugin('static-output', require('./plugins/static-output.js'));

exports.create = function(options) {
  var plugins;
  var modes; // all registered modes
  var pluginModes; // map of modes and plugins scoped to the mode
  var modeAll; // plugins that are scoped to all modes

  function runPlugins(context, methodName, complete, failOver, noMode) {
    var len = 0;
    return (function next(complete) {
      var plugin;
      while (plugin = plugins[len++]) {
        // if plugin shouldn't work with current mode, go to next
        if (!noMode && (!context.mode || pluginModes[context.mode].indexOf(plugin) < 0) && modeAll.indexOf(plugin) < 0) {
          continue;
        }

        var method = plugin[methodName];
        if (method) {
          if (complete) {
            process.nextTick(function() {
              method.call(plugin, context, next, complete);
            });
            return;
          } else {
            return method.call(plugin, context, next, complete);
          }
        }
      }

      // We're done, send data back
      if (complete) {
        // async
        // Clear out our stack under async mode to try to keep the stack somewhat sane.
        process.nextTick(function() {
          complete(undefined, failOver && failOver());
        });
      } else {
        // sync
        return failOver && failOver();
      }
    })(complete);
  }

  function registerPlugin(plugin) {
    var _plugin = globalPlugins[plugin] || plugin;

    var mode = _plugin.mode;
    if (mode) {
      if (_.isString(mode)) {
        mode = [mode];
      }
      _.each(mode, function(_mode) {
        if (mode === 'all') {
          // allow plugins to contribute new modes and participate in all modes
          modeAll.push(_plugin);
        } else {
          if (modes.indexOf(_mode) < 0) {
            modes.push(_mode);
            pluginModes[_mode] = [];
          }
          pluginModes[_mode].push(_plugin);
        }
      });
    } else {
      modeAll.push(_plugin);
    }
    plugins.push(_plugin);
    plugins.sort(function(a, b) {
      return (a.priority || 50) - (b.priority || 50);
    });
  }

  return {
    get: function(name) {
      // Find the plugin with this id, if one exists
      var plugin = plugins.reduce(function(plugin, left) {
        return plugin.id === name ? plugin : left;
      });

      // If the plugin was not found do not return the last item in the reduce
      if (plugin.id === name) {
        return plugin;
      }
    },
    use: function(plugin) {
      if (plugin.path || (_.isString(plugin) && !globalPlugins[plugin])) {
        var pluginPath = plugin.path || plugin;
        var options = plugin.options;
        try {
          plugin = require(pluginPath);
        } catch (e) {
          plugin = require(path.resolve(process.cwd(), fileUtils.lookupPath()) + '/node_modules/' + pluginPath);
        }
        if ('function' === typeof plugin) {
          plugin = plugin(options);
        }
      }
      registerPlugin(plugin);
    },

    initialize: function(config) {
      // reset
      plugins = [];
      modes = []; // all registered modes
      pluginModes = {}; // map of modes and plugins scoped to the mode
      modeAll = []; // plugins that are scoped to all modes

      // load the core plugins
      if (!options.ignoreCorePlugins) {
        corePlugins.forEach(registerPlugin);
      }

      var self = this;
      function plugin(plugins) {
        if (plugins) {
          plugins.forEach(self.use, self);
        }
      }

      // load command line plugins
      plugin(options.plugins);

      // load lumbar.json plugins
      plugin(config.attributes.plugins);
    },

    loadMixin: function(context, complete) {
      runPlugins(context, 'loadMixin', complete, undefined, true);
    },
    loadConfig: function(context, complete) {
      runPlugins(context, 'loadConfig', complete, undefined, true);
    },
    outputConfigs: function(context, complete) {
      runPlugins(context, 'outputConfigs', complete, function() {
        // Default to a one to one mapping for a given {platform, package, module, mode} combo
        return [ {} ];
      });
    },
    modeComplete: function(context, complete) {
      runPlugins(context, 'modeComplete', complete);
    },
    fileName: function(context, complete) {
      runPlugins(context, 'fileName', complete);
    },

    fileFilter: function(context) {
      return runPlugins(context, 'fileFilter');
    },
    moduleResources: function(context, complete) {
      runPlugins(context, 'moduleResources', complete, function() {
        var module = context.module;
        return (module[context.mode] || []).slice();
      });
    },
    resourceList: function(context, complete) {
      runPlugins(context, 'resourceList', complete, function() { return [context.resource]; });
    },

    file: function(context, complete) {
      runPlugins(context, 'file', complete);
    },
    module: function(context, complete) {
      runPlugins(context, 'module', complete);
    },
    resource: function(context, complete) {
      runPlugins(context, 'resource', complete, function() { return context.resource; });
    },
    modes: function() {
      return modes;
    }
  };
};
<commit_msg>Cache pluginModes value<commit_after>var _ = require('underscore'),
    path = require('path');
const corePlugins = [
    'mixin',
    'styles-output', 'scripts-output', 'static-output',
    'scope', 'router', 'template', 'inline-styles',
    'coffee-script', 'stylus', 'handlebars',
    'module-map', 'package-config', 'stylus-config',
    'update-externals',
    'inline-styles-resources', 'styles', 'scripts', 'static'];
var fileUtils = require("./fileUtil");

var globalPlugins = {};

exports.plugin = function(name, plugin) {
  globalPlugins[name] = plugin;
  plugin.id = name;
};

exports.plugin('module-map', require('./plugins/module-map'));
exports.plugin('package-config', require('./plugins/package-config'));
exports.plugin('router', require('./plugins/router'));
exports.plugin('scope', require('./plugins/scope'));
exports.plugin('stylus', require('./plugins/stylus'));
exports.plugin('stylus-config', require('./plugins/stylus-config'));
exports.plugin('coffee-script', require('./plugins/coffee-script'));
exports.plugin('handlebars', require('./plugins/handlebars'));
exports.plugin('inline-styles', require('./plugins/inline-styles'));
exports.plugin('inline-styles-resources', require('./plugins/inline-styles-resources'));
exports.plugin('mixin', require('./plugins/mixin'));
exports.plugin('update-externals', require('./plugins/update-externals'));
exports.plugin('template', require('./plugins/template'));
exports.plugin('styles', require('./plugins/styles.js'));
exports.plugin('scripts', require('./plugins/scripts.js'));
exports.plugin('static', require('./plugins/static.js'));
exports.plugin('styles-output', require('./plugins/styles-output.js'));
exports.plugin('scripts-output', require('./plugins/scripts-output.js'));
exports.plugin('static-output', require('./plugins/static-output.js'));

exports.create = function(options) {
  var plugins;
  var modes; // all registered modes
  var pluginModes; // map of modes and plugins scoped to the mode
  var modeAll; // plugins that are scoped to all modes

  function runPlugins(context, methodName, complete, failOver, noMode) {
    var len = 0,
        pluginMode = pluginModes[context.mode] || [];

    return (function next(complete) {
      var plugin;
      while (plugin = plugins[len++]) {
        // if plugin shouldn't work with current mode, go to next
        if (!noMode
            && (!context.mode || pluginMode.indexOf(plugin) < 0)
            && modeAll.indexOf(plugin) < 0) {
          continue;
        }

        var method = plugin[methodName];
        if (method) {
          if (complete) {
            process.nextTick(function() {
              method.call(plugin, context, next, complete);
            });
            return;
          } else {
            return method.call(plugin, context, next, complete);
          }
        }
      }

      // We're done, send data back
      if (complete) {
        // async
        // Clear out our stack under async mode to try to keep the stack somewhat sane.
        process.nextTick(function() {
          complete(undefined, failOver && failOver());
        });
      } else {
        // sync
        return failOver && failOver();
      }
    })(complete);
  }

  function registerPlugin(plugin) {
    var _plugin = globalPlugins[plugin] || plugin;

    var mode = _plugin.mode;
    if (mode) {
      if (_.isString(mode)) {
        mode = [mode];
      }
      _.each(mode, function(_mode) {
        if (mode === 'all') {
          // allow plugins to contribute new modes and participate in all modes
          modeAll.push(_plugin);
        } else {
          if (modes.indexOf(_mode) < 0) {
            modes.push(_mode);
            pluginModes[_mode] = [];
          }
          pluginModes[_mode].push(_plugin);
        }
      });
    } else {
      modeAll.push(_plugin);
    }
    plugins.push(_plugin);
    plugins.sort(function(a, b) {
      return (a.priority || 50) - (b.priority || 50);
    });
  }

  return {
    get: function(name) {
      // Find the plugin with this id, if one exists
      var plugin = plugins.reduce(function(plugin, left) {
        return plugin.id === name ? plugin : left;
      });

      // If the plugin was not found do not return the last item in the reduce
      if (plugin.id === name) {
        return plugin;
      }
    },
    use: function(plugin) {
      if (plugin.path || (_.isString(plugin) && !globalPlugins[plugin])) {
        var pluginPath = plugin.path || plugin;
        var options = plugin.options;
        try {
          plugin = require(pluginPath);
        } catch (e) {
          plugin = require(path.resolve(process.cwd(), fileUtils.lookupPath()) + '/node_modules/' + pluginPath);
        }
        if ('function' === typeof plugin) {
          plugin = plugin(options);
        }
      }
      registerPlugin(plugin);
    },

    initialize: function(config) {
      // reset
      plugins = [];
      modes = []; // all registered modes
      pluginModes = {}; // map of modes and plugins scoped to the mode
      modeAll = []; // plugins that are scoped to all modes

      // load the core plugins
      if (!options.ignoreCorePlugins) {
        corePlugins.forEach(registerPlugin);
      }

      var self = this;
      function plugin(plugins) {
        if (plugins) {
          plugins.forEach(self.use, self);
        }
      }

      // load command line plugins
      plugin(options.plugins);

      // load lumbar.json plugins
      plugin(config.attributes.plugins);
    },

    loadMixin: function(context, complete) {
      runPlugins(context, 'loadMixin', complete, undefined, true);
    },
    loadConfig: function(context, complete) {
      runPlugins(context, 'loadConfig', complete, undefined, true);
    },
    outputConfigs: function(context, complete) {
      runPlugins(context, 'outputConfigs', complete, function() {
        // Default to a one to one mapping for a given {platform, package, module, mode} combo
        return [ {} ];
      });
    },
    modeComplete: function(context, complete) {
      runPlugins(context, 'modeComplete', complete);
    },
    fileName: function(context, complete) {
      runPlugins(context, 'fileName', complete);
    },

    fileFilter: function(context) {
      return runPlugins(context, 'fileFilter');
    },
    moduleResources: function(context, complete) {
      runPlugins(context, 'moduleResources', complete, function() {
        var module = context.module;
        return (module[context.mode] || []).slice();
      });
    },
    resourceList: function(context, complete) {
      runPlugins(context, 'resourceList', complete, function() { return [context.resource]; });
    },

    file: function(context, complete) {
      runPlugins(context, 'file', complete);
    },
    module: function(context, complete) {
      runPlugins(context, 'module', complete);
    },
    resource: function(context, complete) {
      runPlugins(context, 'resource', complete, function() { return context.resource; });
    },
    modes: function() {
      return modes;
    }
  };
};
<|endoftext|>


<commit_before>/**
 * @module poller
 * @description
 * A Poller for Endpoints
 */

"use strict";

// built-in modules
var events = require("events");
var util = require("util");

// npm-installed modules
var _ = require("lodash");

// own modules
var utils = require("./utils");

/**
 * Poller Class. Inherits from events.EventEmitter. This poller
 * is designed in that it polls for new updates automatically
 * without having you implement `lastreadId` logic.
 *
 * @example
 * // create a new poller that keeps retrieiving traffic updates
 * var poller = new sdk.Poller(sdk.trafficUpdates.get, {
 *   interval: 5000, // 5 seconds
 * });
 *
 * // listen for new updates
 * poller.on("message", function(updates, meta, responseObject) {
 *   console.log("received these updates: %j", updates);
 * });
 *
 * // listen for errors e.g. network failures etc.
 * // if an error occurs an you not listening on the "error"
 * // event, the error will bubble up to the domain/process.
 * poller.on("error", function(err) {
 *   console.log("error: %s", err);
 * });
 *
 * // you have to explicitly start it
 * poller.start();
 *
 * // lets say we close it after a minute or so
 * setTimeout(function() {
 *   poller.stop();
 * }, 1000 * 60);
 *
 * @constructor
 * @param  {itemsGetRequest} getRequest
 * @param  {Object} [options]
 * @param  {Object|Function} [options.params] - parameters passed to get request.
 *      If `options.params` is a function, it is called and it return value is
 *      assumed an object as the request params.
 *      If `options.params` requires to do an asynchronous action, it is passed a
 *      `done` function as its only argument to call with the value when done.
 * @param  {Integer} [options.interval=5000] - configures the poller's timer
 */
function Poller(getRequest, options) {
    options = options || { };
    events.EventEmitter.call(this);
    this._pollerOptions = utils.getPollerOptions([utils.setup().poller, options]);
    this._get = getRequest;
    this._params = options.params || { };
    this._lastreadId = this._params.lastreadId || null;
    this._timer = null;
    return this;
}

// inherit from the EventEmitter class
util.inherits(Poller, events.EventEmitter);

/**
 * Starts the poller
 */
Poller.prototype.start = function start() {
    var me = this;
    function sendRequest(args) {
        me._get(args, function(err, items, meta, res) {
            if (err) {
                return me.emit("error", err);
            }
            // emit 'message' event if we received items
            if (items.length) {
                me._params.lastreadId = items[items.length - 1].id;
                return me.emit("message", items, meta, res);
            }
            return;
        });
    }
    me._timer = setInterval(function() {
        var args = { };
        if (me._lastreadId) {
            args.lastreadId = me._lastreadId;
        }
        if (_.isFunction(me._params)) {
            if (me._params.length) {
                return me._params(function(params) {
                    _.merge(args, params);
                    return sendRequest(args);
                });
            }
            _.merge(args, me._params());
        } else {
            _.merge(args, me._params);
        }
        return sendRequest(args);
    }, me._pollerOptions.interval);
};

/**
 * Stops the poller
 */
Poller.prototype.stop = function stop() {
    this._timer.close();
    this.removeAllListeners();
    return this;
};

// exporting the constructor
exports = module.exports = Poller;
exports.Poller = Poller;
<commit_msg>Fix error reported by eslint<commit_after>/**
 * @module poller
 * @description
 * A Poller for Endpoints
 */

"use strict";

// built-in modules
var events = require("events");
var util = require("util");

// npm-installed modules
var _ = require("lodash");

// own modules
var utils = require("./utils");

/**
 * Poller Class. Inherits from events.EventEmitter. This poller
 * is designed in that it polls for new updates automatically
 * without having you implement `lastreadId` logic.
 *
 * @example
 * // create a new poller that keeps retrieiving traffic updates
 * var poller = new sdk.Poller(sdk.trafficUpdates.get, {
 *   interval: 5000, // 5 seconds
 * });
 *
 * // listen for new updates
 * poller.on("message", function(updates, meta, responseObject) {
 *   console.log("received these updates: %j", updates);
 * });
 *
 * // listen for errors e.g. network failures etc.
 * // if an error occurs an you not listening on the "error"
 * // event, the error will bubble up to the domain/process.
 * poller.on("error", function(err) {
 *   console.log("error: %s", err);
 * });
 *
 * // you have to explicitly start it
 * poller.start();
 *
 * // lets say we close it after a minute or so
 * setTimeout(function() {
 *   poller.stop();
 * }, 1000 * 60);
 *
 * @constructor
 * @param  {itemsGetRequest} getRequest
 * @param  {Object} [options]
 * @param  {Object|Function} [options.params] - parameters passed to get request.
 *      If `options.params` is a function, it is called and it return value is
 *      assumed an object as the request params.
 *      If `options.params` requires to do an asynchronous action, it is passed a
 *      `done` function as its only argument to call with the value when done.
 * @param  {Integer} [options.interval=5000] - configures the poller's timer
 */
function Poller(getRequest, options) {
    options = options || { };
    events.EventEmitter.call(this);
    this._pollerOptions = utils.getPollerOptions([utils.setup().poller, options]);
    this._get = getRequest;
    this._params = options.params || { };
    this._lastreadId = this._params.lastreadId || null;
    this._timer = null;
    return this;
}

// inherit from the EventEmitter class
util.inherits(Poller, events.EventEmitter);

/**
 * Starts the poller
 */
Poller.prototype.start = function start() {
    var me = this;
    function sendRequest(args) {
        me._get(args, function(err, items, meta, res) {
            if (err) {
                return me.emit("error", err);
            }
            // emit 'message' event if we received items
            if (items.length) {
                me._params.lastreadId = items[items.length - 1].id;
                return me.emit("message", items, meta, res);
            }
            return null;
        });
    }
    me._timer = setInterval(function() {
        var args = { };
        if (me._lastreadId) {
            args.lastreadId = me._lastreadId;
        }
        if (_.isFunction(me._params)) {
            if (me._params.length) {
                return me._params(function(params) {
                    _.merge(args, params);
                    return sendRequest(args);
                });
            }
            _.merge(args, me._params());
        } else {
            _.merge(args, me._params);
        }
        return sendRequest(args);
    }, me._pollerOptions.interval);
};

/**
 * Stops the poller
 */
Poller.prototype.stop = function stop() {
    this._timer.close();
    this.removeAllListeners();
    return this;
};

// exporting the constructor
exports = module.exports = Poller;
exports.Poller = Poller;
<|endoftext|>


<commit_before>var async = require('async'),
  Playlist = require('./playlist'),
  roomba = require('roomba');

function Roomba() {
  this.playlist = new Playlist();
}

Roomba.prototype.power = function (_opts, cb) {

  console.log('Loading songs on %s', _opts.dir);
  this.playlist.load(_opts.dir);

  var opts = {
    sp: {
      path: _opts.path || '/dev/tty.roomba',
      options: {
        baudrate: _opts.baudrate || 57600
      }
    },
    update_freq: 200
  };

  console.log(
    'Starting Roombox with path %s at baudrate %d',
    opts.sp.path,
    opts.sp.options.baudrate);

  this.bot = new roomba.Roomba(opts);
  this.bot.once('ready', cb);
};

Roomba.prototype.play = function (trackNumber, cb) {
  const MAX_SEGMENTS = 4,
    MAX_NOTES = 16,
    INTERVAL = 200;

  var song = this.playlist.getSong(trackNumber),
    self = this;

  console.log('Preparing track %d: %s - %s',
    trackNumber, song.title, song.by);

  var numNotes = song.notes.length,
    numSegments = Math.min(Math.ceil(numNotes / MAX_NOTES), MAX_SEGMENTS),
    segments = [];

  for (var i = 0; i < numSegments; i += 1) {

    var start = i * MAX_NOTES,
      end = start + MAX_NOTES,
      segmentNotes = song.notes.slice(start, end);
      data = [i, segmentNotes.length],
      duration = 0;

    segmentNotes.forEach(function (note) {
      note[1] = Math.ceil(note[1] / 1.7);
      data = data.concat(note);
      duration += note[1];
    });
    segments.push({ index: i, notes: segmentNotes, duration: duration });

    self.bot.send({ cmd: 'SONG', data: data });
  }

  function play(segment, cb) {
    console.log('Playing segment %d with duration %d ms', segment.index, segment.duration * 1000 / 64);
    self.bot.send({ cmd: 'PLAY', data: [segment.index] });
    setTimeout(cb, INTERVAL + (segment.duration * 1000 / 64));
  }

  async.eachSeries(segments, play, cb);
};

module.exports = Roomba;<commit_msg>Replace roomba with roombox.<commit_after><|endoftext|>


<commit_before>Router.configure({
  layoutTemplate: 'layout',
  loadingTemplate: 'loading',
  notFoundTemplate: 'notFound',
  waitOn: function() {
    return [Meteor.subscribe('notifications')]
  }
});

Router.route('/posts/:_id', {
  name: 'postPage',
  waitOn: function() {
    return Meteor.subscribe('comments', this.params._id);
  },
  data: function() { return Posts.findOne(this.params._id); }
});

Router.route('/posts/:_id/edit', {
  name: 'postEdit',
  data: function() { return Posts.findOne(this.params._id); }
});

Router.route('/submit', {name: 'postSubmit'});

Router.route('/:postsLimit?', {
  name: 'postsList',
  waitOn: function() {
    var limit = parseInt(this.params.postsLimit) || 5;
    return Meteor.subscribe('posts', {sort: {submitted: -1}, limit: limit});
  },
  data: function() {
    var limit = parseInt(this.params.postsLimit) || 5;
    return {
      posts: Posts.find({}, {sort: {submitted: -1}, limit: limit})
    };
  }
});

var requireLogin = function() {
  if (! Meteor.user()) {
    if (Meteor.loggingIn()) {
      this.render(this.loadingTemplate);
    } else {
      this.render('accessDenied');
    }
  } else {
    this.next();
  }
}

Router.onBeforeAction('dataNotFound', {only: 'postPage'});
Router.onBeforeAction(requireLogin, {only: 'postSubmit'});
<commit_msg>Refactored postsLists route into a RouteController<commit_after>Router.configure({
  layoutTemplate: 'layout',
  loadingTemplate: 'loading',
  notFoundTemplate: 'notFound',
  waitOn: function() {
    return [Meteor.subscribe('notifications')]
  }
});

PostsListController = RouteController.extend({
  template: 'postsList',
  increment: 5,
  postsLimit: function() {
    return parseInt(this.params.postsLimit) || this.increment;
  },
  findOptions: function() {
    return {sort: {submitted: -1}, limit: this.postsLimit()};
  },
  waitOn: function() {
    return Meteor.subscribe('posts', this.findOptions());
  },
  data: function() {
    return {posts: Posts.find({}, this.findOptions())};
  }
});

Router.route('/posts/:_id', {
  name: 'postPage',
  waitOn: function() {
    return Meteor.subscribe('comments', this.params._id);
  },
  data: function() { return Posts.findOne(this.params._id); }
});

Router.route('/posts/:_id/edit', {
  name: 'postEdit',
  data: function() { return Posts.findOne(this.params._id); }
});

Router.route('/submit', {name: 'postSubmit'});

Router.route('/:postsLimit?', {
  name: 'postsList'
});

var requireLogin = function() {
  if (! Meteor.user()) {
    if (Meteor.loggingIn()) {
      this.render(this.loadingTemplate);
    } else {
      this.render('accessDenied');
    }
  } else {
    this.next();
  }
}

Router.onBeforeAction('dataNotFound', {only: 'postPage'});
Router.onBeforeAction(requireLogin, {only: 'postSubmit'});
<|endoftext|>