Support methods sort of
This is broken b/c not type aware, but will do for now
This commit is contained in:
parent
c1b5fa392a
commit
1daf23b129
@ -71,9 +71,22 @@ impl<'a, 'b> Reducer<'a, 'b> {
|
||||
//TODO expressions can in principle contain definitions, but I won't worry
|
||||
//about it now
|
||||
}
|
||||
ast::StatementKind::Declaration(decl) =>
|
||||
if let ast::Declaration::FuncDecl(_, statements) = decl {
|
||||
ast::StatementKind::Declaration(decl) => match decl {
|
||||
ast::Declaration::FuncDecl(_, statements) => {
|
||||
self.insert_function_definition(item_id, statements);
|
||||
}
|
||||
ast::Declaration::Impl { type_name: _, interface_name: _, block } =>
|
||||
for item in block {
|
||||
if let ast::Statement {
|
||||
id: item_id,
|
||||
kind: ast::Declaration::FuncDecl(_, statements),
|
||||
..
|
||||
} = item
|
||||
{
|
||||
self.insert_function_definition(item_id, statements);
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
},
|
||||
// Imports should have already been processed by the symbol table and are irrelevant
|
||||
// for this representation.
|
||||
@ -124,6 +137,18 @@ impl<'a, 'b> Reducer<'a, 'b> {
|
||||
self.functions.insert(symbol.def_id(), function_def);
|
||||
}
|
||||
|
||||
//TODO this needs to be type-aware to work correctly
|
||||
fn lookup_method(&mut self, name: &str) -> Option<DefId> {
|
||||
for (def_id, function) in self.functions.iter() {
|
||||
let symbol = self.symbol_table.lookup_symbol_by_def(def_id)?;
|
||||
println!("Def Id: {} symbol: {:?}", def_id, symbol);
|
||||
if symbol.local_name() == name {
|
||||
return Some(*def_id);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn expression(&mut self, expr: &ast::Expression) -> Expression {
|
||||
use crate::ast::ExpressionKind::*;
|
||||
|
||||
@ -142,8 +167,8 @@ impl<'a, 'b> Reducer<'a, 'b> {
|
||||
let args = arguments.iter().map(|arg| self.invocation_argument(arg)).collect();
|
||||
//TODO need to have full type availability at this point to do this method lookup
|
||||
//correctly
|
||||
if let Expression::Access { name: _, expr } = f {
|
||||
let def_id = unimplemented!();
|
||||
if let Expression::Access { name, expr } = f {
|
||||
let def_id = self.lookup_method(&name).unwrap();
|
||||
let method = Expression::Lookup(Lookup::Function(def_id));
|
||||
Expression::CallMethod { f: Box::new(method), args, self_expr: expr }
|
||||
} else {
|
||||
|
@ -40,5 +40,22 @@ fn test_ir() {
|
||||
|
||||
let reduced = build_ir(src);
|
||||
assert_eq!(reduced.functions.len(), 3);
|
||||
//assert!(1 == 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_methods() {
|
||||
let src = r#"
|
||||
type Thing = Thing
|
||||
impl Thing {
|
||||
fn a_method() {
|
||||
20
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let a = Thing
|
||||
4 + a.a_method()
|
||||
"#;
|
||||
let reduced = build_ir(src);
|
||||
assert_eq!(reduced.functions.len(), 1);
|
||||
}
|
||||
|
@ -545,3 +545,20 @@ fn foo() { return 2 }
|
||||
"(7, 9)",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn eval_method() {
|
||||
let src = r#"
|
||||
type Thing = Thing
|
||||
impl Thing {
|
||||
fn a_method() {
|
||||
20
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let a = Thing::Thing
|
||||
4 + a.a_method()
|
||||
"#;
|
||||
eval_assert(src, "24");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user