diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js index 41de49aed641786618325d1dd9d9b0820282ac7d..69cfeef82f5913590d478fc11806f7e1e24c3125 100644 --- a/pd/nw/pdgui.js +++ b/pd/nw/pdgui.js @@ -5605,3 +5605,159 @@ function gui_pddplink_open(filename, dir) { post("pddplink: error: file not found: " + filename); } } + +// Stuff from m_binbuf.c ported to js + +function binbuf_text(str) { + var binbuf = []; + var token = ""; + var whitespace = function(c) { + return (c == " " || c == "\n" || c == "\r" || c == "\t"); + }; + var floatstate = 0, slash = false, lastslash = false, dollar = false; + var digit, dot, plusminus, minus, expon; + + str.split("").forEach(function(c, i, a) { + // Skip leading/trailing whitespace. String.trim also trims + // non-breaking spaces which Pd doesn't do, so we avoid that for now + if (!slash && whitespace(c)) { + return; + } + + if (!slash && c === ";") { + token = { type: "semi" }; + a.push(token); + } else if (!slash && c === ",") { + token = { type: "semi" }; + a.push(token); + } else { + lastslash = slash; + slash = (c === "\\"); + if (floatstate >= 0) + { + digit = (c >= "0" && c <= "9"); + dot = (c == "."); + minus = (c == "-"); + plusminus = (minus || (c == "+")); + expon = (c == "e" || c == "E"); + if (floatstate == 0) /* beginning */ + { + if (minus) floatstate = 1; + else if (digit) floatstate = 2; + else if (dot) floatstate = 3; + else floatstate = -1; + } + else if (floatstate == 1) /* got minus */ + { + if (digit) floatstate = 2; + else if (dot) floatstate = 3; + else floatstate = -1; + } + else if (floatstate == 2) /* got digits */ + { + if (dot) floatstate = 4; + else if (expon) floatstate = 6; + else if (!digit) floatstate = -1; + } + else if (floatstate == 3) /* got '.' without digits */ + { + if (digit) floatstate = 5; + else floatstate = -1; + } + else if (floatstate == 4) /* got '.' after digits */ + { + if (digit) floatstate = 5; + else if (expon) floatstate = 6; + else floatstate = -1; + } + else if (floatstate == 5) /* got digits after . */ + { + if (expon) floatstate = 6; + else if (!digit) floatstate = -1; + } + else if (floatstate == 6) /* got 'e' */ + { + if (plusminus) floatstate = 7; + else if (digit) floatstate = 8; + else floatstate = -1; + } + else if (floatstate == 7) /* got plus or minus */ + { + if (digit) floatstate = 8; + else floatstate = -1; + } + else if (floatstate == 8) /* got digits */ + { + if (!digit) floatstate = -1; + } + } + if (!lastslash && c == "$" && (i < (a.length - 1) && + (a[i+1].charCodeAt(0) >= 48 && a[i+1].charCodeAt(0) <= 57) || + a[i+1] == "@")) { + dollar = true; + } + if (!slash) { + token += c; + } + else if (lastslash) { + token += c; + slash = false; + } + } + // If we got a full token let's push it + if (!slash && (i == a.length - 1 || whitespace(a[i+1]))) { + if (floatstate == 2 || floatstate == 4 || floatstate == 5 || + floatstate == 8) { + binbuf.push({ + type: "float", + value: token + }); + } else if (dollar) { + if (token.charAt(1) == "@") + { + if (token == "$@") { + binbuf.push({ + type: "dollar", + value: "@" + }); + } else { + binbuf.push({ + type: "symbol", + value: token + }); + } + } + else + { + if (token.charAt(0) != '$') + dollar = false; + token.slice(1).split("").forEach(function(c){ + if (c.charCodeAt(0) < 48 || c.charCodeAt(0) > 57) { + dollar = false; + } + }); + if (dollar) { + binbuf.push({ + type: "dollar", + value: token.slice(1) + }); + } else { + binbuf.push({ + type: "dollsym", + value: token + }); + } + } + } else { + binbuf.push({ + type: "symbol", + value: token + }); + } + floatstate = 0, dollar = false, token = ""; + } + }); + return binbuf; +} + +exports.binbuf_text = binbuf_text;