guard hoisting
This commit is contained in:
@@ -62,7 +62,47 @@ When a slot appears with conflicting type inferences (e.g., used in both `add_in
|
||||
|
||||
**Nop prefix:** none (analysis only, does not modify instructions)
|
||||
|
||||
### 2. eliminate_type_checks (type-check + jump elimination)
|
||||
### 2. infer_slot_write_types (slot write-type invariance)
|
||||
|
||||
Scans all instructions to determine which non-parameter slots have a consistent write type. If every instruction that writes to a given slot produces the same type, that type is globally invariant and can safely persist across label join points.
|
||||
|
||||
This analysis is sound because:
|
||||
- `alloc_slot()` in mcode.cm is monotonically increasing — temp slots are never reused
|
||||
- All local variable declarations must be at function body level and initialized — slots are written before any backward jumps to loop headers
|
||||
- `move` is conservatively treated as T_UNKNOWN, avoiding unsound transitive assumptions
|
||||
|
||||
Write type mapping:
|
||||
|
||||
| Instruction class | Write type |
|
||||
|---|---|
|
||||
| `int` | T_INT |
|
||||
| `true`, `false` | T_BOOL |
|
||||
| `null` | T_NULL |
|
||||
| `access` | type of literal value |
|
||||
| `array` | T_ARRAY |
|
||||
| `record` | T_RECORD |
|
||||
| `function` | T_FUNCTION |
|
||||
| `length` | T_INT |
|
||||
| int arithmetic, `neg_int`, bitwise ops | T_INT |
|
||||
| float arithmetic, `neg_float` | T_FLOAT |
|
||||
| `concat` | T_TEXT |
|
||||
| bool ops, comparisons, `in` | T_BOOL |
|
||||
| generic arithmetic (`add`, `subtract`, etc.) | T_UNKNOWN |
|
||||
| `move`, `load_field`, `load_index`, `load_dynamic`, `pop`, `get` | T_UNKNOWN |
|
||||
| `invoke`, `tail_invoke` | T_UNKNOWN |
|
||||
|
||||
The result is a map of slot→type for slots where all writes agree on a single known type. Parameter slots (1..nr_args) and slot 0 are excluded.
|
||||
|
||||
Common patterns this enables:
|
||||
|
||||
- **Loop counters** (`var i = 0; ... i = i + 1`): written by `int` (T_INT) and `add_int` (T_INT) → invariant T_INT
|
||||
- **Length variables** (`var len = length(arr)`): written by `length` (T_INT) only → invariant T_INT
|
||||
- **Boolean flags** (`var found = false; ... found = true`): written by `false` and `true` → invariant T_BOOL
|
||||
- **Locally-created containers** (`var arr = []`): written by `array` only → invariant T_ARRAY
|
||||
|
||||
**Nop prefix:** none (analysis only, does not modify instructions)
|
||||
|
||||
### 3. eliminate_type_checks (type-check + jump elimination)
|
||||
|
||||
Forward pass that tracks the known type of each slot. When a type check (`is_int`, `is_text`, `is_num`, etc.) is followed by a conditional jump, and the slot's type is already known, the check and jump can be eliminated or converted to an unconditional jump.
|
||||
|
||||
@@ -74,11 +114,11 @@ Three cases:
|
||||
|
||||
This pass also reduces `load_dynamic`/`store_dynamic` to `load_field`/`store_field` or `load_index`/`store_index` when the key slot's type is known.
|
||||
|
||||
At label join points, all type information is reset except for parameter types seeded by the backward inference pass.
|
||||
At label join points, all type information is reset except for parameter types from backward inference and write-invariant types from slot write-type analysis.
|
||||
|
||||
**Nop prefix:** `_nop_tc_`
|
||||
|
||||
### 3. simplify_algebra (algebraic identity + comparison folding)
|
||||
### 4. simplify_algebra (algebraic identity + comparison folding)
|
||||
|
||||
Tracks known constant values alongside types. Rewrites identity operations:
|
||||
|
||||
@@ -111,7 +151,7 @@ Same-slot comparison folding:
|
||||
|
||||
**Nop prefix:** none (rewrites in place, does not create nops)
|
||||
|
||||
### 4. simplify_booleans (not + jump fusion)
|
||||
### 5. simplify_booleans (not + jump fusion)
|
||||
|
||||
Peephole pass that eliminates unnecessary `not` instructions:
|
||||
|
||||
@@ -125,13 +165,13 @@ This is particularly effective on `if (!cond)` patterns, which the compiler gene
|
||||
|
||||
**Nop prefix:** `_nop_bl_`
|
||||
|
||||
### 5. eliminate_moves (self-move elimination)
|
||||
### 6. eliminate_moves (self-move elimination)
|
||||
|
||||
Removes `move a, a` instructions where the source and destination are the same slot. These can arise from earlier passes rewriting binary operations into moves.
|
||||
|
||||
**Nop prefix:** `_nop_mv_`
|
||||
|
||||
### 6. eliminate_unreachable (dead code after return)
|
||||
### 7. eliminate_unreachable (dead code after return)
|
||||
|
||||
Nops instructions after `return` until the next real label. Only `return` is treated as a terminal instruction; `disrupt` is not, because the disruption handler code immediately follows `disrupt` and must remain reachable.
|
||||
|
||||
@@ -139,7 +179,7 @@ The mcode compiler emits a label at disruption handler entry points (see `emit_l
|
||||
|
||||
**Nop prefix:** `_nop_ur_`
|
||||
|
||||
### 7. eliminate_dead_jumps (jump-to-next-label elimination)
|
||||
### 8. eliminate_dead_jumps (jump-to-next-label elimination)
|
||||
|
||||
Removes `jump L` instructions where `L` is the immediately following label (skipping over any intervening nop strings). These are common after other passes eliminate conditional branches, leaving behind jumps that fall through naturally.
|
||||
|
||||
@@ -150,8 +190,9 @@ Removes `jump L` instructions where `L` is the immediately following label (skip
|
||||
All passes run in sequence in `optimize_function`:
|
||||
|
||||
```
|
||||
infer_param_types → returns param_types map
|
||||
eliminate_type_checks → uses param_types
|
||||
infer_param_types → returns param_types map
|
||||
infer_slot_write_types → returns write_types map
|
||||
eliminate_type_checks → uses param_types + write_types
|
||||
simplify_algebra
|
||||
simplify_booleans
|
||||
eliminate_moves
|
||||
@@ -237,11 +278,12 @@ The `pure_intrinsics` set currently contains only `is_*` sensory functions (`is_
|
||||
The streamline optimizer uses a numeric type lattice (`T_INT`, `T_FLOAT`, `T_TEXT`, etc.) for fine-grained per-instruction tracking:
|
||||
|
||||
- **Backward inference** (pass 1): Scans typed operators to infer parameter types. Since parameters are `def` (immutable), inferred types persist across label boundaries.
|
||||
- **Forward tracking** (pass 2): `track_types` follows instruction execution order, tracking the type of each slot. Typed arithmetic results set their destination type. Type checks on unknown slots narrow the type on fallthrough.
|
||||
- **Type check elimination** (pass 2): When a slot's type is already known, `is_<type>` + conditional jump pairs are eliminated or converted to unconditional jumps.
|
||||
- **Dynamic access narrowing** (pass 2): `load_dynamic`/`store_dynamic` are narrowed to `load_field`/`store_field` or `load_index`/`store_index` when the key type is known.
|
||||
- **Write-type invariance** (pass 2): Scans all instructions to find local slots where every write produces the same type. These invariant types persist across label boundaries alongside parameter types.
|
||||
- **Forward tracking** (pass 3): `track_types` follows instruction execution order, tracking the type of each slot. Typed arithmetic results set their destination type. Type checks on unknown slots narrow the type on fallthrough.
|
||||
- **Type check elimination** (pass 3): When a slot's type is already known, `is_<type>` + conditional jump pairs are eliminated or converted to unconditional jumps.
|
||||
- **Dynamic access narrowing** (pass 3): `load_dynamic`/`store_dynamic` are narrowed to `load_field`/`store_field` or `load_index`/`store_index` when the key type is known.
|
||||
|
||||
Type information resets at label join points (since control flow merges could bring different types), except for parameter types from backward inference.
|
||||
Type information resets at label join points (since control flow merges could bring different types), except for parameter types from backward inference and write-invariant types from slot write-type analysis.
|
||||
|
||||
## Future Work
|
||||
|
||||
@@ -267,6 +309,8 @@ When a type check on a parameter passes (falls through), the parameter's type co
|
||||
|
||||
A safe version would require proving that a parameter is monomorphic (called with only one type across all call sites), which requires interprocedural analysis.
|
||||
|
||||
**Note:** For local variables (non-parameters), the write-type invariance analysis (pass 2) achieves a similar effect safely — if every write to a slot produces the same type, that type persists across labels without needing to hoist any guard.
|
||||
|
||||
### Tail Call Optimization
|
||||
|
||||
`tail_invoke` instructions are currently marked but execute identically to `invoke`. Actual TCO would reuse the current call frame instead of creating a new one. This requires:
|
||||
|
||||
8014
fold.cm.mcode
8014
fold.cm.mcode
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
5708
mcode.cm.mcode
5708
mcode.cm.mcode
File diff suppressed because it is too large
Load Diff
9128
parse.cm.mcode
9128
parse.cm.mcode
File diff suppressed because it is too large
Load Diff
2088
qbe_emit.cm.mcode
2088
qbe_emit.cm.mcode
File diff suppressed because it is too large
Load Diff
149
streamline.cm
149
streamline.cm
@@ -219,6 +219,16 @@ var streamline = function(ir, log) {
|
||||
return null
|
||||
}
|
||||
|
||||
var seed_writes = function(slot_types, write_types) {
|
||||
var keys = array(write_types)
|
||||
var k = 0
|
||||
while (k < length(keys)) {
|
||||
slot_types[keys[k]] = write_types[keys[k]]
|
||||
k = k + 1
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Pass: infer_param_types — backward type inference
|
||||
// Scans typed operators to infer immutable parameter types.
|
||||
@@ -308,15 +318,137 @@ var streamline = function(ir, log) {
|
||||
return param_types
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Pass: infer_slot_write_types — slot write-type invariance
|
||||
// Scans all instructions to find non-parameter slots where
|
||||
// every write produces the same type. These types persist
|
||||
// across label join points.
|
||||
// =========================================================
|
||||
var infer_slot_write_types = function(func) {
|
||||
var instructions = func.instructions
|
||||
var nr_args = func.nr_args != null ? func.nr_args : 0
|
||||
var num_instr = 0
|
||||
var write_types = null
|
||||
var result = null
|
||||
var keys = null
|
||||
var i = 0
|
||||
var k = 0
|
||||
var instr = null
|
||||
var op = null
|
||||
var slot = 0
|
||||
var typ = null
|
||||
var wt = null
|
||||
|
||||
if (instructions == null) {
|
||||
return {}
|
||||
}
|
||||
|
||||
num_instr = length(instructions)
|
||||
write_types = {}
|
||||
i = 0
|
||||
while (i < num_instr) {
|
||||
instr = instructions[i]
|
||||
if (!is_array(instr)) {
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
|
||||
op = instr[0]
|
||||
slot = -1
|
||||
typ = null
|
||||
|
||||
if (op == "int") {
|
||||
slot = instr[1]
|
||||
typ = T_INT
|
||||
} else if (op == "true" || op == "false") {
|
||||
slot = instr[1]
|
||||
typ = T_BOOL
|
||||
} else if (op == "null") {
|
||||
slot = instr[1]
|
||||
typ = T_NULL
|
||||
} else if (op == "access") {
|
||||
slot = instr[1]
|
||||
typ = access_value_type(instr[2])
|
||||
} else if (op == "array") {
|
||||
slot = instr[1]
|
||||
typ = T_ARRAY
|
||||
} else if (op == "record") {
|
||||
slot = instr[1]
|
||||
typ = T_RECORD
|
||||
} else if (op == "function") {
|
||||
slot = instr[1]
|
||||
typ = T_FUNCTION
|
||||
} else if (op == "length") {
|
||||
slot = instr[1]
|
||||
typ = T_INT
|
||||
} else if (int_result_ops[op] == true) {
|
||||
slot = instr[1]
|
||||
typ = T_INT
|
||||
} else if (float_result_ops[op] == true) {
|
||||
slot = instr[1]
|
||||
typ = T_FLOAT
|
||||
} else if (op == "neg_int" || op == "bitnot" || op == "bitand" ||
|
||||
op == "bitor" || op == "bitxor" || op == "shl" ||
|
||||
op == "shr" || op == "ushr") {
|
||||
slot = instr[1]
|
||||
typ = T_INT
|
||||
} else if (op == "neg_float") {
|
||||
slot = instr[1]
|
||||
typ = T_FLOAT
|
||||
} else if (op == "concat") {
|
||||
slot = instr[1]
|
||||
typ = T_TEXT
|
||||
} else if (bool_result_ops[op] == true) {
|
||||
slot = instr[1]
|
||||
typ = T_BOOL
|
||||
} else if (op == "eq" || op == "ne" || op == "lt" ||
|
||||
op == "le" || op == "gt" || op == "ge" || op == "in") {
|
||||
slot = instr[1]
|
||||
typ = T_BOOL
|
||||
} else if (op == "add" || op == "subtract" || op == "multiply" ||
|
||||
op == "divide" || op == "modulo" || op == "pow") {
|
||||
slot = instr[1]
|
||||
typ = T_UNKNOWN
|
||||
} else if (op == "move" || op == "load_field" || op == "load_index" ||
|
||||
op == "load_dynamic" || op == "pop" || op == "get") {
|
||||
slot = instr[1]
|
||||
typ = T_UNKNOWN
|
||||
} else if (op == "invoke" || op == "tail_invoke") {
|
||||
slot = instr[2]
|
||||
typ = T_UNKNOWN
|
||||
}
|
||||
|
||||
if (slot > 0 && slot > nr_args) {
|
||||
merge_backward(write_types, slot, typ != null ? typ : T_UNKNOWN)
|
||||
}
|
||||
|
||||
i = i + 1
|
||||
}
|
||||
|
||||
// Filter to only slots with known (non-unknown) types
|
||||
result = {}
|
||||
keys = array(write_types)
|
||||
k = 0
|
||||
while (k < length(keys)) {
|
||||
wt = write_types[keys[k]]
|
||||
if (wt != null && wt != T_UNKNOWN) {
|
||||
result[keys[k]] = wt
|
||||
}
|
||||
k = k + 1
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// =========================================================
|
||||
// Pass: eliminate_type_checks — language-level type narrowing
|
||||
// Eliminates is_<type>/jump pairs when type is known.
|
||||
// Reduces load_dynamic/store_dynamic to field/index forms.
|
||||
// =========================================================
|
||||
var eliminate_type_checks = function(func, param_types, log) {
|
||||
var eliminate_type_checks = function(func, param_types, write_types, log) {
|
||||
var instructions = func.instructions
|
||||
var nr_args = func.nr_args != null ? func.nr_args : 0
|
||||
var has_params = false
|
||||
var has_writes = false
|
||||
var num_instr = 0
|
||||
var slot_types = null
|
||||
var nc = 0
|
||||
@@ -351,11 +483,15 @@ var streamline = function(ir, log) {
|
||||
}
|
||||
j = j + 1
|
||||
}
|
||||
has_writes = length(array(write_types)) > 0
|
||||
|
||||
slot_types = {}
|
||||
if (has_params) {
|
||||
seed_params(slot_types, param_types, nr_args)
|
||||
}
|
||||
if (has_writes) {
|
||||
seed_writes(slot_types, write_types)
|
||||
}
|
||||
|
||||
i = 0
|
||||
while (i < num_instr) {
|
||||
@@ -366,6 +502,9 @@ var streamline = function(ir, log) {
|
||||
if (has_params) {
|
||||
seed_params(slot_types, param_types, nr_args)
|
||||
}
|
||||
if (has_writes) {
|
||||
seed_writes(slot_types, write_types)
|
||||
}
|
||||
i = i + 1
|
||||
continue
|
||||
}
|
||||
@@ -1130,6 +1269,7 @@ var streamline = function(ir, log) {
|
||||
// =========================================================
|
||||
var optimize_function = function(func, log) {
|
||||
var param_types = null
|
||||
var write_types = null
|
||||
var slot_types = null
|
||||
if (func.instructions == null || length(func.instructions) == 0) {
|
||||
return null
|
||||
@@ -1139,8 +1279,13 @@ var streamline = function(ir, log) {
|
||||
return param_types
|
||||
})
|
||||
if (verify_fn) verify_fn(func, "after infer_param_types")
|
||||
run_pass(func, "infer_slot_write_types", function() {
|
||||
write_types = infer_slot_write_types(func)
|
||||
return write_types
|
||||
})
|
||||
if (verify_fn) verify_fn(func, "after infer_slot_write_types")
|
||||
run_pass(func, "eliminate_type_checks", function() {
|
||||
slot_types = eliminate_type_checks(func, param_types, log)
|
||||
slot_types = eliminate_type_checks(func, param_types, write_types, log)
|
||||
return slot_types
|
||||
})
|
||||
if (verify_fn) verify_fn(func, "after eliminate_type_checks")
|
||||
|
||||
34571
streamline.cm.mcode
34571
streamline.cm.mcode
File diff suppressed because it is too large
Load Diff
@@ -136,8 +136,8 @@
|
||||
"add_ni_16",
|
||||
["is_text", 8, 5, 94, 17],
|
||||
["jump_false", 8, "add_nt_17", 94, 17],
|
||||
["is_text", 9, 6, 94, 17],
|
||||
["jump_false", 9, "add_nt_17", 94, 17],
|
||||
"_nop_tc_1",
|
||||
["jump", "add_nt_17", 94, 17],
|
||||
["concat", 7, 5, 6, 94, 17],
|
||||
["jump", "add_done_18", 94, 17],
|
||||
"add_nt_17",
|
||||
@@ -199,8 +199,8 @@
|
||||
"add_ni_28",
|
||||
["is_text", 17, 14, 96, 19],
|
||||
["jump_false", 17, "add_nt_29", 96, 19],
|
||||
["is_text", 18, 15, 96, 19],
|
||||
["jump_false", 18, "add_nt_29", 96, 19],
|
||||
"_nop_tc_2",
|
||||
["jump", "add_nt_29", 96, 19],
|
||||
["concat", 16, 14, 15, 96, 19],
|
||||
["jump", "add_done_30", 96, 19],
|
||||
"add_nt_29",
|
||||
@@ -225,8 +225,8 @@
|
||||
"add_ni_32",
|
||||
["is_text", 23, 20, 99, 19],
|
||||
["jump_false", 23, "add_nt_33", 99, 19],
|
||||
["is_text", 24, 21, 99, 19],
|
||||
["jump_false", 24, "add_nt_33", 99, 19],
|
||||
"_nop_tc_3",
|
||||
["jump", "add_nt_33", 99, 19],
|
||||
["concat", 22, 20, 21, 99, 19],
|
||||
["jump", "add_done_34", 99, 19],
|
||||
"add_nt_33",
|
||||
@@ -639,20 +639,20 @@
|
||||
["disrupt", 114, 44],
|
||||
"num_done_100",
|
||||
["access", 28, 10, 114, 51],
|
||||
["is_int", 30, 25, 114, 51],
|
||||
["jump_false", 30, "add_ni_102", 114, 51],
|
||||
"_nop_tc_1",
|
||||
["jump", "add_ni_102", 114, 51],
|
||||
["add_int", 29, 25, 28, 114, 51],
|
||||
["jump", "add_done_104", 114, 51],
|
||||
"add_ni_102",
|
||||
["is_text", 30, 25, 114, 51],
|
||||
["jump_false", 30, "add_nt_103", 114, 51],
|
||||
["is_text", 31, 28, 114, 51],
|
||||
["jump_false", 31, "add_nt_103", 114, 51],
|
||||
"_nop_tc_2",
|
||||
["jump", "add_nt_103", 114, 51],
|
||||
"_nop_tc_3",
|
||||
["jump", "add_nt_103", 114, 51],
|
||||
["concat", 29, 25, 28, 114, 51],
|
||||
["jump", "add_done_104", 114, 51],
|
||||
"add_nt_103",
|
||||
["is_num", 30, 25, 114, 51],
|
||||
["jump_false", 30, "add_err_105", 114, 51],
|
||||
"_nop_tc_4",
|
||||
"_nop_tc_5",
|
||||
["add_float", 29, 25, 28, 114, 51],
|
||||
["jump", "add_done_104", 114, 51],
|
||||
"add_err_105",
|
||||
@@ -733,20 +733,20 @@
|
||||
["disrupt", 115, 44],
|
||||
"num_done_118",
|
||||
["access", 45, 10, 115, 51],
|
||||
["is_int", 47, 42, 115, 51],
|
||||
["jump_false", 47, "add_ni_120", 115, 51],
|
||||
"_nop_tc_6",
|
||||
["jump", "add_ni_120", 115, 51],
|
||||
["add_int", 46, 42, 45, 115, 51],
|
||||
["jump", "add_done_122", 115, 51],
|
||||
"add_ni_120",
|
||||
["is_text", 47, 42, 115, 51],
|
||||
["jump_false", 47, "add_nt_121", 115, 51],
|
||||
["is_text", 48, 45, 115, 51],
|
||||
["jump_false", 48, "add_nt_121", 115, 51],
|
||||
"_nop_tc_7",
|
||||
["jump", "add_nt_121", 115, 51],
|
||||
"_nop_tc_8",
|
||||
["jump", "add_nt_121", 115, 51],
|
||||
["concat", 46, 42, 45, 115, 51],
|
||||
["jump", "add_done_122", 115, 51],
|
||||
"add_nt_121",
|
||||
["is_num", 47, 42, 115, 51],
|
||||
["jump_false", 47, "add_err_123", 115, 51],
|
||||
"_nop_tc_9",
|
||||
"_nop_tc_10",
|
||||
["add_float", 46, 42, 45, 115, 51],
|
||||
["jump", "add_done_122", 115, 51],
|
||||
"add_err_123",
|
||||
@@ -783,15 +783,15 @@
|
||||
"rel_ni_128",
|
||||
["is_num", 5, 2, 122, 17],
|
||||
["jump_false", 5, "rel_nn_129", 122, 17],
|
||||
["is_num", 6, 3, 122, 17],
|
||||
["jump_false", 6, "rel_nn_129", 122, 17],
|
||||
"_nop_tc_2",
|
||||
"_nop_tc_3",
|
||||
["lt_float", 4, 2, 3, 122, 17],
|
||||
["jump", "rel_done_130", 122, 17],
|
||||
"rel_nn_129",
|
||||
["is_text", 5, 2, 122, 17],
|
||||
["jump_false", 5, "rel_err_131", 122, 17],
|
||||
["is_text", 6, 3, 122, 17],
|
||||
["jump_false", 6, "rel_err_131", 122, 17],
|
||||
"_nop_tc_4",
|
||||
["jump", "rel_err_131", 122, 17],
|
||||
["lt_text", 4, 2, 3, 122, 17],
|
||||
["jump", "rel_done_130", 122, 17],
|
||||
"rel_err_131",
|
||||
@@ -866,22 +866,22 @@
|
||||
["setarg", 32, 0, 33, 123, 30],
|
||||
["setarg", 32, 1, 26, 123, 30],
|
||||
["invoke", 32, 30, 123, 30],
|
||||
["is_int", 35, 23, 123, 30],
|
||||
["jump_false", 35, "add_ni_139", 123, 30],
|
||||
"_nop_tc_5",
|
||||
["jump", "add_ni_139", 123, 30],
|
||||
["is_int", 36, 30, 123, 30],
|
||||
["jump_false", 36, "add_ni_139", 123, 30],
|
||||
["add_int", 34, 23, 30, 123, 30],
|
||||
["jump", "add_done_141", 123, 30],
|
||||
"add_ni_139",
|
||||
["is_text", 35, 23, 123, 30],
|
||||
["jump_false", 35, "add_nt_140", 123, 30],
|
||||
"_nop_tc_6",
|
||||
["jump", "add_nt_140", 123, 30],
|
||||
["is_text", 36, 30, 123, 30],
|
||||
["jump_false", 36, "add_nt_140", 123, 30],
|
||||
["concat", 34, 23, 30, 123, 30],
|
||||
["jump", "add_done_141", 123, 30],
|
||||
"add_nt_140",
|
||||
["is_num", 35, 23, 123, 30],
|
||||
["jump_false", 35, "add_err_142", 123, 30],
|
||||
"_nop_tc_7",
|
||||
"_nop_tc_8",
|
||||
["is_num", 36, 30, 123, 30],
|
||||
["jump_false", 36, "add_err_142", 123, 30],
|
||||
["add_float", 34, 23, 30, 123, 30],
|
||||
@@ -898,8 +898,8 @@
|
||||
"add_ni_143",
|
||||
["is_text", 39, 2, 124, 17],
|
||||
["jump_false", 39, "add_nt_144", 124, 17],
|
||||
["is_text", 40, 37, 124, 17],
|
||||
["jump_false", 40, "add_nt_144", 124, 17],
|
||||
"_nop_tc_9",
|
||||
["jump", "add_nt_144", 124, 17],
|
||||
["concat", 38, 2, 37, 124, 17],
|
||||
["jump", "add_done_145", 124, 17],
|
||||
"add_nt_144",
|
||||
@@ -2451,8 +2451,8 @@
|
||||
"add_ni_372",
|
||||
["is_text", 45, 42, 201, 38],
|
||||
["jump_false", 45, "add_nt_373", 201, 38],
|
||||
["is_text", 46, 43, 201, 38],
|
||||
["jump_false", 46, "add_nt_373", 201, 38],
|
||||
"_nop_tc_1",
|
||||
["jump", "add_nt_373", 201, 38],
|
||||
["concat", 44, 42, 43, 201, 38],
|
||||
["jump", "add_done_374", 201, 38],
|
||||
"add_nt_373",
|
||||
@@ -2556,8 +2556,8 @@
|
||||
"add_ni_388",
|
||||
["is_text", 67, 64, 203, 42],
|
||||
["jump_false", 67, "add_nt_389", 203, 42],
|
||||
["is_text", 68, 65, 203, 42],
|
||||
["jump_false", 68, "add_nt_389", 203, 42],
|
||||
"_nop_tc_2",
|
||||
["jump", "add_nt_389", 203, 42],
|
||||
["concat", 66, 64, 65, 203, 42],
|
||||
["jump", "add_done_390", 203, 42],
|
||||
"add_nt_389",
|
||||
@@ -2663,8 +2663,8 @@
|
||||
"add_ni_404",
|
||||
["is_text", 95, 92, 206, 45],
|
||||
["jump_false", 95, "add_nt_405", 206, 45],
|
||||
["is_text", 96, 93, 206, 45],
|
||||
["jump_false", 96, "add_nt_405", 206, 45],
|
||||
"_nop_tc_3",
|
||||
["jump", "add_nt_405", 206, 45],
|
||||
["concat", 94, 92, 93, 206, 45],
|
||||
["jump", "add_done_406", 206, 45],
|
||||
"add_nt_405",
|
||||
@@ -2853,22 +2853,22 @@
|
||||
["access", 138, 0, 211, 37],
|
||||
["is_int", 140, 6, 211, 37],
|
||||
["jump_false", 140, "rel_ni_433", 211, 37],
|
||||
"_nop_tc_1",
|
||||
"_nop_tc_4",
|
||||
["jump", "rel_ni_433", 211, 37],
|
||||
["gt_int", 139, 6, 138, 211, 37],
|
||||
["jump", "rel_done_435", 211, 37],
|
||||
"rel_ni_433",
|
||||
["is_num", 140, 6, 211, 37],
|
||||
["jump_false", 140, "rel_nn_434", 211, 37],
|
||||
["is_num", 141, 138, 211, 37],
|
||||
["jump_false", 141, "rel_nn_434", 211, 37],
|
||||
"_nop_tc_5",
|
||||
"_nop_tc_6",
|
||||
["gt_float", 139, 6, 138, 211, 37],
|
||||
["jump", "rel_done_435", 211, 37],
|
||||
"rel_nn_434",
|
||||
["is_text", 140, 6, 211, 37],
|
||||
["jump_false", 140, "rel_err_436", 211, 37],
|
||||
["is_text", 141, 138, 211, 37],
|
||||
["jump_false", 141, "rel_err_436", 211, 37],
|
||||
"_nop_tc_7",
|
||||
["jump", "rel_err_436", 211, 37],
|
||||
["gt_text", 139, 6, 138, 211, 37],
|
||||
["jump", "rel_done_435", 211, 37],
|
||||
"rel_err_436",
|
||||
@@ -2932,8 +2932,8 @@
|
||||
"add_ni_445",
|
||||
["is_text", 152, 6, 213, 50],
|
||||
["jump_false", 152, "add_nt_446", 213, 50],
|
||||
["is_text", 153, 150, 213, 50],
|
||||
["jump_false", 153, "add_nt_446", 213, 50],
|
||||
"_nop_tc_8",
|
||||
["jump", "add_nt_446", 213, 50],
|
||||
["concat", 151, 6, 150, 213, 50],
|
||||
["jump", "add_done_447", 213, 50],
|
||||
"add_nt_446",
|
||||
@@ -3285,8 +3285,8 @@
|
||||
"add_ni_506",
|
||||
["is_text", 213, 210, 221, 46],
|
||||
["jump_false", 213, "add_nt_507", 221, 46],
|
||||
["is_text", 214, 211, 221, 46],
|
||||
["jump_false", 214, "add_nt_507", 221, 46],
|
||||
"_nop_tc_9",
|
||||
["jump", "add_nt_507", 221, 46],
|
||||
["concat", 212, 210, 211, 221, 46],
|
||||
["jump", "add_done_508", 221, 46],
|
||||
"add_nt_507",
|
||||
@@ -5158,36 +5158,36 @@
|
||||
"ne_ni_762",
|
||||
["is_int", 36, 5, 287, 15],
|
||||
["jump_false", 36, "ne_nn_763", 287, 15],
|
||||
["is_int", 37, 34, 287, 15],
|
||||
["jump_false", 37, "ne_nn_763", 287, 15],
|
||||
"_nop_tc_1",
|
||||
["jump", "ne_nn_763", 287, 15],
|
||||
["ne_int", 35, 5, 34, 287, 15],
|
||||
["jump", "ne_done_760", 287, 15],
|
||||
"ne_nn_763",
|
||||
["is_num", 36, 5, 287, 15],
|
||||
["jump_false", 36, "ne_nt_764", 287, 15],
|
||||
["is_num", 37, 34, 287, 15],
|
||||
["jump_false", 37, "ne_nt_764", 287, 15],
|
||||
"_nop_tc_2",
|
||||
["jump", "ne_nt_764", 287, 15],
|
||||
["ne_float", 35, 5, 34, 287, 15],
|
||||
["jump", "ne_done_760", 287, 15],
|
||||
"ne_nt_764",
|
||||
["is_text", 36, 5, 287, 15],
|
||||
["jump_false", 36, "ne_nnl_765", 287, 15],
|
||||
["is_text", 37, 34, 287, 15],
|
||||
["jump_false", 37, "ne_nnl_765", 287, 15],
|
||||
"_nop_tc_3",
|
||||
["jump", "ne_nnl_765", 287, 15],
|
||||
["ne_text", 35, 5, 34, 287, 15],
|
||||
["jump", "ne_done_760", 287, 15],
|
||||
"ne_nnl_765",
|
||||
["is_null", 36, 5, 287, 15],
|
||||
["jump_false", 36, "ne_nb_766", 287, 15],
|
||||
["is_null", 37, 34, 287, 15],
|
||||
["jump_false", 37, "ne_nb_766", 287, 15],
|
||||
"_nop_tc_4",
|
||||
"_nop_tc_5",
|
||||
["false", 35, 287, 15],
|
||||
["jump", "ne_done_760", 287, 15],
|
||||
"ne_nb_766",
|
||||
["is_bool", 36, 5, 287, 15],
|
||||
["jump_false", 36, "ne_mis_767", 287, 15],
|
||||
["is_bool", 37, 34, 287, 15],
|
||||
["jump_false", 37, "ne_mis_767", 287, 15],
|
||||
"_nop_tc_6",
|
||||
["jump", "ne_mis_767", 287, 15],
|
||||
["ne_bool", 35, 5, 34, 287, 15],
|
||||
["jump", "ne_done_760", 287, 15],
|
||||
"ne_mis_767",
|
||||
@@ -5685,8 +5685,8 @@
|
||||
"add_ni_833",
|
||||
["is_text", 19, 6, 334, 40],
|
||||
["jump_false", 19, "add_nt_834", 334, 40],
|
||||
["is_text", 20, 17, 334, 40],
|
||||
["jump_false", 20, "add_nt_834", 334, 40],
|
||||
"_nop_tc_1",
|
||||
["jump", "add_nt_834", 334, 40],
|
||||
["concat", 18, 6, 17, 334, 40],
|
||||
["jump", "add_done_835", 334, 40],
|
||||
"add_nt_834",
|
||||
@@ -5774,8 +5774,8 @@
|
||||
"add_ni_845",
|
||||
["is_text", 18, 5, 347, 40],
|
||||
["jump_false", 18, "add_nt_846", 347, 40],
|
||||
["is_text", 19, 16, 347, 40],
|
||||
["jump_false", 19, "add_nt_846", 347, 40],
|
||||
"_nop_tc_1",
|
||||
["jump", "add_nt_846", 347, 40],
|
||||
["concat", 17, 5, 16, 347, 40],
|
||||
["jump", "add_done_847", 347, 40],
|
||||
"add_nt_846",
|
||||
@@ -5862,29 +5862,29 @@
|
||||
"eq_ni_854",
|
||||
["is_num", 12, 3, 362, 14],
|
||||
["jump_false", 12, "eq_nn_855", 362, 14],
|
||||
["is_num", 13, 10, 362, 14],
|
||||
["jump_false", 13, "eq_nn_855", 362, 14],
|
||||
"_nop_tc_2",
|
||||
"_nop_tc_3",
|
||||
["eq_float", 11, 3, 10, 362, 14],
|
||||
["jump", "eq_done_853", 362, 14],
|
||||
"eq_nn_855",
|
||||
["is_text", 12, 3, 362, 14],
|
||||
["jump_false", 12, "eq_nt_856", 362, 14],
|
||||
["is_text", 13, 10, 362, 14],
|
||||
["jump_false", 13, "eq_nt_856", 362, 14],
|
||||
"_nop_tc_4",
|
||||
["jump", "eq_nt_856", 362, 14],
|
||||
["eq_text", 11, 3, 10, 362, 14],
|
||||
["jump", "eq_done_853", 362, 14],
|
||||
"eq_nt_856",
|
||||
["is_null", 12, 3, 362, 14],
|
||||
["jump_false", 12, "eq_nnl_857", 362, 14],
|
||||
["is_null", 13, 10, 362, 14],
|
||||
["jump_false", 13, "eq_nnl_857", 362, 14],
|
||||
"_nop_tc_5",
|
||||
["jump", "eq_nnl_857", 362, 14],
|
||||
["true", 11, 362, 14],
|
||||
["jump", "eq_done_853", 362, 14],
|
||||
"eq_nnl_857",
|
||||
["is_bool", 12, 3, 362, 14],
|
||||
["jump_false", 12, "eq_nb_858", 362, 14],
|
||||
["is_bool", 13, 10, 362, 14],
|
||||
["jump_false", 13, "eq_nb_858", 362, 14],
|
||||
"_nop_tc_6",
|
||||
["jump", "eq_nb_858", 362, 14],
|
||||
["eq_bool", 11, 3, 10, 362, 14],
|
||||
["jump", "eq_done_853", 362, 14],
|
||||
"eq_nb_858",
|
||||
@@ -11012,22 +11012,22 @@
|
||||
["function", 132, 19, 356, 22],
|
||||
["move", 45, 132, 356, 22],
|
||||
"while_start_1521",
|
||||
["is_int", 134, 6, 504, 16],
|
||||
["jump_false", 134, "rel_ni_1523", 504, 16],
|
||||
"_nop_tc_1",
|
||||
["jump", "rel_ni_1523", 504, 16],
|
||||
["is_int", 135, 30, 504, 16],
|
||||
["jump_false", 135, "rel_ni_1523", 504, 16],
|
||||
["lt_int", 133, 6, 30, 504, 16],
|
||||
["jump", "rel_done_1525", 504, 16],
|
||||
"rel_ni_1523",
|
||||
["is_num", 134, 6, 504, 16],
|
||||
["jump_false", 134, "rel_nn_1524", 504, 16],
|
||||
"_nop_tc_2",
|
||||
"_nop_tc_3",
|
||||
["is_num", 135, 30, 504, 16],
|
||||
["jump_false", 135, "rel_nn_1524", 504, 16],
|
||||
["lt_float", 133, 6, 30, 504, 16],
|
||||
["jump", "rel_done_1525", 504, 16],
|
||||
"rel_nn_1524",
|
||||
["is_text", 134, 6, 504, 16],
|
||||
["jump_false", 134, "rel_err_1526", 504, 16],
|
||||
"_nop_tc_4",
|
||||
["jump", "rel_err_1526", 504, 16],
|
||||
["is_text", 135, 30, 504, 16],
|
||||
["jump_false", 135, "rel_err_1526", 504, 16],
|
||||
["lt_text", 133, 6, 30, 504, 16],
|
||||
|
||||
Reference in New Issue
Block a user