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
|
//TODO expressions can in principle contain definitions, but I won't worry
|
||||||
//about it now
|
//about it now
|
||||||
}
|
}
|
||||||
ast::StatementKind::Declaration(decl) =>
|
ast::StatementKind::Declaration(decl) => match decl {
|
||||||
if let ast::Declaration::FuncDecl(_, statements) = decl {
|
ast::Declaration::FuncDecl(_, statements) => {
|
||||||
self.insert_function_definition(item_id, 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
|
// Imports should have already been processed by the symbol table and are irrelevant
|
||||||
// for this representation.
|
// for this representation.
|
||||||
@ -124,6 +137,18 @@ impl<'a, 'b> Reducer<'a, 'b> {
|
|||||||
self.functions.insert(symbol.def_id(), function_def);
|
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 {
|
fn expression(&mut self, expr: &ast::Expression) -> Expression {
|
||||||
use crate::ast::ExpressionKind::*;
|
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();
|
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
|
//TODO need to have full type availability at this point to do this method lookup
|
||||||
//correctly
|
//correctly
|
||||||
if let Expression::Access { name: _, expr } = f {
|
if let Expression::Access { name, expr } = f {
|
||||||
let def_id = unimplemented!();
|
let def_id = self.lookup_method(&name).unwrap();
|
||||||
let method = Expression::Lookup(Lookup::Function(def_id));
|
let method = Expression::Lookup(Lookup::Function(def_id));
|
||||||
Expression::CallMethod { f: Box::new(method), args, self_expr: expr }
|
Expression::CallMethod { f: Box::new(method), args, self_expr: expr }
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,5 +40,22 @@ fn test_ir() {
|
|||||||
|
|
||||||
let reduced = build_ir(src);
|
let reduced = build_ir(src);
|
||||||
assert_eq!(reduced.functions.len(), 3);
|
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)",
|
"(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