/*

    Kit's JavaScript Brainfuck Interpeter
    http://brainfuck.progopedia.org/

    @licstart  The following is the entire license notice for the
    JavaScript code in this page.

    Copyright (C) 2009 Sergey Dymchenko

    The JavaScript code in this page is free software: you can
    redistribute it and/or modify it under the terms of the GNU
    General Public License (GNU GPL) as published by the Free Software
    Foundation, either version 3 of the License, or (at your option)
    any later version.  The code is distributed WITHOUT ANY WARRANTY;
    without even the implied warranty of MERCHANTABILITY or FITNESS
    FOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.

    As additional permission under GNU GPL version 3 section 7, you
    may distribute non-source (e.g., minimized or compacted) forms of
    that code without the copy of the GNU GPL normally required by
    section 4, provided you include this license notice and a URL
    through which recipients can access the Corresponding Source.

    @licend  The above is the entire license notice
    for the JavaScript code in this page.

    @source: http://brainfuck.progopedia.org/kits-js-brainfuck-0.1.tar.gz

*/


function bf_interpret(prog, params) {
    var mem_size = 30000;
    var max_val = 255;
    var a = [];

    var i;
    for (i = 0; i < mem_size; i++) {
	a[i]=0;
    }

    var p = 0;
    var l = 0;
    var argi = 0;

    var result = '';

    for (i = 0; i < prog.length; i++) {
	switch (prog.charAt(i)) {
	case ">":
	    p++; p %= mem_size;
	    break;
	case "<":
	    p--; p %= mem_size;
	    break;
	case "+":
	    a[p]++; a[p] %= max_val;
	    break;
	case "-":
	    a[p]--; a[p] %= max_val;
	    break;
	case ".":
	    result += String.fromCharCode(a[p]);
	    break;
	case ",":
	    a[p] = params.charCodeAt(argi);
	    argi++;
	    break;
	case "[":
	    if (a[p] === 0) {
		for (i++; l > 0 || prog.charAt(i) != ']'; i++) {
		    if (prog.charAt(i) == '[') {
			l++;
		    }
		    if (prog.charAt(i) == ']') {
			l--;
		    }
		}
	    }
	    break;
	case "]":
	    for (i--; l > 0 || prog.charAt(i) != '['; i--) {
		if (prog.charAt(i) == ']') {
		    l++;
		}
		if (prog.charAt(i) == '[') {
		    l--;
		}
	    }
	    i--;
	    break;
	}
    }

    return result;
}


/*
 * Return 1 if closing bracket(s) missing.
 * Return 2 if opening bracket(s) missing.
 * Return 3 if closing bracket before opening bracket encountered.
 * Return 0 otherwise.
 */
function bf_validate_brackets(program) {
    var ob = 0;
    var cb = 0;
    for (var i = 0; i < program.length; i++) {
	if (program.charAt(i) == '[') {
	    ob++;
	} else if (program.charAt(i) == ']') {
	    cb++;
	    if (cb > ob) {
		return 3; // alert("Closing bracket before opening bracket!");
	    }
	}
    }

    if (ob > cb) {
	return 1; // alert("Missing closing bracket(s)!");
    }
    if (ob < cb) {
	return 2; // alert("Missing opening bracket(s)!");
    }

    return 0;
}

