Files
@ 7cf6df93d16d
Branch filter:
Location: CSY/reowolf/src/protocol/parser/pass_stack_size.rs
7cf6df93d16d
4.4 KiB
application/rls-services+xml
Move builtin definitions to std lib
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | use crate::collections::*;
use crate::protocol::*;
use super::visitor::*;
// Will get a rename. Will probably become bytecode emitter or something. For
// now it just scans the scopes and assigns a unique number for each variable
// such that, at any point in the program's execution, all accessible in-scope
// variables will have a unique position "on the stack".
pub(crate) struct PassStackSize {
definition_buffer: ScopedBuffer<DefinitionId>,
variable_buffer: ScopedBuffer<VariableId>,
scope_buffer: ScopedBuffer<ScopeId>,
}
impl PassStackSize {
pub(crate) fn new() -> Self {
return Self{
definition_buffer: ScopedBuffer::with_capacity(BUFFER_INIT_CAP_LARGE),
variable_buffer: ScopedBuffer::with_capacity(BUFFER_INIT_CAP_SMALL),
scope_buffer: ScopedBuffer::with_capacity(BUFFER_INIT_CAP_SMALL),
}
}
}
impl Visitor for PassStackSize {
// Top level visitors
fn visit_module(&mut self, ctx: &mut Ctx) -> VisitorResult {
let module = ctx.module();
debug_assert_eq!(module.phase, ModuleCompilationPhase::Rewritten);
let root_id = module.root_id;
let root = &ctx.heap[root_id];
let definition_section = self.definition_buffer.start_section_initialized(&root.definitions);
for definition_index in 0..definition_section.len() {
let definition_id = definition_section[definition_index];
self.visit_definition(ctx, definition_id)?
}
definition_section.forget();
// ctx.module_mut().phase = ModuleCompilationPhase::StackSizeStuffAndStuff;
return Ok(())
}
fn visit_procedure_definition(&mut self, ctx: &mut Ctx, id: ProcedureDefinitionId) -> VisitorResult {
let definition = &ctx.heap[id];
let scope_id = definition.scope;
self.visit_scope_and_assign_local_ids(ctx, scope_id, 0);
return Ok(());
}
}
impl PassStackSize {
fn visit_scope_and_assign_local_ids(&mut self, ctx: &mut Ctx, scope_id: ScopeId, mut variable_counter: i32) {
let scope = &mut ctx.heap[scope_id];
scope.first_unique_id_in_scope = variable_counter;
let variable_section = self.variable_buffer.start_section_initialized(&scope.variables);
let child_scope_section = self.scope_buffer.start_section_initialized(&scope.nested);
let mut variable_index = 0;
let mut child_scope_index = 0;
loop {
// Determine relative positions of variable and scope to determine
// which one occurs first within the current scope.
let variable_relative_pos;
if variable_index < variable_section.len() {
let variable_id = variable_section[variable_index];
let variable = &ctx.heap[variable_id];
variable_relative_pos = variable.relative_pos_in_parent;
} else {
variable_relative_pos = i32::MAX;
}
let child_scope_relative_pos;
if child_scope_index < child_scope_section.len() {
let child_scope_id = child_scope_section[child_scope_index];
let child_scope = &ctx.heap[child_scope_id];
child_scope_relative_pos = child_scope.relative_pos_in_parent;
} else {
child_scope_relative_pos = i32::MAX;
}
if variable_relative_pos == i32::MAX && child_scope_relative_pos == i32::MAX {
// Done, no more elements in the scope to consider
break;
}
// Label the variable/scope, whichever comes first.
if variable_relative_pos <= child_scope_relative_pos {
debug_assert_ne!(variable_relative_pos, child_scope_relative_pos, "checking if this ever happens");
let variable = &mut ctx.heap[variable_section[variable_index]];
variable.unique_id_in_scope = variable_counter;
variable_counter += 1;
variable_index += 1;
} else {
let child_scope_id = child_scope_section[child_scope_index];
self.visit_scope_and_assign_local_ids(ctx, child_scope_id, variable_counter);
child_scope_index += 1;
}
}
variable_section.forget();
child_scope_section.forget();
let scope = &mut ctx.heap[scope_id];
scope.next_unique_id_in_scope = variable_counter;
}
}
|