[fine] Methods!

This commit is contained in:
John Doty 2024-01-24 09:03:45 -08:00
parent 2839b43f6d
commit 0c69758b11
5 changed files with 352 additions and 95 deletions

View file

@ -291,6 +291,7 @@ fn compile_expression(c: &mut Compiler, t: TreeRef) {
TreeKind::NewObjectExpression => compile_new_object_expression(c, t, tree),
TreeKind::FieldValue => compile_field_value(c, t, tree),
TreeKind::MemberAccess => compile_member_access(c, tree),
TreeKind::SelfReference => compile_self_reference(c),
_ => ice!(c, t, "{tree:?} is not an expression, cannot compile"),
};
if matches!(cr, None) {
@ -553,11 +554,19 @@ fn compile_load_declaration(c: &mut Compiler, t: TreeRef, declaration: &Declarat
let tree = &c.syntax[*declaration];
compiler_assert_eq!(c, t, tree.kind, TreeKind::FunctionDecl);
compile_function_declaration(c, t, tree, false)?;
compile_function_declaration(c, *declaration, tree, false)?;
*c.function_bindings
.get(&key)
.expect("did not compile the function!")
match c.function_bindings.get(&key) {
Some(index) => *index,
None => {
ice!(
c,
t,
"did not compile the function with key {:?}!",
declaration
)
}
}
}
};
Instruction::LoadFunction(index)
@ -584,6 +593,12 @@ fn compile_call_expression(c: &mut Compiler, tree: &Tree) -> CR {
}
let func = tree.nth_tree(0)?;
let func_type = c.semantics.type_of(func);
let arg_count = match func_type {
// TODO: Consider being guided by syntax here?
Type::Method(..) => arg_count + 1,
_ => arg_count,
};
compile_expression(c, func);
c.push(Instruction::Call(arg_count));
@ -682,11 +697,21 @@ fn compile_field_value(c: &mut Compiler, t: TreeRef, tree: &Tree) -> CR {
fn compile_member_access(c: &mut Compiler, tree: &Tree) -> CR {
// 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)?);
// NOTE: If this is a method call we still don't have to do anything
// special here, since the load of the member function will *not*
// consume the self pointer from the stack.
compile_expression(c, tree.nth_tree(2)?);
OK
}
fn compile_self_reference(c: &mut Compiler) -> CR {
c.push(Instruction::LoadArgument(0));
OK
}
fn compile_statement(c: &mut Compiler, t: TreeRef, gen_value: bool) {
let tree = &c.semantics.tree()[t];
let cr = match tree.kind {
@ -777,6 +802,7 @@ fn compile_function_declaration(c: &mut Compiler, t: TreeRef, tree: &Tree, gen_v
// if we have no unbound type variables.
let fk = FunctionKey { tree: t };
if !c.function_bindings.contains_key(&fk) {
// TODO: If this is a method the name should be different.
let name = tree.nth_token(1)?;
let param_list = tree.child_tree_of_kind(c.syntax, TreeKind::ParamList)?;