[fine] Improvements to classes
- Classes are defined lazily - Member access is via environment - Member access is just a binary expression with a weird environment - Slot loads look like variable loads now - Associativity in the parser (ugh)
This commit is contained in:
parent
0d48bfb113
commit
2839b43f6d
5 changed files with 286 additions and 123 deletions
|
|
@ -487,6 +487,9 @@ fn compile_binary_expression(c: &mut Compiler, t: TreeRef, tr: &Tree) -> CR {
|
|||
compiler_assert!(c, t, index < c.module.globals);
|
||||
Instruction::StoreModule(index)
|
||||
}
|
||||
Location::Slot => {
|
||||
ice!(c, t, "cannot have an identifier lvalue bind to a slot");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -496,6 +499,9 @@ fn compile_binary_expression(c: &mut Compiler, t: TreeRef, tr: &Tree) -> CR {
|
|||
};
|
||||
c.push(instruction);
|
||||
}
|
||||
|
||||
// TODO: Member
|
||||
// TODO: List element
|
||||
_ => ice!(c, t, "Unsupported lvalue type"),
|
||||
}
|
||||
OK
|
||||
|
|
@ -533,6 +539,10 @@ fn compile_load_declaration(c: &mut Compiler, t: TreeRef, declaration: &Declarat
|
|||
compiler_assert!(c, t, index < c.module.globals);
|
||||
Instruction::LoadModule(index)
|
||||
}
|
||||
Location::Slot => {
|
||||
// TODO: Assert slot is in field range?
|
||||
Instruction::LoadSlot(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
Declaration::Function { declaration, .. } => {
|
||||
|
|
@ -603,10 +613,11 @@ fn compile_argument(c: &mut Compiler, tree: &Tree) -> CR {
|
|||
|
||||
fn compile_new_object_expression(c: &mut Compiler, t: TreeRef, tree: &Tree) -> CR {
|
||||
// We pass in the arguments.... by... field order?
|
||||
let Type::Class(class) = c.semantics.type_of(t) else {
|
||||
let Type::Class(ct, _) = c.semantics.type_of(t) else {
|
||||
c.push(Instruction::Panic);
|
||||
return OK;
|
||||
};
|
||||
let class = c.semantics.class_of(ct);
|
||||
|
||||
let field_list = tree.child_tree_of_kind(c.syntax, TreeKind::FieldList)?;
|
||||
let mut field_bindings = HashMap::new();
|
||||
|
|
@ -669,22 +680,10 @@ fn compile_field_value(c: &mut Compiler, t: TreeRef, tree: &Tree) -> CR {
|
|||
}
|
||||
|
||||
fn compile_member_access(c: &mut Compiler, tree: &Tree) -> CR {
|
||||
let lhs = tree.nth_tree(0)?;
|
||||
compile_expression(c, lhs);
|
||||
|
||||
let id = tree.nth_token(2)?;
|
||||
let Type::Class(cr) = c.semantics.type_of(lhs) else {
|
||||
return None;
|
||||
};
|
||||
let Some((index, _fld)) = cr
|
||||
.fields
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, f)| &*f.name == id.as_str())
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
c.push(Instruction::LoadSlot(index));
|
||||
// In member access; the lhs sets up the object and in theory the rhs
|
||||
// binds against it. ::shrug::
|
||||
compile_expression(c, tree.nth_tree(0)?);
|
||||
compile_expression(c, tree.nth_tree(2)?);
|
||||
OK
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue