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; } }
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");