<commit_before>require('jasmine-node');

var colors = require('colors'),
    markdown = require('markdown').markdown,
    stackTraceParser = require('stack-trace-parser'),
    ROOT_LEVEL = 1,
    DESCRIBE_LEVEL = 2,
    IT_LEVEL = 3,
    parser;

var isHeader = function(node) {
  return node[0] === 'header';
};

var isCodeBlock = function(node) {
  return node[0] === 'code_block';
};

var getName = function(node) {
  return node[2];
};

var getLevel = function(node) {
  return node[1].level;
};

var makeFileNameRelative = function(fileName) {
  return fileName.replace(process.cwd(), '.');
};

parser = {
  displayEvalException: function(exception, name, code) {
    var parsedStackTrace = stackTraceParser.parse(exception);
    if (parsedStackTrace[0].isEval) {
      console.log('\n');
      console.log(exception.toString().red, 'thrown from', name.red, 'in', makeFileNameRelative(parser.fileName).red + ':');
      console.log('. . . . .');
      var errorOnLineNumber = parsedStackTrace[0].evalLineNumber - 1;
      code.split('\n').forEach(function(line, index) {
        if (index == errorOnLineNumber) {
          line = line.red;
        }
        console.log(line);
      });
      console.log('. . . . .\n');
    }
  },

  run: function(name, code) {
    if (code.indexOf('done()') === -1) {
      return function() {
        try {
          return eval(code);
        }
        catch (exception) {
          parser.displayEvalException(exception, name, code);
          exception.message += ' (' + makeFileNameRelative(parser.fileName) + ')';
          throw exception;
        }
      }
    } else {
      return function(done) {
        try {
          return eval(code);
        }
        catch (exception) {
          parser.displayEvalException(exception, name, code);
          exception.message += ' (' + makeFileNameRelative(parser.fileName) + ')';
          throw exception;
        }
      }
    }
  },

  parse: function(text, fileName) {
    var tree = markdown.parse(text),
        root = tree[1],
        complete = {
          name: getName(root),
          describes: []
        };

    this.fileName = fileName;

    if (!parser.validNode(root, 'header', ROOT_LEVEL)) {
      return;
    }

    complete.global = parser.parseCodeBlocks(tree, 1);
    complete.globalFn = parser.run(complete.name, complete.global);

    for (var i=2; i < tree.length; i++) {
      var node = tree[i];
      if (parser.validNode(node, 'header', DESCRIBE_LEVEL)) {
        complete.describes.push(parser.parseDescribe(tree, i));
      }
    }

    complete.fn = function(describeFn) {
      describeFn = describeFn || describe;
      complete.globalFn();
      describeFn(complete.name, function() {
        complete.describes.forEach(function(parsedDescribe) {
          describeFn(parsedDescribe.name, parsedDescribe.fn);
        });
      });
    };

    return complete;
  },

  parseDescribe: function(tree, offset) {
    var node = tree[offset],
        parsedDescribe = {
          name: getName(node),
          it: []
        };

    parsedDescribe.beforeEach = parser.parseCodeBlocks(tree, offset);
    parsedDescribe.beforeEachFn = parser.run(parsedDescribe.name, parsedDescribe.beforeEach);

    while (true) {
      offset += 1;
      var child = tree[offset];

      if (!child || isHeader(child) && getLevel(child) < IT_LEVEL) {
        break;
      }

      if (parser.validNode(child, 'header', IT_LEVEL)) {
        parsedDescribe.it.push(parser.parseIt(tree, offset));
      }
    }

    parsedDescribe.fn = function(itFn) {
      itFn = itFn || it;
      beforeEach(parsedDescribe.beforeEachFn);
      parsedDescribe.it.forEach(function(parsedIt) {
        itFn(parsedIt.name, parsedIt.fn);
      });
    };

    return parsedDescribe;
  },

  parseIt: function(tree, offset) {
    var node = tree[offset],
        it = {
          name: getName(node)
        };

    it.code = parser.parseCodeBlocks(tree, offset);
    it.fn = parser.run(it.name, it.code);

    return it;
  },

  parseCodeBlocks: function(tree, offset) {
    var code_blocks = [];

    while (true) {
      offset += 1;
      var child = tree[offset];

      if (!child || isHeader(child)) {
        break;
      }

      if (isCodeBlock(child)) {
        code_blocks.push(child[1]);
      }
    }

    return code_blocks.join('\n');
  },

  validNode: function(node, type, level) {
    return node[0] === type && node[1].level === level;
  }
};

module.exports = parser;
<commit_msg>Clean up async running<commit_after>require('jasmine-node');

var colors = require('colors'),
    markdown = require('markdown').markdown,
    stackTraceParser = require('stack-trace-parser'),
    ROOT_LEVEL = 1,
    DESCRIBE_LEVEL = 2,
    IT_LEVEL = 3,
    parser;

var doneRegExp = new RegExp(/\sdone()/);

var isHeader = function(node) {
  return node[0] === 'header';
};

var isCodeBlock = function(node) {
  return node[0] === 'code_block';
};

var getName = function(node) {
  return node[2];
};

var getLevel = function(node) {
  return node[1].level;
};

var makeFileNameRelative = function(fileName) {
  return fileName.replace(process.cwd(), '.');
};

var runExample = function(name, code) {
  try {
    return eval(code);
  } catch (exception) {
    parser.displayEvalException(exception, name, code);
    exception.message += ' (' + makeFileNameRelative(parser.fileName) + ')';
    throw exception;
  }
}

parser = {
  displayEvalException: function(exception, name, code) {
    var parsedStackTrace = stackTraceParser.parse(exception);
    if (parsedStackTrace[0].isEval) {
      console.log('\n');
      console.log(exception.toString().red, 'thrown from', name.red, 'in', makeFileNameRelative(parser.fileName).red + ':');
      console.log('. . . . .');
      var errorOnLineNumber = parsedStackTrace[0].evalLineNumber - 1;
      code.split('\n').forEach(function(line, index) {
        if (index == errorOnLineNumber) {
          line = line.red;
        }
        console.log(line);
      });
      console.log('. . . . .\n');
    }
  },

  run: function(name, code) {
    if (doneRegExp.test(code)) {
      return function(done) { runExample(name, code); }
    } else {
      return function() { runExample(name, code); }
    }
  },

  parse: function(text, fileName) {
    var tree = markdown.parse(text),
        root = tree[1],
        complete = {
          name: getName(root),
          describes: []
        };

    this.fileName = fileName;

    if (!parser.validNode(root, 'header', ROOT_LEVEL)) {
      return;
    }

    complete.global = parser.parseCodeBlocks(tree, 1);
    complete.globalFn = parser.run(complete.name, complete.global);

    for (var i=2; i < tree.length; i++) {
      var node = tree[i];
      if (parser.validNode(node, 'header', DESCRIBE_LEVEL)) {
        complete.describes.push(parser.parseDescribe(tree, i));
      }
    }

    complete.fn = function(describeFn) {
      describeFn = describeFn || describe;
      complete.globalFn();
      describeFn(complete.name, function() {
        complete.describes.forEach(function(parsedDescribe) {
          describeFn(parsedDescribe.name, parsedDescribe.fn);
        });
      });
    };

    return complete;
  },

  parseDescribe: function(tree, offset) {
    var node = tree[offset],
        parsedDescribe = {
          name: getName(node),
          it: []
        };

    parsedDescribe.beforeEach = parser.parseCodeBlocks(tree, offset);
    parsedDescribe.beforeEachFn = parser.run(parsedDescribe.name, parsedDescribe.beforeEach);

    while (true) {
      offset += 1;
      var child = tree[offset];

      if (!child || isHeader(child) && getLevel(child) < IT_LEVEL) {
        break;
      }

      if (parser.validNode(child, 'header', IT_LEVEL)) {
        parsedDescribe.it.push(parser.parseIt(tree, offset));
      }
    }

    parsedDescribe.fn = function(itFn) {
      itFn = itFn || it;
      beforeEach(parsedDescribe.beforeEachFn);
      parsedDescribe.it.forEach(function(parsedIt) {
        itFn(parsedIt.name, parsedIt.fn);
      });
    };

    return parsedDescribe;
  },

  parseIt: function(tree, offset) {
    var node = tree[offset],
        it = {
          name: getName(node)
        };

    it.code = parser.parseCodeBlocks(tree, offset);
    it.fn = parser.run(it.name, it.code);

    return it;
  },

  parseCodeBlocks: function(tree, offset) {
    var code_blocks = [];

    while (true) {
      offset += 1;
      var child = tree[offset];

      if (!child || isHeader(child)) {
        break;
      }

      if (isCodeBlock(child)) {
        code_blocks.push(child[1]);
      }
    }

    return code_blocks.join('\n');
  },

  validNode: function(node, type, level) {
    return node[0] === type && node[1].level === level;
  }
};

module.exports = parser;
<|endoftext|>


<commit_before>$(function() {

	var socket = io.connect('http://localhost:8080');

	// LOGIN
	$('#login').submit(function(e) {
		e.preventDefault();

		socket.emit('login', {
			email   : $('#email').val(),
			password: $('#password').val()
		});
	});

	// List all users connected
	socket.on('notificationUserConnection', function (user) {
		$('#users').append('
' + user.email + '
')
	});

	// User connected
	socket.on('userConnection', function () {
		$("#login" ).hide("slide", { direction: "right" }, 1200);
        $("#users").delay(400).show("slide", { direction: "right" }, 1200);
	});

	// User disconnect
	socket.on('notificationUserDisconnect', function(user) {
		$('#user-'+user.id).remove();
	});

});<commit_msg>Fix connection animation<commit_after>$(function() {

	var socket = io.connect('http://localhost:8080');

	// LOGIN
	$('#login').submit(function(e) {
		e.preventDefault();

		socket.emit('login', {
			email   : $('#email').val(),
			password: $('#password').val()
		});
	});

	// List all users connected
	socket.on('notificationUserConnection', function (user) {
		$('#users').append('
' + user.email + '
')
	});

	// User connected
	socket.on('userConnection', function () {
		$("#login" ).hide("slide", function() {
        	$("#users").show("slide");
		});
	});

	// User disconnect
	socket.on('notificationUserDisconnect', function(user) {
		$('#user-'+user.id).remove();
	});

});<|endoftext|>


<commit_before>var generators = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');
var _ = require('lodash');
var fs = require('fs');
var del = require('del');
var download = require('download');
var downloadStatus = require('download-status');
var walk = require('walk');
var path = require('path');

module.exports = generators.Base.extend({
  prompting: {
    askToUser: function askToUser() {
      var done = this.async();

      this.log(yosay(
        'Welcome to the kickass ' + chalk.red('wordpress-s-theme') + ' generator!'
      ));

      var prompts = [
				{
          type: 'input',
          name: 'proxyname',
          message: 'Localhost address',
          default: 'localhost'
        },
				{
          type: 'input',
          name: 'domenname',
          message: 'If you want to add a domain site',
          default: ''
        },
        {
          type: 'input',
          name: 'themename',
          message: 'Theme Name',
          default: 'Theme Name'
        },
        {
          type: 'input',
          name: 'themeslug',
          message: 'Theme Slug',
          default: 'Theme Slug'
        },
        {
          type: 'input',
          name: 'themeuri',
          message: 'Theme URI',
          default: 'https://example.com/themeuri/'
        },
        {
          type: 'input',
          name: 'author',
          message: 'Author',
          default: 'Author'
        },
        {
          type: 'input',
          name: 'authoruri',
          message: 'Author URI',
          default: 'https://example.com/authoruri/'
        },
        {
          type: 'input',
          name: 'authoremail',
          message: 'Author Email',
          default: 'info@example.com'
        },
        {
          type: 'input',
          name: 'description',
          message: 'Description',
          default: 'Description'
        },
        {
          type: 'input',
          name: 'bugreport',
          message: 'Bug Report',
          default: 'https://example.com/bugreport/'
        },
        {
          type: 'confirm',
          name: 'gitignore',
          message: 'Would you like to add a ' + chalk.white('.gitignore') + ' file?',
          default: true
        },
        {
          type: 'confirm',
          name: 'editorconfig',
          message: 'Would you like to add a ' + chalk.white('.editorconfig') + ' file?',
          default: true
        },
        {
          type: 'confirm',
          name: 'jshintrc',
          message: 'Would you like to add a ' + chalk.white('.jshintrc') + ' file?',
          default: true
        },
        {
          type: 'confirm',
          name: 'gulpsetup',
          message: 'Would you like to setup a Gulp configuration ready to use?',
          default: true
        }
      ];

      this.prompt(prompts, function (props) {
        this.props = props;
        this.props.prefix = _.snakeCase(this.props.themeslug) + '_';
        this.props.themeslug = _.kebabCase(this.props.themeslug);

        done();
      }.bind(this));
    }
  },

  writing: {
    installUnderscores: function installUnderscores() {
      var done = this.async();
      var callback = function (error, remote) {
        if (error) {
          done(error);
        }

        done();
      }.bind(this);

      this.log(chalk.yellow('\nLet\'s grab the latest version of Underscores...'));

      new download({mode: '755', extract: true, strip: 1})
        .get('https://github.com/Automattic/_s/archive/master.tar.gz')
        .dest('.')
        .use(downloadStatus())
        .run(callback);
    },

    deleteFiles: function deleteFiles() {
      var done = this.async();
      var dir = this.destinationRoot();

      var unusedFiles = ['.jscsrc', '.jshintignore', '.travis.yml', 'codesniffer.ruleset.xml', 'CONTRIBUTING.md', 'README.md'];

      this.log(chalk.yellow('\nDeleting some unused files...'));

      // Delete unused files
      unusedFiles = _.map(unusedFiles, function(file) {
        return dir + '/' + file;
      });

      del(unusedFiles).catch(function(error) {
        done(error);
      })
      .then(paths => {
        this.log(chalk.cyan(paths.join('\n')));

        done();
      });
    },

    parseThemeFiles: function parseThemeFiles() {
      var done = this.async();
      var _this = this;
      var walker;

      _this.log(chalk.yellow('\nParsing theme files...'));

      walker = walk.walk('.');

      _this.log.write().info('Please wait...');

      walker.on("file", function (root, fileStats, next) {
        var filePath = root + '/' + fileStats.name;

        if (path.extname(fileStats.name) == '.php') {
          fs.readFile(filePath, 'utf8', function (err,data) {
            if (err) {
              done(error);
            }

            var result;

            result = data.replace(/'_s'/g, "'" + _this.props.themeslug + "'");
            result = result.replace(/_s_/g, _this.props.prefix);
            result = result.replace(/ _s/g, ' ' + _this.props.themename);
            result = result.replace(/_s-/g, _this.props.themeslug + '-');

            fs.writeFile(filePath, result, 'utf8', function (err) {
              if (err) {
                done(error);
              }
            });

            next();
          });
        } else if (path.extname(fileStats.name) == '.css' || fileStats.name == 'style.scss') {
          fs.readFile(filePath, 'utf8', function (err,data) {
            if (err) {
              done(error);
            }

            var result;

            result = data.replace(/(Theme Name: )(.+)/g, '$1' + _this.props.themename);
            result = result.replace(/(Theme URI: )(.+)/g, '$1' + _this.props.themeuri);
            result = result.replace(/(Author: )(.+)/g, '$1' + _this.props.author);
            result = result.replace(/(Author URI: )(.+)/g, '$1' + _this.props.authoruri);
            result = result.replace(/(Description: )(.+)/g, '$1' + _this.props.description);
            result = result.replace(/(Text Domain: )(.+)/g, '$1' + _this.props.themeslug);
            result = result.replace(/_s is based on Underscores/g, _this.props.themename + ' is based on Underscores');

            fs.writeFile(filePath, result, 'utf8', function (err) {
              if (err) {
                done(error);
              }
            });

            next();
          });
        } else if (fileStats.name === 'readme.txt') {
          fs.readFile(filePath, 'utf8', function (err,data) {
            if (err) {
              done(error);
            }

            var result;

            result = data.replace(/=== _s ===/g, '=== ' + _this.props.themename + ' ===');
            result = result.replace(/A starter theme called _s, or underscores./g, _this.props.description);
            result = result.replace(/(== Description ==\n\n)(.+)/g, '$1' + 'Long description here');
            result = result.replace(/== Frequently Asked Questions ==[\s\S]*?== Credits ==/g, '== Credits ==');

            fs.writeFile(filePath, result, 'utf8', function (err) {
              if (err) {
                done(error);
              }
            });

            next();
          });
        } else if (fileStats.name === 'style.scss') {
          fs.readFile(filePath, 'utf8', function (err,data) {
            if (err) {
              done(error);
            }/*--------------------------------------------------------------   */

            var result;

            result = data.replace(/\/*--------------------------------------------------------------/, '\n\n// bower:scss' + '\n\n// endbower\n\n' + '\n\n/*--------------------------------------------------------------');

            fs.writeFile(filePath, result, 'utf8', function (err) {
              if (err) {
                done(error);
              }
            });

            next();
          });
        } else if (fileStats.name === '_s.pot') {
          fs.readFile(filePath, 'utf8', function (err,data) {
            if (err) {
              done(error);
            }

            var result;

            result = data.replace(/Copyright (C) 2016 Automattic/g, 'Copyright (C) 2016 ' + _this.props.author);
            result = result.replace(/Project-Id-Version: _s/g, 'Project-Id-Version: ' + _this.props.themename);
            result = result.replace(/Report-Msgid-Bugs-To: https:\/\/wordpress.org\/tags\/_s/g, 'Report-Msgid-Bugs-To: ' + _this.props.bugreport);
            result = result.replace(/Language-Team: LANGUAGE <LL@li\.org>/g, 'Language-Team: ' + _this.props.author + '<' + _this.props.authoremail + '>');
            result = result.replace(/@ _s/g, '@ ' + _this.props.themeslug);

            fs.writeFile(filePath, result, 'utf8', function (err) {
              if (err) {
                done(error);
              }
            });

            fs.rename(filePath, './languages/' + _this.props.themeslug + '.pot');

            next();
          });
        } else {
          next();
        }
      });

      walker.on("errors", function (root, nodeStatsArray, next) {
        done(error);
        next();
      });

      walker.on("end", function () {
        done();
      });
    },

    packageFiles: function packageFiles() {
      this.log(chalk.yellow('\nCopying configuration files...'));

      if (this.props.gitignore) {
        this.fs.copy(
          this.templatePath('_gitignore'),
          this.destinationPath('.gitignore')
        );
      }

      if (this.props.editorconfig) {
        this.fs.copy(
          this.templatePath('_editorconfig'),
          this.destinationPath('.editorconfig')
        );
      }

      if (this.props.jshintrc) {
        this.fs.copy(
          this.templatePath('_jshintrc'),
          this.destinationPath('.jshintrc')
        );
      }

      if (this.props.gulpsetup) {
        this.fs.copyTpl(
          this.templatePath('_package.json'),
          this.destinationPath('package.json'),
          {
            package_name: this.props.themeslug,
            package_description: this.props.description,
            package_author: this.props.author
          }
        );

        this.fs.copyTpl(
          this.templatePath('_gulpfile.js'),
          this.destinationPath('gulpfile.js'),
          {
            proxy_address: this.props.proxyname,
            proxy_domain: this.props.domenname,
            theme_domain: this.props.themeslug,
            package_name: this.props.themename,
            theme_bugreport: this.props.bugreport,
            author: this.props.author,
            author_email: this.props.authoremail
          }
        );
      }
    }
  },

  install: {
    installPackages: function installPackages() {
      if (this.props.gulpsetup) {
        this.log(chalk.yellow('\nInstalling required packages...'));

        this.npmInstall(['gulp'], { 'saveDev': true });
        this.npmInstall(['browser-sync'], { 'saveDev': true });
        this.npmInstall(['gulp-sass'], { 'saveDev': true });
        this.npmInstall(['gulp-autoprefixer'], { 'saveDev': true });
        this.npmInstall(['gulp-rename'], { 'saveDev': true });
        this.npmInstall(['gulp-uglify'], { 'saveDev': true });
        this.npmInstall(['jshint'], { 'saveDev': true });
        this.npmInstall(['gulp-jshint'], { 'saveDev': true });
        this.npmInstall(['jshint-stylish'], { 'saveDev': true });
        this.npmInstall(['gulp-wp-pot'], { 'saveDev': true });
        this.npmInstall(['gulp-sort'], { 'saveDev': true });
        this.npmInstall(['gulp-group-css-media-queries'], { 'saveDev': true });
        this.npmInstall(['del'], { 'saveDev': true });
        this.npmInstall(['gulp-zip'], { 'saveDev': true });
        this.npmInstall(['run-sequence'], { 'saveDev': true });
        this.npmInstall(['wiredep'], { 'saveDev': true });
      }
    }
  },

  end: {
    endMessage: function endMessage() {
      this.log(chalk.green('\nAll Done!!\n------------------------\n'));

      if (this.props.gulpsetup) {
        this.log('\nRun ' + chalk.green('gulp') + ' to start the development and ' + chalk.green('gulp build') + ' to create a zip file in ' + chalk.white('dist/' + this.props.themeslug + '.zip') + ' ready for production.');
      }
    }
  },
});
<commit_msg>add bower:scss in scss file<commit_after>var generators = require('yeoman-generator');
var chalk = require('chalk');
var yosay = require('yosay');
var _ = require('lodash');
var fs = require('fs');
var del = require('del');
var download = require('download');
var downloadStatus = require('download-status');
var walk = require('walk');
var path = require('path');

module.exports = generators.Base.extend({
  prompting: {
    askToUser: function askToUser() {
      var done = this.async();

      this.log(yosay(
        'Welcome to the kickass ' + chalk.red('wordpress-s-theme') + ' generator!'
      ));

      var prompts = [
				{
          type: 'input',
          name: 'proxyname',
          message: 'Localhost address',
          default: 'localhost'
        },
				{
          type: 'input',
          name: 'domenname',
          message: 'If you want to add a domain site',
          default: ''
        },
        {
          type: 'input',
          name: 'themename',
          message: 'Theme Name',
          default: 'Theme Name'
        },
        {
          type: 'input',
          name: 'themeslug',
          message: 'Theme Slug',
          default: 'Theme Slug'
        },
        {
          type: 'input',
          name: 'themeuri',
          message: 'Theme URI',
          default: 'https://example.com/themeuri/'
        },
        {
          type: 'input',
          name: 'author',
          message: 'Author',
          default: 'Author'
        },
        {
          type: 'input',
          name: 'authoruri',
          message: 'Author URI',
          default: 'https://example.com/authoruri/'
        },
        {
          type: 'input',
          name: 'authoremail',
          message: 'Author Email',
          default: 'info@example.com'
        },
        {
          type: 'input',
          name: 'description',
          message: 'Description',
          default: 'Description'
        },
        {
          type: 'input',
          name: 'bugreport',
          message: 'Bug Report',
          default: 'https://example.com/bugreport/'
        },
        {
          type: 'confirm',
          name: 'gitignore',
          message: 'Would you like to add a ' + chalk.white('.gitignore') + ' file?',
          default: true
        },
        {
          type: 'confirm',
          name: 'editorconfig',
          message: 'Would you like to add a ' + chalk.white('.editorconfig') + ' file?',
          default: true
        },
        {
          type: 'confirm',
          name: 'jshintrc',
          message: 'Would you like to add a ' + chalk.white('.jshintrc') + ' file?',
          default: true
        },
        {
          type: 'confirm',
          name: 'gulpsetup',
          message: 'Would you like to setup a Gulp configuration ready to use?',
          default: true
        }
      ];

      this.prompt(prompts, function (props) {
        this.props = props;
        this.props.prefix = _.snakeCase(this.props.themeslug) + '_';
        this.props.themeslug = _.kebabCase(this.props.themeslug);

        done();
      }.bind(this));
    }
  },

  writing: {
    installUnderscores: function installUnderscores() {
      var done = this.async();
      var callback = function (error, remote) {
        if (error) {
          done(error);
        }

        done();
      }.bind(this);

      this.log(chalk.yellow('\nLet\'s grab the latest version of Underscores...'));

      new download({mode: '755', extract: true, strip: 1})
        .get('https://github.com/Automattic/_s/archive/master.tar.gz')
        .dest('.')
        .use(downloadStatus())
        .run(callback);
    },

    deleteFiles: function deleteFiles() {
      var done = this.async();
      var dir = this.destinationRoot();

      var unusedFiles = ['.jscsrc', '.jshintignore', '.travis.yml', 'codesniffer.ruleset.xml', 'CONTRIBUTING.md', 'README.md'];

      this.log(chalk.yellow('\nDeleting some unused files...'));

      // Delete unused files
      unusedFiles = _.map(unusedFiles, function(file) {
        return dir + '/' + file;
      });

      del(unusedFiles).catch(function(error) {
        done(error);
      })
      .then(paths => {
        this.log(chalk.cyan(paths.join('\n')));

        done();
      });
    },

    parseThemeFiles: function parseThemeFiles() {
      var done = this.async();
      var _this = this;
      var walker;

      _this.log(chalk.yellow('\nParsing theme files...'));

      walker = walk.walk('.');

      _this.log.write().info('Please wait...');

      walker.on("file", function (root, fileStats, next) {
        var filePath = root + '/' + fileStats.name;

        if (path.extname(fileStats.name) == '.php') {
          fs.readFile(filePath, 'utf8', function (err,data) {
            if (err) {
              done(error);
            }

            var result;

            result = data.replace(/'_s'/g, "'" + _this.props.themeslug + "'");
            result = result.replace(/_s_/g, _this.props.prefix);
            result = result.replace(/ _s/g, ' ' + _this.props.themename);
            result = result.replace(/_s-/g, _this.props.themeslug + '-');

            fs.writeFile(filePath, result, 'utf8', function (err) {
              if (err) {
                done(error);
              }
            });

            next();
          });
        } else if (path.extname(fileStats.name) == '.css' || fileStats.name == 'style.scss') {
          fs.readFile(filePath, 'utf8', function (err,data) {
            if (err) {
              done(error);
            }

            var result;

            result = data.replace(/(Theme Name: )(.+)/g, '$1' + _this.props.themename);
            result = result.replace(/(Theme URI: )(.+)/g, '$1' + _this.props.themeuri);
            result = result.replace(/(Author: )(.+)/g, '$1' + _this.props.author);
            result = result.replace(/(Author URI: )(.+)/g, '$1' + _this.props.authoruri);
            result = result.replace(/(Description: )(.+)/g, '$1' + _this.props.description);
            result = result.replace(/(Text Domain: )(.+)/g, '$1' + _this.props.themeslug);
            result = result.replace(/_s is based on Underscores/g, _this.props.themename + ' is based on Underscores');
            result = result.replace(/\@import "normalize";/g, '\n\n// bower:scss' + '\n\n// endbower\n\n' + '\n\n@import "normalize";');

            fs.writeFile(filePath, result, 'utf8', function (err) {
              if (err) {
                done(error);
              }
            });

            next();
          });
        } else if (fileStats.name === 'readme.txt') {
          fs.readFile(filePath, 'utf8', function (err,data) {
            if (err) {
              done(error);
            }

            var result;

            result = data.replace(/=== _s ===/g, '=== ' + _this.props.themename + ' ===');
            result = result.replace(/A starter theme called _s, or underscores./g, _this.props.description);
            result = result.replace(/(== Description ==\n\n)(.+)/g, '$1' + 'Long description here');
            result = result.replace(/== Frequently Asked Questions ==[\s\S]*?== Credits ==/g, '== Credits ==');

            fs.writeFile(filePath, result, 'utf8', function (err) {
              if (err) {
                done(error);
              }
            });

            next();
          });
        } else if (fileStats.name === '_s.pot') {
          fs.readFile(filePath, 'utf8', function (err,data) {
            if (err) {
              done(error);
            }

            var result;

            result = data.replace(/Copyright (C) 2016 Automattic/g, 'Copyright (C) 2016 ' + _this.props.author);
            result = result.replace(/Project-Id-Version: _s/g, 'Project-Id-Version: ' + _this.props.themename);
            result = result.replace(/Report-Msgid-Bugs-To: https:\/\/wordpress.org\/tags\/_s/g, 'Report-Msgid-Bugs-To: ' + _this.props.bugreport);
            result = result.replace(/Language-Team: LANGUAGE <LL@li\.org>/g, 'Language-Team: ' + _this.props.author + '<' + _this.props.authoremail + '>');
            result = result.replace(/@ _s/g, '@ ' + _this.props.themeslug);

            fs.writeFile(filePath, result, 'utf8', function (err) {
              if (err) {
                done(error);
              }
            });

            fs.rename(filePath, './languages/' + _this.props.themeslug + '.pot');

            next();
          });
        } else {
          next();
        }
      });

      walker.on("errors", function (root, nodeStatsArray, next) {
        done(error);
        next();
      });

      walker.on("end", function () {
        done();
      });
    },

    packageFiles: function packageFiles() {
      this.log(chalk.yellow('\nCopying configuration files...'));

      if (this.props.gitignore) {
        this.fs.copy(
          this.templatePath('_gitignore'),
          this.destinationPath('.gitignore')
        );
      }

      if (this.props.editorconfig) {
        this.fs.copy(
          this.templatePath('_editorconfig'),
          this.destinationPath('.editorconfig')
        );
      }

      if (this.props.jshintrc) {
        this.fs.copy(
          this.templatePath('_jshintrc'),
          this.destinationPath('.jshintrc')
        );
      }

      if (this.props.gulpsetup) {
        this.fs.copyTpl(
          this.templatePath('_package.json'),
          this.destinationPath('package.json'),
          {
            package_name: this.props.themeslug,
            package_description: this.props.description,
            package_author: this.props.author
          }
        );

        this.fs.copyTpl(
          this.templatePath('_gulpfile.js'),
          this.destinationPath('gulpfile.js'),
          {
            proxy_address: this.props.proxyname,
            proxy_domain: this.props.domenname,
            theme_domain: this.props.themeslug,
            package_name: this.props.themename,
            theme_bugreport: this.props.bugreport,
            author: this.props.author,
            author_email: this.props.authoremail
          }
        );
      }
    }
  },

  install: {
    installPackages: function installPackages() {
      if (this.props.gulpsetup) {
        this.log(chalk.yellow('\nInstalling required packages...'));

        this.npmInstall(['gulp'], { 'saveDev': true });
        this.npmInstall(['browser-sync'], { 'saveDev': true });
        this.npmInstall(['gulp-sass'], { 'saveDev': true });
        this.npmInstall(['gulp-autoprefixer'], { 'saveDev': true });
        this.npmInstall(['gulp-rename'], { 'saveDev': true });
        this.npmInstall(['gulp-uglify'], { 'saveDev': true });
        this.npmInstall(['jshint'], { 'saveDev': true });
        this.npmInstall(['gulp-jshint'], { 'saveDev': true });
        this.npmInstall(['jshint-stylish'], { 'saveDev': true });
        this.npmInstall(['gulp-wp-pot'], { 'saveDev': true });
        this.npmInstall(['gulp-sort'], { 'saveDev': true });
        this.npmInstall(['gulp-group-css-media-queries'], { 'saveDev': true });
        this.npmInstall(['del'], { 'saveDev': true });
        this.npmInstall(['gulp-zip'], { 'saveDev': true });
        this.npmInstall(['run-sequence'], { 'saveDev': true });
        this.npmInstall(['wiredep'], { 'saveDev': true });
      }
    }
  },

  end: {
    endMessage: function endMessage() {
      this.log(chalk.green('\nAll Done!!\n------------------------\n'));

      if (this.props.gulpsetup) {
        this.log('\nRun ' + chalk.green('gulp') + ' to start the development and ' + chalk.green('gulp build') + ' to create a zip file in ' + chalk.white('dist/' + this.props.themeslug + '.zip') + ' ready for production.');
      }
    }
  },
});
<|endoftext|>


<commit_before>Ibis.Parser = (function () {
  var Lexer = Ibis.Lexer;
  var Expr = Ibis.Expr;
  var Value = Ibis.Value;
  var IbisError = Ibis.IbisError;

  var exports = function () {
    return {
      ofString: ofString,
      parse: parse
    };
  };

  function ofString(string) {
    return {
      lexer: Lexer.ofString(string),
      headToken: null
    }
  }

  function parse(parser) {
    lookAhead(parser);
    if (parser.headToken == "EOF") {
      return null;
    }
    return parseStmt(parser);
  }

  function lookAhead(parser) {
    if (Lexer.advance(parser.lexer)) {
      parser.headToken = Lexer.token(parser.lexer);
    } else {
      parser.headToken = "EOF";
    }
  }

  function parseStmt(parser) {
    var expr = parseExpr(parser);
    switch (parser.headToken) {
    case "EOF":
      break;
    default:
      throw new IbisError(expected(parser, "EOF"));
    }
    return expr;
  }

  function parseExpr(parser) {
    return parseEqExpr(parser);
  }

  function parseEqExpr(parser) {
    var expr = parseRelExpr(parser);
    while (parser.headToken.match(/=/)) {
      var op = parser.headToken;
      lookAhead(parser);
      expr = createBinExpr(op, expr, parseRelExpr(parser));
    }
    return expr;
  }

  function parseRelExpr(parser) {
    return parseAddExpr(parser);
  }

  function parseAddExpr(parser) {
    var expr = parseMulExpr(parser);
    while (parser.headToken.match(/[+\-]/)) {
      var op = parser.headToken;
      lookAhead(parser);
      expr = createBinExpr(op, expr, parseMulExpr(parser));
    }
    return expr;
  }

  function parseMulExpr(parser) {
    var expr = parsePrimExpr(parser);
    while (parser.headToken.match(/[*\/]/)) {
      var op = parser.headToken;
      lookAhead(parser);
      expr = createBinExpr(op, expr, parsePrimExpr(parser));
    }
    return expr;
  }

  function parsePrimExpr(parser) {
    var expr = parseAtom(parser);
    while (parser.headToken == "INT" ||
           parser.headToken == "IDENT" ||
           parser.headToken == "fun" ||
           parser.headToken == "let" ||
           parser.headToken == "(") {
      expr = Expr.createApp(expr, parseAtom(parser));
    }
    return expr;
  }

  function parseAtom(parser) {
    var expr = null;
    switch (parser.headToken) {
    case "INT":
      expr = parseInt(parser);
      break;
    case "IDENT":
      expr = parseIdent(parser);
      break;
    case "fun":
      expr = parseAbs(parser);
      break;
    case "let":
      expr = parseLet(parser);
      break;
    case "true":
      expr = parseTrue(parser);
      break;
    case "false":
      expr = parseFalse(parser);
      break;
    case "if":
      expr = parseIf(parser);
      break;
    case "(":
      expr = parseParen(parser);
      break;
    default:
      throw new IbisError(unexpected(parser));
    }
    return expr;
  }

  function parseInt(parser) {
    var expr = Expr.createConst(Value.createInt(Lexer.value(parser.lexer)));
    lookAhead(parser);
    return expr;
  }

  function parseIdent(parser) {
    var expr = Expr.createVar(Lexer.value(parser.lexer));
    lookAhead(parser);
    return expr;
  }

  function parseAbs(parser) {
    lookAhead(parser);
    if (parser.headToken != "IDENT") {
      throw new IbisError(expected(parser, "IDENT"));
    }
    var varName = Lexer.value(parser.lexer);
    lookAhead(parser);
    if (parser.headToken != "->") {
      throw new IbisError(expected(parser, "->"));
    }
    lookAhead(parser);
    var bodyExpr = parseExpr(parser);
    return Expr.createAbs(varName, bodyExpr);
  }

  function parseLet(parser) {
    lookAhead(parser);
    if (parser.headToken == "rec") {
      return parseLetRec(parser);
    }
    if (parser.headToken != "IDENT") {
      throw new IbisError(expected(parser, "IDENT"));
    }
    var varName = Lexer.value(parser.lexer);
    lookAhead(parser);
    if (parser.headToken != "=") {
      throw new IbisError(expected(parser, "="));
    }
    lookAhead(parser);
    var valueExpr = parseExpr(parser);
    return Expr.createLet(varName, valueExpr);
  }

  function parseLetRec(parser) {
    lookAhead(parser);
    if (parser.headToken != "IDENT") {
      throw new IbisError(expected(parser, "IDENT"));
    }
    var varName = Lexer.value(parser.lexer);
    lookAhead(parser);
    if (parser.headToken != "=") {
      throw new IbisError(expected(parser, "="));
    }
    lookAhead(parser);
    if (parser.headToken != "fun") {
      throw new IbisError(expected(parser, "fun"));
    }
    var valueExpr = parseAbs(parser);
    return Expr.createLetRec(varName, valueExpr);
  }

  function parseTrue(parser) {
    var expr = Expr.createConst(Value.True);
    lookAhead(parser);
    return expr;
  }

  function parseFalse(parser) {
    var expr = Expr.createConst(Value.False);
    lookAhead(parser);
    return expr;
  }

  function parseIf(parser) {
    lookAhead(parser);
    var condExpr = parseExpr(parser);
    if (parser.headToken != "then") {
      throw new IbisError(expected(parser, "then"));
    }
    lookAhead(parser);
    var thenExpr = parseExpr(parser);
    if (parser.headToken != "else") {
      throw new IbisError(expected(parser, "else"));
    }
    lookAhead(parser);
    var elseExpr = parseExpr(parser);
    return Expr.createIf(condExpr, thenExpr, elseExpr);
  }

  function parseParen(parser) {
    lookAhead(parser);
    var expr = parseExpr(parser);
    if (parser.headToken == ",") {
      return parseTuple(parser, [expr]);
    }
    if (parser.headToken != ")") {
      throw new IbisError(expected(parser, ")"));
    }
    lookAhead(parser);
    return expr;
  }

  function parseTuple(parser, exprArray) {
    lookAhead(parser);
    exprArray.push(parseExpr(parser));
    if (parser.headToken == ",") {
      return parseTuple(parser, exprArray);
    }
    if (parser.headToken != ")") {
      throw new IbisError(expected(parser, ")"));
    }
    lookAhead(parser);
    return Expr.createTuple(exprArray);
  }

  function createBinExpr(op, lhs, rhs) {
    return Expr.createApp(Expr.createApp(Expr.createVar(op), lhs), rhs);
  }

  function expected(parser, expectedToken) {
    return "unexpected " + parser.headToken + ", expected " + expectedToken;
  }

  function unexpected(parser) {
    return "unexpected " + parser.headToken
  }

  return exports();
})();
<commit_msg>Bug fix: Parser can parse 'f true'<commit_after>Ibis.Parser = (function () {
  var Lexer = Ibis.Lexer;
  var Expr = Ibis.Expr;
  var Value = Ibis.Value;
  var IbisError = Ibis.IbisError;

  var exports = function () {
    return {
      ofString: ofString,
      parse: parse
    };
  };

  function ofString(string) {
    return {
      lexer: Lexer.ofString(string),
      headToken: null
    }
  }

  function parse(parser) {
    lookAhead(parser);
    if (parser.headToken == "EOF") {
      return null;
    }
    return parseStmt(parser);
  }

  function lookAhead(parser) {
    if (Lexer.advance(parser.lexer)) {
      parser.headToken = Lexer.token(parser.lexer);
    } else {
      parser.headToken = "EOF";
    }
  }

  function parseStmt(parser) {
    var expr = parseExpr(parser);
    switch (parser.headToken) {
    case "EOF":
      break;
    default:
      throw new IbisError(expected(parser, "EOF"));
    }
    return expr;
  }

  function parseExpr(parser) {
    return parseEqExpr(parser);
  }

  function parseEqExpr(parser) {
    var expr = parseRelExpr(parser);
    while (parser.headToken.match(/=/)) {
      var op = parser.headToken;
      lookAhead(parser);
      expr = createBinExpr(op, expr, parseRelExpr(parser));
    }
    return expr;
  }

  function parseRelExpr(parser) {
    return parseAddExpr(parser);
  }

  function parseAddExpr(parser) {
    var expr = parseMulExpr(parser);
    while (parser.headToken.match(/[+\-]/)) {
      var op = parser.headToken;
      lookAhead(parser);
      expr = createBinExpr(op, expr, parseMulExpr(parser));
    }
    return expr;
  }

  function parseMulExpr(parser) {
    var expr = parsePrimExpr(parser);
    while (parser.headToken.match(/[*\/]/)) {
      var op = parser.headToken;
      lookAhead(parser);
      expr = createBinExpr(op, expr, parsePrimExpr(parser));
    }
    return expr;
  }

  function parsePrimExpr(parser) {
    var expr = parseAtom(parser);
    while (parser.headToken == "INT" ||
           parser.headToken == "IDENT" ||
           parser.headToken == "fun" ||
           parser.headToken == "let" ||
           parser.headToken == "true" ||
           parser.headToken == "false" ||
           parser.headToken == "if" ||
           parser.headToken == "(") {
      expr = Expr.createApp(expr, parseAtom(parser));
    }
    return expr;
  }

  function parseAtom(parser) {
    var expr = null;
    switch (parser.headToken) {
    case "INT":
      expr = parseInt(parser);
      break;
    case "IDENT":
      expr = parseIdent(parser);
      break;
    case "fun":
      expr = parseAbs(parser);
      break;
    case "let":
      expr = parseLet(parser);
      break;
    case "true":
      expr = parseTrue(parser);
      break;
    case "false":
      expr = parseFalse(parser);
      break;
    case "if":
      expr = parseIf(parser);
      break;
    case "(":
      expr = parseParen(parser);
      break;
    default:
      throw new IbisError(unexpected(parser));
    }
    return expr;
  }

  function parseInt(parser) {
    var expr = Expr.createConst(Value.createInt(Lexer.value(parser.lexer)));
    lookAhead(parser);
    return expr;
  }

  function parseIdent(parser) {
    var expr = Expr.createVar(Lexer.value(parser.lexer));
    lookAhead(parser);
    return expr;
  }

  function parseAbs(parser) {
    lookAhead(parser);
    if (parser.headToken != "IDENT") {
      throw new IbisError(expected(parser, "IDENT"));
    }
    var varName = Lexer.value(parser.lexer);
    lookAhead(parser);
    if (parser.headToken != "->") {
      throw new IbisError(expected(parser, "->"));
    }
    lookAhead(parser);
    var bodyExpr = parseExpr(parser);
    return Expr.createAbs(varName, bodyExpr);
  }

  function parseLet(parser) {
    lookAhead(parser);
    if (parser.headToken == "rec") {
      return parseLetRec(parser);
    }
    if (parser.headToken != "IDENT") {
      throw new IbisError(expected(parser, "IDENT"));
    }
    var varName = Lexer.value(parser.lexer);
    lookAhead(parser);
    if (parser.headToken != "=") {
      throw new IbisError(expected(parser, "="));
    }
    lookAhead(parser);
    var valueExpr = parseExpr(parser);
    return Expr.createLet(varName, valueExpr);
  }

  function parseLetRec(parser) {
    lookAhead(parser);
    if (parser.headToken != "IDENT") {
      throw new IbisError(expected(parser, "IDENT"));
    }
    var varName = Lexer.value(parser.lexer);
    lookAhead(parser);
    if (parser.headToken != "=") {
      throw new IbisError(expected(parser, "="));
    }
    lookAhead(parser);
    if (parser.headToken != "fun") {
      throw new IbisError(expected(parser, "fun"));
    }
    var valueExpr = parseAbs(parser);
    return Expr.createLetRec(varName, valueExpr);
  }

  function parseTrue(parser) {
    var expr = Expr.createConst(Value.True);
    lookAhead(parser);
    return expr;
  }

  function parseFalse(parser) {
    var expr = Expr.createConst(Value.False);
    lookAhead(parser);
    return expr;
  }

  function parseIf(parser) {
    lookAhead(parser);
    var condExpr = parseExpr(parser);
    if (parser.headToken != "then") {
      throw new IbisError(expected(parser, "then"));
    }
    lookAhead(parser);
    var thenExpr = parseExpr(parser);
    if (parser.headToken != "else") {
      throw new IbisError(expected(parser, "else"));
    }
    lookAhead(parser);
    var elseExpr = parseExpr(parser);
    return Expr.createIf(condExpr, thenExpr, elseExpr);
  }

  function parseParen(parser) {
    lookAhead(parser);
    var expr = parseExpr(parser);
    if (parser.headToken == ",") {
      return parseTuple(parser, [expr]);
    }
    if (parser.headToken != ")") {
      throw new IbisError(expected(parser, ")"));
    }
    lookAhead(parser);
    return expr;
  }

  function parseTuple(parser, exprArray) {
    lookAhead(parser);
    exprArray.push(parseExpr(parser));
    if (parser.headToken == ",") {
      return parseTuple(parser, exprArray);
    }
    if (parser.headToken != ")") {
      throw new IbisError(expected(parser, ")"));
    }
    lookAhead(parser);
    return Expr.createTuple(exprArray);
  }

  function createBinExpr(op, lhs, rhs) {
    return Expr.createApp(Expr.createApp(Expr.createVar(op), lhs), rhs);
  }

  function expected(parser, expectedToken) {
    return "unexpected " + parser.headToken + ", expected " + expectedToken;
  }

  function unexpected(parser) {
    return "unexpected " + parser.headToken
  }

  return exports();
})();
<|endoftext|>


<commit_before>$(document).ready(function() {
	// Fetch the user data.
	$.get('/api/init', function (data) {
		var projects, handlers, handler, h;
		window.data = data;
		projects = data.user.projects;
		// TODO: iterate over the projects and fill the combo box.
		handlers = projects['MyProject'].handlers;
		Object.keys(handlers).forEach(function (h) {
			if (h === 'length') return;
			handler = handlers[h];
			console.log('method=' + handler.method + ',uri=' + handler.uri);
			// Get the DOM node with the Bespin instance inside
			var edit = document.getElementById("editor1");
			// Get the environment variable.
			var env = edit.bespin;
			// Get the editor.
			if (env && env.editor)
				env.editor.value = data.user.projects['MyProject'].handlers['GET /'].code;
		});
	});
});

window.onBespinLoad = function() {
    // Get the DOM node with the Bespin instance inside
    var edit = document.getElementById("editor1");
    // Get the environment variable.
    var env = edit.bespin;
    // Get the editor.
    var editor = env.editor;
    env.settings.set("tabstop", 4);
    editor.syntax = "js";
    editor.focus = true;
	if (window.data)
		editor.value = window.data.user.projects['MyProject'].handlers['GET /'].code;

    function nodifyMsg(msg) {
        var options = {id: 'message_from_top',
            position: 'top',
            size: 20,
            backgroundColor: '#4C4A41',
            //delay: 1500,
            delay: 3500,
            speed: 500,
            fontSize: '12px'
        };

        $.showMessage(msg, options)
    }

    $('#save-btn').click(function() {
		$.ajax({
			url: '/api/init',
			type: 'PUT',
			data: {
				method: 'GET',
				project: 'MyProject',
				code: encodeURIComponent(editor.value),
				uri: '/'
			},
			success: function () {
				nodifyMsg("File saved!");
			},
			dataType: "text",
			error: function(request, status, error) {
				nodifyMsg("Error while saving file: " + error, "error");
			}
		});
    });

    $('#revert-btn').click(function() {
        nodifyMsg("File reverted!");

    });

    $('#deploy-btn').click(function() {
        nodifyMsg("Project deployed!");

    });

}
<commit_msg>Implement Revert fucntionality.<commit_after>$(document).ready(function() {
	// Fetch the user data.
	$.get('/api/init', function (data) {
		var projects, handlers, handler, h;
		window.data = data;
		projects = data.user.projects;
		// TODO: iterate over the projects and fill the combo box.
		handlers = projects['MyProject'].handlers;
		Object.keys(handlers).forEach(function (h) {
			if (h === 'length') return;
			handler = handlers[h];
			console.log('method=' + handler.method + ',uri=' + handler.uri);
			// Get the DOM node with the Bespin instance inside
			var edit = document.getElementById("editor1");
			// Get the environment variable.
			var env = edit.bespin;
			// Get the editor.
			if (env && env.editor)
				env.editor.value = data.user.projects['MyProject'].handlers['GET /'].code;
		});
	});
});

window.onBespinLoad = function() {
    // Get the DOM node with the Bespin instance inside
    var edit = document.getElementById("editor1");
    // Get the environment variable.
    var env = edit.bespin;
    // Get the editor.
    var editor = env.editor;
    env.settings.set("tabstop", 4);
    editor.syntax = "js";
    editor.focus = true;
	if (window.data)
		editor.value = window.data.user.projects['MyProject'].handlers['GET /'].code;

    function nodifyMsg(msg) {
        var options = {id: 'message_from_top',
            position: 'top',
            size: 20,
            backgroundColor: '#4C4A41',
            //delay: 1500,
            delay: 3500,
            speed: 500,
            fontSize: '12px'
        };

        $.showMessage(msg, options)
    }

    $('#save-btn').click(function() {
		$.ajax({
			url: '/api/init',
			type: 'PUT',
			data: {
				method: 'GET',
				project: 'MyProject',
				code: encodeURIComponent(editor.value),
				uri: '/'
			},
			success: function () {
				nodifyMsg("The contents were saved");
			},
			dataType: "text",
			error: function(request, status, error) {
				nodifyMsg("Error while saving file: " + error, "error");
			}
		});
    });

    $('#revert-btn').click(function() {
		$.get('/api/init', function (data) {
			editor.value = window.data.user.projects['MyProject'].handlers['GET /'].code;
			nodifyMsg("The contents were reverted");
		});
    });

    $('#deploy-btn').click(function() {
        nodifyMsg("Project deployed!");

    });

}
<|endoftext|>


<commit_before>'use strict';

var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var npmCheck = require('npm-check');
var path = require('path');
var yosay = require('yosay');

module.exports = yeoman.generators.Base.extend({
  constructor: function() {
    yeoman.generators.Base.apply(this, arguments);
    // add option to skip install
    this.option('skip-install');
    this.argument('appname', {
      type: String,
      required: false
    });
    this.appname = this.appname || path.basename(process.cwd());
  },

  prompting: function() {
    // Yeoman greeting
    this.log(yosay(
      'Yo! I\'m here to help build your ' +
      chalk.bold.yellow('Angular2') +
      ' application.'
    ));
  },

  writing: {
    app: function() {
      this.basicTemplate = 'src/' + this._.slugify(this.appname) +
        '.html';

      this.copy('_package.json', 'package.json');
      this.copy('_gulpfile.js', 'gulpfile.js');
      this.copy('_readme.md', 'readme.md');
      this.copy('_editorconfig', '.editorconfig');
      this.copy('_gitignore', '.gitignore');

      this.mkdir('src');
      this.copy('src/_index.js', 'src/index.js');
      this.copy('src/_index.html', 'src/index.html');
      this.copy('src/_basic-template.html', this.basicTemplate);
    }
  },

  install: function() {
    this.installDependencies({
      skipInstall: this.options['skip-install'],
      bower: false,
      callback: function() {
        this.emit('dependenciesInstalled');
      }.bind(this)
    });

    this.on('dependenciesInstalled', function() {
      npmCheck({
        global: true
      }).then(function(globalPackages) {
        if (!globalPackages.gulp) {
          return './node_modules/.bin/gulp';
        }
        return 'gulp';
      }).then(function(gulpCommand) {
        this.spawnCommand(gulpCommand).on('close', function() {
          this.log('');
          this.log('');
          this.log('Setup complete, run ' +
            chalk.bold.yellow(gulpCommand + ' serve') +
            ' to start serving the application.');
          this.log('');
        }.bind(this));
      }.bind(this));

    }.bind(this));

  }
});
<commit_msg>update gulp run message<commit_after>'use strict';

var yeoman = require('yeoman-generator');
var chalk = require('chalk');
var npmCheck = require('npm-check');
var path = require('path');
var yosay = require('yosay');

module.exports = yeoman.generators.Base.extend({
  constructor: function() {
    yeoman.generators.Base.apply(this, arguments);
    // add option to skip install
    this.option('skip-install');
    this.argument('appname', {
      type: String,
      required: false
    });
    this.appname = this.appname || path.basename(process.cwd());
  },

  prompting: function() {
    // Yeoman greeting
    this.log(yosay(
      'Yo! I\'m here to help build your ' +
      chalk.bold.yellow('Angular2') +
      ' application.'
    ));
  },

  writing: {
    app: function() {
      this.basicTemplate = 'src/' + this._.slugify(this.appname) +
        '.html';

      this.copy('_package.json', 'package.json');
      this.copy('_gulpfile.js', 'gulpfile.js');
      this.copy('_readme.md', 'readme.md');
      this.copy('_editorconfig', '.editorconfig');
      this.copy('_gitignore', '.gitignore');

      this.mkdir('src');
      this.copy('src/_index.js', 'src/index.js');
      this.copy('src/_index.html', 'src/index.html');
      this.copy('src/_basic-template.html', this.basicTemplate);
    }
  },

  install: function() {
    this.installDependencies({
      skipInstall: this.options['skip-install'],
      bower: false,
      callback: function() {
        this.emit('dependenciesInstalled');
      }.bind(this)
    });

    this.on('dependenciesInstalled', function() {
      npmCheck({
        global: true
      }).then(function(globalPackages) {
        if (!globalPackages.gulp) {
          return './node_modules/.bin/gulp';
        }
        return 'gulp';
      }).then(function(gulpCommand) {
        this.spawnCommand(gulpCommand).on('close', function() {
          this.log('');
          this.log('');
          this.log('Setup complete, run ' +
            chalk.bold.yellow(gulpCommand + ' dev') +
            ' to start serving the application' +
            ' (it\'ll also start watching for any changes you make).');
          this.log('');
        }.bind(this));
      }.bind(this));

    }.bind(this));

  }
});
<|endoftext|>


<commit_before>/*
 * parser.js
 *
 * www.catch22.net
 *
 * Copyright (C) 2012 James Brown
 * Licenced under the MIT licence
 * Please refer to the file LICENCE.TXT for copying permission
 */

var Parser;
Parser = Parser || {};

Parser.Token = {
    OPERATOR:   'Operator',
    IDENTIFIER: 'Identifier',
    NUMBER:     'Number',
    UNKNOWN:    'Unknown',
    NONE:       null,

    ANDAND: '&&',
    OROR:   '||',
    EQU:    '==',
    NEQ:    '!=',
    SHR:    '<<',
    SHL:    '>>'
};

Parser.Number = {
  DEC:   10,
  HEX:   16,
  OCT:   8,
  BIN:   2,
  FLOAT: 'Floating'
};

Parser.Expression = {
  BINARY:     'Binary',
  UNARY:      'Unary',
  NUMBER:     'Number',
  IDENTIFIER: 'Identifier'
};

Parser.Mode = {
  PROGRAMMER: 'Prg',
  NORMAL:     'Sci',
  FRACTION:   'Fra'
}

Parser.Lexer = function() {

  var buf = '2 + 2';
  var idx = 0;            // position in buf
  var ch  = '\x00';       // current character read
  var tstr = '';          // identifier
  var tnum = 0;           // number, if current token is TOK_NUMBER
  var numbase = 0;
  var NUM = Parser.Number;
  var TOK = Parser.Token;
  var tpos = 0;

  var parsemode = Parser.Mode.PROGRAMMER;

  function init(expression, mode) {
     buf  = expression;
     idx  = 0;
     ch   = nextch();
     t    = 0;

     parsemode = mode;
  }

  // return next character, don't read ahead
  function peekch() {
    return idx < buf.length ? buf.charAt(idx) : '\x00';
  }

  // return next character, and read ahead
  function nextch() {
    var c = '\x00';
    if(idx < buf.length) {
      c = buf.charAt(idx);
      idx += 1;
    }
    return c;
  }

  function isalpha(ch) {
    return ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z';
  }

  function isxdigit(ch) {
    return ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'F' || ch >= 'a' && ch <= 'f';
  }

  function isdigit(ch) {
    return ch >= '0' && ch <= '9';
  }

  function skipwhitespace() {
    while(ch == ' ' || ch == '\u0009' || ch == '\u00A0' || ch == '\u00D0')
      ch = nextch();
    return ch;
  }

  function create_token(type, val) {
    return {
      type:   type,
      value:  val,
      base:   numbase,
      pos:    tpos
    };
  }

  //
  //  Parse hex/decimal/octal/float numbers
  //  return a NUMBER Token
  //
  function parse_number() {

    tstr = '';

    if(ch == '0') {     // Hex/Octal
      ch = nextch();

      if(ch == 'X' || ch == 'x') {    // Hex
        ch = nextch();
        while(isxdigit(ch)) {
          tstr += ch;
          ch = nextch();
        }

        numbase = NUM.HEX;
      }
      else if(ch == 'B' || ch == 'b') {    // Bin
        ch = nextch();
        while(isxdigit(ch)) {
          tstr += ch;
          ch = nextch();
        }

        numbase = NUM.BIN;
      }
      else {            // Octal
        while(isdigit(ch)) {
          tstr += ch;
          ch = nextch();
        }
        numbase = NUM.OCT;
      }

    }
    else {            // Decimal

      numbase = NUM.DEC;
      tstr = '';

      while(isdigit(ch)) {
        tstr += ch;
        ch = nextch();
      }
    }

    // floating point!
    if(ch == '.' && numbase != NUM.HEX) {

      /* restrict s
       * if(parsemode == Parser.Mode.PROGRAMMER) {
        return null;
      }*/

      numbase = NUM.FLOAT;
      tstr += '.';
      ch = nextch();

      while(isdigit(ch)) {
        tstr += ch;
        ch = nextch();
      }

      // optional exponent
      if(ch == 'e' || ch == 'E') {
        tstr += ch;
        ch = nextch();

        if(ch == '-' || ch == '+') {
          tstr += ch;
          ch = nextch();
        }

        while(isdigit(ch)) {
          tstr += ch;
          ch = nextch();
        }
      }

      tnum = parseFloat(tstr);
    }
    else {
      tnum = parseInt(tstr, numbase);
    }

    return create_token(TOK.NUMBER, tnum);
  }

  //
  //
  //
  function parse_identifier() {
    tstr = '';

    while(isalpha(ch) || isdigit(ch) || ch == '_') {
      tstr += ch;
      ch = nextch();
    }
    return create_token(TOK.IDENTIFIER, tstr);
  }

  // this is the main function!
  function gettok() {
    ch = skipwhitespace();

    tpos = idx;

    // parse numbers
    if(isdigit(ch) || (ch == '.' && isdigit(peekch()))) {
      return parse_number();
    }

    // parse identifiers
    if(isalpha(ch) || ch == '_') {
      return parse_identifier();
    }

    // check for double-charactor operators
    switch(ch) {
    case '!': ch = nextch();
              if(ch == '=') {                               // !=
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.NEQ);
              }
              return create_token(TOK.OPERATOR, '!');       // !

    case '=': ch = nextch();
              if(ch == '=') {                               // ==
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.EQU);
              }
              return create_token(TOK.OPERATOR, '=');       // =

    case '<': ch = nextch();
              if(ch == '=') {                               // <=
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.LE);
              }
              else if(ch == '<') {                          // <<
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.SHR);
              }
              return create_token(TOK.OPERATOR, '<');       // <

    case '>': ch = nextch();
              if(ch == '=') {                               // >=
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.LE);
              }
              else if(ch == '>') {                          // >>
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.SHL);
              }
              return create_token(TOK.OPERATOR, '>');       // >

    case '&': ch = nextch();
              if(ch == '&') {                               // &&
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.ANDAND);
              }
              return create_token(TOK.OPERATOR, '&');       // &

    case '|': ch = nextch();
              if(ch == '|') {                               // ||
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK_OROR);
              }
              return create_token(TOK.OPERATOR, '|');       // |

    case '': case '':
    case '*': case '+': case '-': case '/': case '%': case '!': case '~':
    case '(': case ')': case '[': case ']':
    case '?': case ':':
    //case ';': case '
              var t = create_token(TOK.OPERATOR, ch);           // single-character operators
              ch = nextch();
              return t;

    case '': case '\x00':
              return create_token(TOK.NONE, '');
    default:                                                // unknown character!
              var t = create_token(TOK.UNKNOWN, ch);
              ch = nextch();
              return t;
    }

  }

  // return the 'interface' to the lexical analyser!
  return {
    init: init,
    gettok: gettok
  };
}

Parser.Parser = function() {

  var lexer = new Parser.Lexer();
  var TOK   = Parser.Token;
  var EXPR  = Parser.Expression;
  var NUM   = Parser.Number;
  var t     = { type: TOK.NONE };            // current token

  var ERR   = 0;

  function ExprNode(type, tok, left, right) {
    return {
      type:  type,      // one of EXPR_BINARY, EXPR_UNARY etc
      op:    tok,       // operator token
      left:  left,      // left-side ExprNode
      right: right      // right-side ExprNode
    }
  }

  function Precedence(t)
  {
    if(t.type != TOK.OPERATOR)
      return 0;

    switch(t.value)
    {
    // unary operators at 14+
    // '++', '--', '*', '&', '+', '-', '~', '!'

    // binary operators at 4 to 13 inclusive
    case '*': case '/': case '%': return 13;
    case '+': case '-':           return 12;
    case TOK.SHL: case TOK.SHR:   return 11;
    case '<': case '>':
    case TOK.LE : case TOK.GE:    return 10;
    case TOK.EQU: case TOK.NEQ:   return 9;
    case '&':                     return 8;
    case '^':                     return 7;
    case '|':                     return 6;
    case TOK.ANDAND:              return 5;
    case TOK.OROR:                return 4;

    // not referenced
    case '?':                     return 3;
    case '=':                     return 2;
    case ',':                     return 1;
    default:                      return 0;
    }
  }

  function PrimaryExpression() {

    var p = null;

    switch(t.type) {
    case TOK.NUMBER:
      p = ExprNode(EXPR.NUMBER, t);
      t = lexer.gettok();
      break;

    case TOK.IDENTIFIER:
      p = ExprNode(EXPR.IDENTIFIER, t);
      t = lexer.gettok();
      break;

    default:
      ERR = true;
      break;
    }

    return p;
  }

  function PostfixExpression(p) {

    var q = null;

    while(true) {
      var op = t;
      switch(op.type) {
        //case '[': // array bounds
        //case '.': // field access
        //case TOK.DEREF // ->
        //case TOK.INC: case TOK.DEC: // post increment/decrement
        //case '(': // function calls
        default:
          return p;
      }
    }
  }

  function UnaryExpression() {

    var op = t;
    var p  = null;

    if(op.type == TOK.OPERATOR) {

      switch(op.value) {
      /*case '*': case '&':  // pointer/address
        t = gettok();
        p = UnaryExpression();
        p = ExprNode(EXPR.POINTER, op, p);
      }*/
      case '+': case '-': case '~': case '!':
        t = lexer.gettok();
        p = UnaryExpression();
        p = ExprNode(EXPR.UNARY, op, p);
        return p;

      case '(':
        t = lexer.gettok();
        p = FullExpression(')');
        p = PostfixExpression(p);
        return p;
      }
    }

    //case TOK.INC: case TOK.DEC:
    //break;

    p = PrimaryExpression();
    p = PostfixExpression(p);

    return p;
  }

  function BinaryExpression(k) {
    var left = UnaryExpression();
    var i    = 0;

    for(i = Precedence(t); i >= k && i > 0; i--) {
      while(Precedence(t) == i && t != '=') {// && ch != '=') {
        var op = t;
        var right = 0;
        t = lexer.gettok();
        if(op.type == TOK.OPERATOR && (op.value == TOK.ANDAND || op.value == TOK.OROR)) {
          right = BinaryExpression(i);
        }
        else {
          right = BinaryExpression(i+1);
        }
        left = ExprNode(EXPR.BINARY, op, left, right);
      }
    }

    return left;
  }

  function ConditionalExpression() {

    var p = BinaryExpression(4);

    if(t.type == TOK.OPERATOR && t.value == '?') {
      var op = t;
      t = lexer.gettok();

      var left  = Expression(':');
      var right = ConditionalExpression();;

      p = ExprNode(EXPR.TERTIARY, op, left, right, p);
    }

    return p;
  }

  function Test(ch) {
    if(ch) {
      if(t.value == ch) {
        t = lexer.gettok();
        return true;
      }
      else {
        alert('error');
        return false;
      }
    }
  }

  function Expression(term) {
    var p = ConditionalExpression();

    Test(term);
    return p;
  }

  function FullExpression(term) {
    var p = Expression();

    if(term && !Test(term))
      return null;
    else
      return p;
  }

  function parse_expression() {
    return Expression(null)
  }

  function parse(expression, mode) {
    lexer.init(expression, mode);

    t = lexer.gettok();

    return parse_expression();
  }

  return {
    parse: parse
  };

}

Parser.Evaluator = function() {

  var parser = new Parser.Parser();
  var TOK    = Parser.Token;
  var EXPR   = Parser.Expression;
  var NUM    = Parser.Number;
  var evalmode   = null;

  function eval0(expr) {

    if(expr == null) {
      return null;
    }

    switch(expr.type) {

    case EXPR.IDENTIFIER:
      return null;//0;

    case EXPR.NUMBER:
      var val = expr.op.value;
      if(evalmode == 'Prg') {
        val = Math.floor(val);
      }

      return val;

    case EXPR.UNARY:
      var val = eval0(expr.left);

      switch(expr.op.value) {
        case '+': val =  val;         break;
        case '-': val = -val;         break;
        case '!': val = !val ? 1 : 0; break;
        case '~': val = ~val;         break;
        default:  val = null;         break; // error
      }

      if(evalmode == 'Prg') {
        val = Math.floor(val);
      }

      return val;

    case EXPR.BINARY:
      var lval = eval0(expr.left);
      var rval = eval0(expr.right);
      var val  = 0;

      switch(expr.op.value) {
        case '+':         val = lval + rval;  break;
        case '-':         val = lval - rval;  break;
        case '*':         val = lval * rval;  break;
        case '/':         val = lval / rval;  break;
        case '%':         val = lval % rval;  break;
        case '|':         val = lval | rval;  break;
        case '&':         val = lval & rval;  break;
        case TOK.ANDAND:  val = lval && rval; break;
        case TOK.OROR:    val = lval || rval; break;
        case TOK.SHR:     val = lval << rval; break;
        case TOK.SHL:     val = lval >> rval; break;
        case TOK.GE:      val = lval >= rval; break;
        case TOK.LE:      val = lval <= rval; break;
        case TOK.EQU:     val = lval == rval; break;
        case TOK.NEQ:     val = lval != rval; break;
      }

      if(evalmode == 'Prg') {
        val = Math.floor(val);
      }

      return val;

    default:
      return 0;
    }
  }

  function evalulate(str, mode) {
    evalmode = mode;
    expr = parser.parse(str, mode);
    if(expr == null) {
      return 'ERR';
    }

    var val = eval0(expr);

    if(val == null)
      val = 'ERR';

    return val;
  }

  return {
    evalulate: evalulate
  }

}
<commit_msg>Fixed stupid parsing error<commit_after>/*
 * parser.js
 *
 * www.catch22.net
 *
 * Copyright (C) 2012 James Brown
 * Licenced under the MIT licence
 * Please refer to the file LICENCE.TXT for copying permission
 */

var Parser;
Parser = Parser || {};

Parser.Token = {
    OPERATOR:   'Operator',
    IDENTIFIER: 'Identifier',
    NUMBER:     'Number',
    UNKNOWN:    'Unknown',
    NONE:       null,

    ANDAND: '&&',
    OROR:   '||',
    EQU:    '==',
    NEQ:    '!=',
    SHR:    '<<',
    SHL:    '>>'
};

Parser.Number = {
  DEC:   10,
  HEX:   16,
  OCT:   8,
  BIN:   2,
  FLOAT: 'Floating'
};

Parser.Expression = {
  BINARY:     'Binary',
  UNARY:      'Unary',
  NUMBER:     'Number',
  IDENTIFIER: 'Identifier'
};

Parser.Mode = {
  PROGRAMMER: 'Prg',
  NORMAL:     'Sci',
  FRACTION:   'Fra'
}

Parser.Lexer = function() {

  var buf = '2 + 2';
  var idx = 0;            // position in buf
  var ch  = '\x00';       // current character read
  var tstr = '';          // identifier
  var tnum = 0;           // number, if current token is TOK_NUMBER
  var numbase = 0;
  var NUM = Parser.Number;
  var TOK = Parser.Token;
  var tpos = 0;

  var parsemode = Parser.Mode.PROGRAMMER;

  function init(expression, mode) {
     buf  = expression;
     idx  = 0;
     ch   = nextch();
     t    = 0;

     parsemode = mode;
  }

  // return next character, don't read ahead
  function peekch() {
    return idx < buf.length ? buf.charAt(idx) : '\x00';
  }

  // return next character, and read ahead
  function nextch() {
    var c = '\x00';
    if(idx < buf.length) {
      c = buf.charAt(idx);
      idx += 1;
    }
    return c;
  }

  function isalpha(ch) {
    return ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z';
  }

  function isxdigit(ch) {
    return ch >= '0' && ch <= '9' || ch >= 'A' && ch <= 'F' || ch >= 'a' && ch <= 'f';
  }

  function isdigit(ch) {
    return ch >= '0' && ch <= '9';
  }

  function skipwhitespace() {
    while(ch == ' ' || ch == '\u0009' || ch == '\u00A0' || ch == '\u00D0')
      ch = nextch();
    return ch;
  }

  function create_token(type, val) {
    return {
      type:   type,
      value:  val,
      base:   numbase,
      pos:    tpos
    };
  }

  //
  //  Parse hex/decimal/octal/float numbers
  //  return a NUMBER Token
  //
  function parse_number() {

    tstr = '';

    if(ch == '0') {     // Hex/Octal
      ch = nextch();

      if(ch == 'X' || ch == 'x') {    // Hex
        ch = nextch();
        while(isxdigit(ch)) {
          tstr += ch;
          ch = nextch();
        }

        numbase = NUM.HEX;
      }
      else if(ch == 'B' || ch == 'b') {    // Bin
        ch = nextch();
        while(isxdigit(ch)) {
          tstr += ch;
          ch = nextch();
        }

        numbase = NUM.BIN;
      }
      else {            // Octal
        tstr = '0';
        while(isdigit(ch)) {
          tstr += ch;
          ch = nextch();
        }
        numbase = NUM.OCT;
      }
    }
    else {            // Decimal

      numbase = NUM.DEC;
      tstr = '';

      while(isdigit(ch)) {
        tstr += ch;
        ch = nextch();
      }
    }

    // floating point!
    if(ch == '.' && numbase != NUM.HEX) {

      /* restrict s
       * if(parsemode == Parser.Mode.PROGRAMMER) {
        return null;
      }*/

      numbase = NUM.FLOAT;
      tstr += '.';
      ch = nextch();

      while(isdigit(ch)) {
        tstr += ch;
        ch = nextch();
      }

      // optional exponent
      if(ch == 'e' || ch == 'E') {
        tstr += ch;
        ch = nextch();

        if(ch == '-' || ch == '+') {
          tstr += ch;
          ch = nextch();
        }

        while(isdigit(ch)) {
          tstr += ch;
          ch = nextch();
        }
      }

      tnum = parseFloat(tstr);
    }
    else {
      tnum = parseInt(tstr, numbase);
    }

    return create_token(TOK.NUMBER, tnum);
  }

  //
  //
  //
  function parse_identifier() {
    tstr = '';

    while(isalpha(ch) || isdigit(ch) || ch == '_') {
      tstr += ch;
      ch = nextch();
    }
    return create_token(TOK.IDENTIFIER, tstr);
  }

  // this is the main function!
  function gettok() {
    ch = skipwhitespace();

    tpos = idx;

    // parse numbers
    if(isdigit(ch) || (ch == '.' && isdigit(peekch()))) {
      return parse_number();
    }

    // parse identifiers
    if(isalpha(ch) || ch == '_') {
      return parse_identifier();
    }

    // check for double-charactor operators
    switch(ch) {
    case '!': ch = nextch();
              if(ch == '=') {                               // !=
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.NEQ);
              }
              return create_token(TOK.OPERATOR, '!');       // !

    case '=': ch = nextch();
              if(ch == '=') {                               // ==
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.EQU);
              }
              return create_token(TOK.OPERATOR, '=');       // =

    case '<': ch = nextch();
              if(ch == '=') {                               // <=
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.LE);
              }
              else if(ch == '<') {                          // <<
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.SHR);
              }
              return create_token(TOK.OPERATOR, '<');       // <

    case '>': ch = nextch();
              if(ch == '=') {                               // >=
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.LE);
              }
              else if(ch == '>') {                          // >>
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.SHL);
              }
              return create_token(TOK.OPERATOR, '>');       // >

    case '&': ch = nextch();
              if(ch == '&') {                               // &&
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK.ANDAND);
              }
              return create_token(TOK.OPERATOR, '&');       // &

    case '|': ch = nextch();
              if(ch == '|') {                               // ||
                ch = nextch();
                return create_token(TOK.OPERATOR, TOK_OROR);
              }
              return create_token(TOK.OPERATOR, '|');       // |

    case '': case '':
    case '*': case '+': case '-': case '/': case '%': case '!': case '~':
    case '(': case ')': case '[': case ']':
    case '?': case ':':
    //case ';': case '
              var t = create_token(TOK.OPERATOR, ch);           // single-character operators
              ch = nextch();
              return t;

    case '': case '\x00':
              return create_token(TOK.NONE, '');
    default:                                                // unknown character!
              var t = create_token(TOK.UNKNOWN, ch);
              ch = nextch();
              return t;
    }

  }

  // return the 'interface' to the lexical analyser!
  return {
    init: init,
    gettok: gettok
  };
}

Parser.Parser = function() {

  var lexer = new Parser.Lexer();
  var TOK   = Parser.Token;
  var EXPR  = Parser.Expression;
  var NUM   = Parser.Number;
  var t     = { type: TOK.NONE };            // current token

  var ERR   = 0;

  function ExprNode(type, tok, left, right) {
    return {
      type:  type,      // one of EXPR_BINARY, EXPR_UNARY etc
      op:    tok,       // operator token
      left:  left,      // left-side ExprNode
      right: right      // right-side ExprNode
    }
  }

  function Precedence(t)
  {
    if(t.type != TOK.OPERATOR)
      return 0;

    switch(t.value)
    {
    // unary operators at 14+
    // '++', '--', '*', '&', '+', '-', '~', '!'

    // binary operators at 4 to 13 inclusive
    case '*': case '/': case '%': return 13;
    case '+': case '-':           return 12;
    case TOK.SHL: case TOK.SHR:   return 11;
    case '<': case '>':
    case TOK.LE : case TOK.GE:    return 10;
    case TOK.EQU: case TOK.NEQ:   return 9;
    case '&':                     return 8;
    case '^':                     return 7;
    case '|':                     return 6;
    case TOK.ANDAND:              return 5;
    case TOK.OROR:                return 4;

    // not referenced
    case '?':                     return 3;
    case '=':                     return 2;
    case ',':                     return 1;
    default:                      return 0;
    }
  }

  function PrimaryExpression() {

    var p = null;

    switch(t.type) {
    case TOK.NUMBER:
      p = ExprNode(EXPR.NUMBER, t);
      t = lexer.gettok();
      break;

    case TOK.IDENTIFIER:
      p = ExprNode(EXPR.IDENTIFIER, t);
      t = lexer.gettok();
      break;

    default:
      ERR = true;
      break;
    }

    return p;
  }

  function PostfixExpression(p) {

    var q = null;

    while(true) {
      var op = t;
      switch(op.type) {
        //case '[': // array bounds
        //case '.': // field access
        //case TOK.DEREF // ->
        //case TOK.INC: case TOK.DEC: // post increment/decrement
        //case '(': // function calls
        default:
          return p;
      }
    }
  }

  function UnaryExpression() {

    var op = t;
    var p  = null;

    if(op.type == TOK.OPERATOR) {

      switch(op.value) {
      /*case '*': case '&':  // pointer/address
        t = gettok();
        p = UnaryExpression();
        p = ExprNode(EXPR.POINTER, op, p);
      }*/
      case '+': case '-': case '~': case '!':
        t = lexer.gettok();
        p = UnaryExpression();
        p = ExprNode(EXPR.UNARY, op, p);
        return p;

      case '(':
        t = lexer.gettok();
        p = FullExpression(')');
        p = PostfixExpression(p);
        return p;
      }
    }

    //case TOK.INC: case TOK.DEC:
    //break;

    p = PrimaryExpression();
    p = PostfixExpression(p);

    return p;
  }

  function BinaryExpression(k) {
    var left = UnaryExpression();
    var i    = 0;

    for(i = Precedence(t); i >= k && i > 0; i--) {
      while(Precedence(t) == i && t != '=') {// && ch != '=') {
        var op = t;
        var right = 0;
        t = lexer.gettok();
        if(op.type == TOK.OPERATOR && (op.value == TOK.ANDAND || op.value == TOK.OROR)) {
          right = BinaryExpression(i);
        }
        else {
          right = BinaryExpression(i+1);
        }
        left = ExprNode(EXPR.BINARY, op, left, right);
      }
    }

    return left;
  }

  function ConditionalExpression() {

    var p = BinaryExpression(4);

    if(t.type == TOK.OPERATOR && t.value == '?') {
      var op = t;
      t = lexer.gettok();

      var left  = Expression(':');
      var right = ConditionalExpression();;

      p = ExprNode(EXPR.TERTIARY, op, left, right, p);
    }

    return p;
  }

  function Test(ch) {
    if(ch) {
      if(t.value == ch) {
        t = lexer.gettok();
        return true;
      }
      else {
        alert('error');
        return false;
      }
    }
  }

  function Expression(term) {
    var p = ConditionalExpression();

    Test(term);
    return p;
  }

  function FullExpression(term) {
    var p = Expression();

    if(term && !Test(term))
      return null;
    else
      return p;
  }

  function parse_expression() {
    return Expression(null)
  }

  function parse(expression, mode) {
    lexer.init(expression, mode);

    t = lexer.gettok();

    return parse_expression();
  }

  return {
    parse: parse
  };

}

Parser.Evaluator = function() {

  var parser = new Parser.Parser();
  var TOK    = Parser.Token;
  var EXPR   = Parser.Expression;
  var NUM    = Parser.Number;
  var evalmode   = null;

  function eval0(expr) {

    if(expr == null) {
      return null;
    }

    switch(expr.type) {

    case EXPR.IDENTIFIER:
      return null;//0;

    case EXPR.NUMBER:
      var val = expr.op.value;
      if(evalmode == 'Prg') {
        val = Math.floor(val);
      }

      return val;

    case EXPR.UNARY:
      var val = eval0(expr.left);

      switch(expr.op.value) {
        case '+': val =  val;         break;
        case '-': val = -val;         break;
        case '!': val = !val ? 1 : 0; break;
        case '~': val = ~val;         break;
        default:  val = null;         break; // error
      }

      if(evalmode == 'Prg') {
        val = Math.floor(val);
      }

      return val;

    case EXPR.BINARY:
      var lval = eval0(expr.left);
      var rval = eval0(expr.right);
      var val  = 0;

      switch(expr.op.value) {
        case '+':         val = lval + rval;  break;
        case '-':         val = lval - rval;  break;
        case '*':         val = lval * rval;  break;
        case '/':         val = lval / rval;  break;
        case '%':         val = lval % rval;  break;
        case '|':         val = lval | rval;  break;
        case '&':         val = lval & rval;  break;
        case TOK.ANDAND:  val = lval && rval; break;
        case TOK.OROR:    val = lval || rval; break;
        case TOK.SHR:     val = lval << rval; break;
        case TOK.SHL:     val = lval >> rval; break;
        case TOK.GE:      val = lval >= rval; break;
        case TOK.LE:      val = lval <= rval; break;
        case TOK.EQU:     val = lval == rval; break;
        case TOK.NEQ:     val = lval != rval; break;
      }

      if(evalmode == 'Prg') {
        val = Math.floor(val);
      }

      return val;

    default:
      return 0;
    }
  }

  function evalulate(str, mode) {
    evalmode = mode;
    expr = parser.parse(str, mode);
    if(expr == null) {
      return 'ERR';
    }

    var val = eval0(expr);

    if(val == null)
      val = 'ERR';

    return val;
  }

  return {
    evalulate: evalulate
  }

}
<|endoftext|>