function resolvePN(str) {
let stack = [[]]let ops = {
"*": (a b) => a * b
"/": (a b) => a / b
"+": (a b) => a + b
"-": (a b) => a - b
}let parts = str.split(" ")let stackEachIteration = []stackEachIteration.push({ stack: JSON.parse(JSON.stringify(stack)) index: -1 })for (let i = 0let part = parts[i]if (ops[part]) {
stack.push([part])} else {
stack[stack.length - 1].push(parseInt(part))}
stackEachIteration.push({ stack: JSON.parse(JSON.stringify(stack)) index: i })while (true) {
if (stack[stack.length - 1].length === 3) {
let op = ops[stack[stack.length - 1][0]] let result = op(stack[stack.length - 1][1] stack[stack.length - 1][2]) stack.pop() stack[stack.length - 1].push(result) stackEachIteration.push({ stack: JSON.parse(JSON.stringify(stack)) index: i }) } else { break}
}
return {
finalAnswer: stack[0][0]
finalStack: stack
stackEachIteration
expr: str
}}
function drawExpr(expr highlightIndex height = 0.3) {
let parts = expr.split(" ")let tex = ""parts.forEach((part index) => {
let partStr = partif (part === "+") {
partStr = "+"} else if (part === "*") {
partStr = "\\times"} else if (part === "/") {
partStr = "\\div"}
if (index === highlightIndex) {
partStr = `\\colorbox{cyan}{\$${partStr}\$}`} else {
partStr = `\\colorbox{white}{\$${partStr}\$}`}
partStr += "\\,"tex += partStr})return latex(tex height)}
let stackSquare = outline(square(0.10 "cyan") 0.01)let stackParts = [
[sprite(stackSquare 0.03 0.03) sprite(stackSquare 0.25 0.03) sprite(stackSquare 0.47 0.03) sprite(stackSquare 0.69 0.03)]
[sprite(stackSquare 0.03 0.25) sprite(stackSquare 0.25 0.25) sprite(stackSquare 0.47 0.25) sprite(stackSquare 0.69 0.25)]
[sprite(stackSquare 0.03 0.47) sprite(stackSquare 0.25 0.47) sprite(stackSquare 0.47 0.47) sprite(stackSquare 0.69 0.47)]
]stackParts.forEach(a => a.forEach(b => b.hidden = true))
let stackLines = []function drawStackLine(fromRow fromCol) {
console.log(fromRow fromCol)if (fromRow === 0 && fromCol !== 0) returnlet toRow = fromRow + 1let newLine = line(0.03 + (toRow * 0.22) 0.114 "#1fa9ab" 0.025)let newX = (fromRow * 0.22) + 0.13let newY = (fromCol * 0.22) + 0.01 + 0.095if (stackLines[fromRow]) {
stackLines[fromRow].move(newX newY 0)} else {
stackLines[fromRow] = sprite(square(0) newX newY)}
stackLines[fromRow].shape=newLine}
//drawStackLine(0 1 2)
function drawStack(stack) {
}
let stackPartsText = []for (let i = 0stackPartsText.push([])for (let j = 0stackPartsText[i][j] = sprite(latex("") stackParts[i][j].x + 0.007 stackParts[i][j].y + 0.026)}
}
let pn1spfunction renderPn(pn curFrame exprHeight = 0.3 moveExpr1 = false) {
stackLines = []let pn1 = resolvePN(pn)pn1sp = sprite(square(0) 0 0.68)pn1.stackEachIteration.forEach((iter index) => {
on(curFrame () => {
for (let i = 0 for (let j = 0 // i: row j: col
let text = square(0) if (iter.stack[j] && iter.stack[j][i]) {
let partStr = iter.stack[j][i].toString() let len = partStr.length * 0.5 if (partStr.length === 1) len = 0.7 if (partStr === "15") len = 0.9 if (partStr === "-3") len = 1.05 if (partStr === "0.5") len = 1.1 if (partStr === "1.5") len = 1.1 if (partStr === "*") {
partStr = "\\times" len = 1 } else if (partStr === "/") {
partStr = "\\div" len = 0.8 }
text = latex(partStr 0.09 * (1/len)) }
transitionSprite(stackPartsText[i][j] text "fade" 10) }
}
stackParts.forEach((col colIndex) => {
col.forEach((item index) => {
if (index === 0) {
item.hidden = (colIndex !== 0) } else {
item.hidden = index > (iter.stack.length - 1) }
}) }) let colCount = stackParts[0].length for (let col = 0 let shouldDrawLine = iter.stack[col] console.log("sL" iter.stack.length) if (col >= (iter.stack.length - 1)) shouldDrawLine = false if (shouldDrawLine) {
drawStackLine(col iter.stack[col].length) } else if (stackLines[col]) {
stackLines[col].shape = square(0) }
}
if (index === 0 && moveExpr1) {
transitionSprite(expr1 drawExpr(pn1.expr iter.index exprHeight) "move_pixels" 30) expr1.move(pn1sp.x pn1sp.y 25) } else {
transitionSprite(pn1sp drawExpr(pn1.expr iter.index exprHeight) "fade" 30) expr1.hidden = true }
})curFrame += 60})return curFrame}
let expr1 = sprite(latex("") 0.008 0.1)async function play() {
let curFrame = 0let num1 = sprite(latex("2" 0.3) 0.1 0.1)let sign = sprite(latex("\\div" 0.3) 0.25 0.1)let num2 = sprite(latex("3" 0.3) 0.5 0.1)curFrame += 60on(curFrame () => {
sign.move(0.05 0.1 60)num1.move(0.3 0.1 60)})curFrame += 120on(curFrame () => {
transitionSprite(num1 square(0) "fade" 60)transitionSprite(num2 square(0) "fade" 60)transitionSprite(sign square(0) "fade" 60)transitionSprite(expr1 latex("5(1 + 2)" 0.35) "fade" 60)})curFrame += 120curFrame = renderPn("* 5 + 1 2" curFrame 0.3 true)curFrame += 60curFrame = renderPn("/ - 5 8 * 3 / 5 10" curFrame 0.185)}
play()