Example #1
0
function interpret($slice, $more = "")
{
    global $SLICE_LEN;
    global $stack;
    global $TYPE_NUMBER, $TYPE_STRING, $TYPE_CHARACTER, $TYPE_FUNCTION, $TYPE_FLAG;
    global $BC_PUSH_N, $BC_PUSH_S, $BC_PUSH_C, $BC_PUSH_F, $BC_PUSH_COMMENT;
    global $BC_TYPE_N, $BC_TYPE_S, $BC_TYPE_C, $BC_TYPE_F, $BC_TYPE_FLAG;
    global $BC_GET_TYPE, $BC_ADD, $BC_SUBTRACT, $BC_MULTIPLY, $BC_DIVIDE;
    global $BC_REMAINDER, $BC_FLOOR, $BC_POW, $BC_BITWISE_SHIFT, $BC_BITWISE_AND, $BC_BITWISE_OR;
    global $BC_BITWISE_XOR, $BC_COMPARE_LT, $BC_COMPARE_GT, $BC_COMPARE_LTEQ, $BC_COMPARE_GTEQ;
    global $BC_COMPARE_EQ, $BC_COMPARE_NEQ, $BC_FLOW_IF, $BC_FLOW_WHILE, $BC_FLOW_UNTIL;
    global $BC_FLOW_TIMES, $BC_FLOW_CALL, $BC_FLOW_CALL_F, $BC_FLOW_DIP, $BC_FLOW_SIP;
    global $BC_FLOW_BI, $BC_FLOW_TRI, $BC_FLOW_RETURN, $BC_MEM_COPY, $BC_MEM_FETCH;
    global $BC_MEM_STORE, $BC_MEM_REQUEST, $BC_MEM_RELEASE, $BC_MEM_COLLECT, $BC_STACK_DUP;
    global $BC_STACK_DROP, $BC_STACK_SWAP, $BC_STACK_OVER, $BC_STACK_TUCK, $BC_STACK_NIP;
    global $BC_STACK_DEPTH, $BC_STACK_CLEAR, $BC_QUOTE_NAME, $BC_STRING_SEEK, $BC_STRING_SUBSTR;
    global $BC_STRING_NUMERIC, $BC_TO_LOWER, $BC_TO_UPPER, $BC_LENGTH, $BC_REPORT_ERROR;
    $offset = 0;
    while ($offset < $SLICE_LEN) {
        $opcode = intval(fetch($slice, $offset));
        if ($opcode == $BC_PUSH_N) {
            $offset += 1;
            stack_push(floatval(fetch($slice, $offset)), $TYPE_NUMBER);
        } elseif ($opcode == $BC_PUSH_S) {
            $offset += 1;
            stack_push(floatval(fetch($slice, $offset)), $TYPE_STRING);
        } elseif ($opcode == $BC_PUSH_C) {
            $offset += 1;
            stack_push(floatval(fetch($slice, $offset)), $TYPE_CHARACTER);
        } elseif ($opcode == $BC_PUSH_F) {
            $offset += 1;
            stack_push(floatval(fetch($slice, $offset)), $TYPE_FUNCTION);
        } elseif ($opcode == $BC_PUSH_COMMENT) {
            $offset += 1;
        } elseif ($opcode == $BC_TYPE_N) {
            if (check_depth(1)) {
                stack_change_type($TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_TYPE_S) {
            if (check_depth(1)) {
                stack_change_type($TYPE_STRING);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_TYPE_C) {
            if (check_depth(1)) {
                stack_change_type($TYPE_CHARACTER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_TYPE_F) {
            if (check_depth(1)) {
                stack_change_type($TYPE_FUNCTION);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_TYPE_FLAG) {
            if (check_depth(1)) {
                stack_change_type($TYPE_FLAG);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_GET_TYPE) {
            if (check_depth(1)) {
                stack_push(stack_type(), $TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_ADD) {
            if (check_depth(2)) {
                $x = stack_type();
                $a = stack_pop();
                $y = stack_type();
                $b = stack_pop();
                if ($x == $TYPE_NUMBER and $y == $TYPE_NUMBER) {
                    stack_push($a + $b, $TYPE_NUMBER);
                } elseif ($x == $TYPE_STRING and $y == $TYPE_STRING) {
                    $a = slice_to_string($a);
                    $b = slice_to_string($b);
                    stack_push(string_to_slice($b . $a), $TYPE_STRING);
                } else {
                    $offset = $SLICE_LEN;
                    report_error('$BC_ADD only works with NUMBER and STRING types, found ' . "{$x}:{$a} and {$y}:{$b}");
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_SUBTRACT) {
            if (check_depth(2)) {
                $a = stack_pop();
                $b = stack_pop();
                stack_push($b - $a, $TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_MULTIPLY) {
            if (check_depth(2)) {
                $a = stack_pop();
                $b = stack_pop();
                stack_push($a * $b, $TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_DIVIDE) {
            if (check_depth(2)) {
                $a = stack_pop();
                $b = stack_pop();
                stack_push($b / $a, $TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_REMAINDER) {
            if (check_depth(2)) {
                $a = stack_pop();
                $b = stack_pop();
                stack_push($b % $a, $TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_FLOOR) {
            if (check_depth(1)) {
                $a = stack_pop();
                $a = floatval($a);
                stack_push(floor($a), $TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_POW) {
            if (check_depth(2)) {
                $a = stack_pop();
                $a = floatval($a);
                $b = stack_pop();
                $b = floatval($b);
                stack_push(pow($b, $a), $TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_BITWISE_SHIFT) {
            if (check_depth(2)) {
                $a = stack_pop();
                $b = stack_pop();
                if ($a < 0) {
                    stack_push($b << abs($a), $TYPE_NUMBER);
                } else {
                    stack_push($b >> $a, $TYPE_NUMBER);
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_BITWISE_AND) {
            if (check_depth(2)) {
                $a = intval(stack_pop());
                $b = intval(stack_pop());
                stack_push($b & $a, $TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_BITWISE_OR) {
            if (check_depth(2)) {
                $a = intval(stack_pop());
                $b = intval(stack_pop());
                stack_push($b | $a, $TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_BITWISE_XOR) {
            if (check_depth(2)) {
                $a = intval(stack_pop());
                $b = intval(stack_pop());
                stack_push($b ^ $a, $TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_COMPARE_LT) {
            if (check_depth(2)) {
                $x = stack_type();
                $a = stack_pop();
                $y = stack_type();
                $b = stack_pop();
                if ($x == $TYPE_NUMBER and $y == $TYPE_NUMBER) {
                    if ($b < $a) {
                        stack_push(-1, $TYPE_FLAG);
                    } else {
                        stack_push(0, $TYPE_FLAG);
                    }
                } else {
                    $offset = $SLICE_LEN;
                    report_error('$BC_COMPARE_LT only recognizes NUMBER types');
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_COMPARE_GT) {
            if (check_depth(2)) {
                $x = stack_type();
                $a = stack_pop();
                $y = stack_type();
                $b = stack_pop();
                if ($x == $TYPE_NUMBER and $y == $TYPE_NUMBER) {
                    if ($b > $a) {
                        stack_push(-1, $TYPE_FLAG);
                    } else {
                        stack_push(0, $TYPE_FLAG);
                    }
                } else {
                    $offset = $SLICE_LEN;
                    report_error('$BC_COMPARE_LT only recognizes NUMBER types');
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_COMPARE_LTEQ) {
            if (check_depth(2)) {
                $x = stack_type();
                $a = stack_pop();
                $y = stack_type();
                $b = stack_pop();
                if ($x == $TYPE_NUMBER and $y == $TYPE_NUMBER) {
                    if ($b <= $a) {
                        stack_push(-1, $TYPE_FLAG);
                    } else {
                        stack_push(0, $TYPE_FLAG);
                    }
                } else {
                    $offset = $SLICE_LEN;
                    report_error('$BC_COMPARE_LTEQ only recognizes NUMBER types');
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_COMPARE_GTEQ) {
            if (check_depth(2)) {
                $x = stack_type();
                $a = stack_pop();
                $y = stack_type();
                $b = stack_pop();
                if ($x == $TYPE_NUMBER and $y == $TYPE_NUMBER) {
                    if ($b >= $a) {
                        stack_push(-1, $TYPE_FLAG);
                    } else {
                        stack_push(0, $TYPE_FLAG);
                    }
                } else {
                    $offset = $SLICE_LEN;
                    report_error('$BC_COMPARE_GTEQ only recognizes NUMBER types');
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_COMPARE_EQ) {
            if (check_depth(2)) {
                $x = stack_type();
                $a = stack_pop();
                $y = stack_type();
                $b = stack_pop();
                if ($x == $y and $x != $TYPE_STRING) {
                    if ($b == $a) {
                        stack_push(-1, $TYPE_FLAG);
                    } else {
                        stack_push(0, $TYPE_FLAG);
                    }
                } elseif ($x == $y and $x == $TYPE_STRING) {
                    if (slice_to_string($b) == slice_to_string($a)) {
                        stack_push(-1, $TYPE_FLAG);
                    } else {
                        stack_push(0, $TYPE_FLAG);
                    }
                } else {
                    $offset = $SLICE_LEN;
                    report_error('$BC_COMPARE_EQ requires matched types');
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_COMPARE_NEQ) {
            if (check_depth(2)) {
                $x = stack_type();
                $a = stack_pop();
                $y = stack_type();
                $b = stack_pop();
                if ($x == $y and $x != $TYPE_STRING) {
                    if ($b != $a) {
                        stack_push(-1, $TYPE_FLAG);
                    } else {
                        stack_push(0, $TYPE_FLAG);
                    }
                } elseif ($x == $y and $x == $TYPE_STRING) {
                    if (slice_to_string($b) != slice_to_string($a)) {
                        stack_push(-1, $TYPE_FLAG);
                    } else {
                        stack_push(0, $TYPE_FLAG);
                    }
                } else {
                    $offset = $SLICE_LEN;
                    report_error('$BC_COMPARE_NEQ requires matched types');
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_FLOW_IF) {
            if (check_depth(3)) {
                $a = stack_pop();
                $b = stack_pop();
                $c = stack_pop();
                if ($c == -1) {
                    interpret($b, $more);
                } else {
                    interpret($a, $more);
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_FLOW_WHILE) {
            if (check_depth(1)) {
                $quote = stack_pop();
                $a = -1;
                while ($a == -1) {
                    interpret($quote, $more);
                    $a = stack_pop();
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_FLOW_UNTIL) {
            if (check_depth(1)) {
                $quote = stack_pop();
                $a = 0;
                while ($a == 0) {
                    interpret($quote, $more);
                    $a = stack_pop();
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_FLOW_TIMES) {
            if (check_depth(2)) {
                $quote = stack_pop();
                $count = stack_pop();
                while ($count > 0) {
                    interpret($quote, $more);
                    $count -= 1;
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_FLOW_CALL) {
            $offset += 1;
            interpret(fetch($slice, $offset), $more);
        } elseif ($opcode == $BC_FLOW_CALL_F) {
            if (check_depth(1)) {
                $a = stack_pop();
                interpret($a, $more);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_FLOW_DIP) {
            if (check_depth(2)) {
                $quote = stack_pop();
                $vtype = stack_type();
                $value = stack_pop();
                interpret($quote, $more);
                stack_push($value, $vtype);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_FLOW_SIP) {
            if (check_depth(2)) {
                $quote = stack_pop();
                stack_dup();
                $vtype = stack_type();
                $value = stack_pop();
                interpret($quote, $more);
                stack_push($value, $vtype);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_FLOW_BI) {
            if (check_depth(3)) {
                $a = stack_pop();
                $b = stack_pop();
                stack_dup();
                $x = stack_type();
                $y = stack_pop();
                interpret($b, $more);
                stack_push($y, $x);
                interpret($a, $more);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_FLOW_TRI) {
            if (check_depth(4)) {
                $a = stack_pop();
                $b = stack_pop();
                $c = stack_pop();
                stack_dup();
                $x = stack_type();
                $y = stack_pop();
                stack_dup();
                $m = stack_type();
                $q = stack_pop();
                interpret($c, $more);
                stack_push($q, $m);
                interpret($b, $more);
                stack_push($y, $x);
                interpret($a, $more);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_FLOW_RETURN) {
            $offset = $SLICE_LEN;
        } elseif ($opcode == $BC_MEM_COPY) {
            if (check_depth(2)) {
                $a = stack_pop();
                $b = stack_pop();
                copy_slice($b, $a);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_MEM_FETCH) {
            if (check_depth(2)) {
                $a = stack_pop();
                $b = stack_pop();
                stack_push(fetch($b, $a), $TYPE_NUMBER);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_MEM_STORE) {
            if (check_depth(3)) {
                $a = stack_pop();
                $b = stack_pop();
                $c = stack_pop();
                store($c, $b, $a);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_MEM_REQUEST) {
            stack_push(request_slice(), $TYPE_FUNCTION);
        } elseif ($opcode == $BC_MEM_RELEASE) {
            if (check_depth(1)) {
                release_slice(stack_pop());
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_MEM_COLLECT) {
            collect_unused_slices();
        } elseif ($opcode == $BC_STACK_DUP) {
            if (check_depth(1)) {
                stack_dup();
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_STACK_DROP) {
            if (check_depth(1)) {
                stack_drop();
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_STACK_SWAP) {
            if (check_depth(2)) {
                stack_swap();
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_STACK_OVER) {
            if (check_depth(2)) {
                stack_over();
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_STACK_TUCK) {
            if (check_depth(2)) {
                stack_tuck();
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_STACK_NIP) {
            if (check_depth(2)) {
                stack_swap();
                stack_drop();
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_STACK_DEPTH) {
            stack_push(count($stack), $TYPE_NUMBER);
        } elseif ($opcode == $BC_STACK_CLEAR) {
            stack_clear();
        } elseif ($opcode == $BC_QUOTE_NAME) {
            if (check_depth(2)) {
                $name = slice_to_string(stack_pop());
                $ptr = stack_pop();
                add_definition($name, $ptr);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_STRING_SEEK) {
            if (check_depth(2)) {
                $a = slice_to_string(stack_pop());
                $b = slice_to_string(stack_pop());
                if (strpos($b, $a) === FALSE) {
                    stack_push(-1, $TYPE_NUMBER);
                } else {
                    stack_push(strpos($b, $a), $TYPE_NUMBER);
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_STRING_SUBSTR) {
            if (check_depth(3)) {
                $a = intval(stack_pop());
                $b = intval(stack_pop());
                $c = slice_to_string(stack_pop());
                $c = substr($c, $b, $a);
                stack_push(string_to_slice($c), $TYPE_STRING);
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_STRING_NUMERIC) {
            if (check_depth(1)) {
                $a = slice_to_string(stack_pop());
                if (is_numeric($a)) {
                    stack_push(-1, $TYPE_FLAG);
                } else {
                    stack_push(0, $TYPE_FLAG);
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_TO_UPPER) {
            if (check_depth(1)) {
                $t = stack_type();
                if ($t == $TYPE_STRING) {
                    $ptr = stack_pop();
                    $a = strtoupper(slice_to_string($ptr));
                    stack_push(string_to_slice($a), $TYPE_STRING);
                } elseif ($t == $TYPE_CHARACTER) {
                    $a = stack_pop();
                    $b = " ";
                    $b[0] = chr($a);
                    $c = strtoupper($b);
                    $a = $c[0];
                    stack_push(ord($a), $TYPE_CHARACTER);
                } else {
                    $t = 0;
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_TO_LOWER) {
            if (check_depth(1)) {
                $t = stack_type();
                if ($t == $TYPE_STRING) {
                    $ptr = stack_pop();
                    $a = strtolower(slice_to_string($ptr));
                    stack_push(string_to_slice($a), $TYPE_STRING);
                } elseif ($t == $TYPE_CHARACTER) {
                    $a = stack_pop();
                    $b = " ";
                    $b[0] = chr($a);
                    $c = strtolower($b);
                    $a = $c[0];
                    stack_push(ord($a), $TYPE_CHARACTER);
                } else {
                    $t = 0;
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_LENGTH) {
            if (check_depth(1)) {
                if (stack_type() == $TYPE_STRING) {
                    $a = slice_to_string(stack_tos());
                    stack_push(strlen($a), $TYPE_NUMBER);
                } else {
                    stack_push(0, $TYPE_NUMBER);
                }
            } else {
                $offset = $SLICE_LEN;
            }
        } elseif ($opcode == $BC_REPORT_ERROR) {
            if (check_depth(1)) {
                if (stack_type() == $TYPE_STRING) {
                    $a = slice_to_string(stack_pop());
                    report_error($a);
                }
            }
            $offset = $SLICE_LEN;
        }
        if ($more != "") {
            $offset = $more($slice, $offset, $opcode);
        }
        $offset += 1;
    }
}
Example #2
0
add_definition("vt", "double, separate/cut/divide in two");
make_word("uta", "口", "口");
add_definition("n", "mouth");
add_definition("mod", "oral");
add_definition("noun", "mouth, the part of the human body that includes the lips and everything inside the mouth and throat; mouth, oral cavity, throat, pharynx, lips");
add_definition("noun", "maw, a similar part in an animal's body, used for eating, sucking or grooming; beak, bill, rostrum, jaw, proboscis");
make_word("utala", "戦", "战");
add_definition("n", "conflict, disharmony, competition, fight, war, battle, attack, blow, argument, physical or verbal violence");
add_definition("vt", "hit, strike, attack, compete against");
make_word("walo", "白", "白");
add_definition("mod", "white, light (colour)");
add_definition("n", "white thing or part, whiteness, lightness");
make_word("wan", "一", "一");
add_definition("mod", "one, a");
add_definition("n", "unit, element, particle, part, piece");
add_definition("vt", "unite, make one");
make_word("waso", "鳥", "鸟");
add_definition("n", "bird, winged animal");
make_word("wawa", "力", "力");
add_definition("n", "energy, strength, power");
add_definition("mod", "energetic, strong, fierce, intense, sure, confident");
add_definition("vt", "strengthen, energize, empower");
make_word("weka", "遥", "脱");
add_definition("mod", "away, absent, missing");
add_definition("n", "absence");
add_definition("vt", "throw away, remove, get rid of");
make_word("wile", "要", "要");
add_definition("vt", "to want, need, wish, have to, must, will, should");
add_definition("n", "desire, need, will");
add_definition("mod", "necessary");
exit("success");