Javascript (ES6), 453 bytes
The first and most obvious solution that came to my mind is one that looks around the slides and then merges or replaces.
a=>{b=(d,e,f)=>d.substr(0,e)+f+d.substr(e+(''+f).length);g=0;a=a.split`
`.map(h=>h.replace(/o/g,'1'));j=i=>i.match(/[0-9]/);k=' ';while(!g){g=1;for(r=a.length-2;r>0;r--){for(c=1;c<a[r].length-1;c++){nr=r+1;l=b(a[r],c,k);nc=a[nr][c]=='\\'?c+1:a[nr][c]=='/'?c-1:a[nr][c]==k||j(a[nr][c])?c:null;j(a[r][c])&&nc!=null?j(a[nr][nc])?(a[nr]=b(a[nr],nc,+a[nr][nc]+ +a[r][c]),a[r]=l,g=0):a[nr][nc]==k?(a[nr]=b(a[nr],nc,a[r][c]),a[r]=l,g=0):0:0}}}return a.join`
`}
Ungolfed:
state => {
replaceAt = (str, index, char) => str.substr(0, index) + char + str.substr(index + ('' + char).length);
complete = 0;
state = state.split `\n`.map(line => line.replace(/o/g, '1'));
isNumber = inp => inp.match(/[0-9]/);
space = ' ';
while (!complete) {
complete = 1;
for (r = state.length - 2; r > 0; r--) {
for (c = 1; c < state[r].length - 1; c++) {
nr = r + 1;
nc = state[nr][c] == '\\' ? c + 1 : state[nr][c] == '/' ? c - 1 : state[nr][c] == space || isNumber(state[nr][c]) ? c : null;
replacedLine = replaceAt(state[r], c, space);
isNumber(state[r][c]) && nc != null ?
isNumber(state[nr][nc]) ? (
state[nr] = replaceAt(state[nr], nc, +state[nr][nc] + +state[r][c]),
state[r] = replacedLine,
complete = 0
) : state[nr][nc] == space ? (
state[nr] = replaceAt(state[nr], nc, state[r][c]),
state[r] = replacedLine,
complete = 0
) : 0
: 0
}
}
}
return state.join `\n`;
}
Lookaround and string manipulation are not cheap. Interested in your 389b Python code.