Skip to content

Commit

Permalink
method_call: Add location info
Browse files Browse the repository at this point in the history
  • Loading branch information
CohenArthur committed Feb 20, 2022
1 parent 9da644e commit 76cb85b
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
24 changes: 23 additions & 1 deletion src/instruction/method_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
use crate::generics::{self, Generic};
use crate::instruction::FunctionCall;
use crate::typechecker::{CheckedType, TypeCtx};
use crate::{log, Context, InstrKind, Instruction, ObjectInstance, TypeCheck};
use crate::{log, Context, InstrKind, Instruction, ObjectInstance, SpanTuple, TypeCheck};

#[derive(Clone)]
pub struct MethodCall {
var: Box<dyn Instruction>,
method: FunctionCall,
cached_type: Option<CheckedType>,
location: Option<SpanTuple>,
}

impl MethodCall {
Expand All @@ -20,8 +21,13 @@ impl MethodCall {
var,
method,
cached_type: None,
location: None,
}
}

pub fn set_location(&mut self, location: SpanTuple) {
self.location = Some(location)
}
}

impl Instruction for MethodCall {
Expand All @@ -39,6 +45,9 @@ impl Instruction for MethodCall {

// FIXME: No clone here
let mut call = self.method.clone();
if let Some(loc) = &self.location {
call.set_location(loc.clone())
};

call.add_arg_front(self.var.clone());

Expand All @@ -48,12 +57,19 @@ impl Instruction for MethodCall {

call.execute(ctx)
}

fn location(&self) -> Option<&SpanTuple> {
self.location.as_ref()
}
}

impl TypeCheck for MethodCall {
fn resolve_type(&mut self, ctx: &mut TypeCtx) -> CheckedType {
let mut call = self.method.clone();
call.add_arg_front(self.var.clone());
if let Some(loc) = &self.location {
call.set_location(loc.clone())
};

call.type_of(ctx)
}
Expand All @@ -71,6 +87,9 @@ impl Generic for MethodCall {
fn expand(&self, ctx: &mut Context) {
let mut call = self.method.clone();
call.add_arg_front(self.var.clone());
if let Some(loc) = &self.location {
call.set_location(loc.clone())
};

log!("generic expanding method call: {}", self.method.name());

Expand All @@ -83,6 +102,9 @@ impl Generic for MethodCall {

let mut call = self.method.clone();
call.add_arg_front(self.var.clone());
if let Some(loc) = &self.location {
call.set_location(loc.clone())
};

log!("generic resolving method call: {}", self.method.name());

Expand Down
17 changes: 12 additions & 5 deletions src/parser/constructs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,22 +127,24 @@ fn term(input: ParseInput) -> ParseResult<ParseInput, Box<dyn Instruction>> {
/// factor = next unit factor_rest
fn factor(input: ParseInput) -> ParseResult<ParseInput, Box<dyn Instruction>> {
let input = next(input);
let (input, start_loc) = position(input)?;
let (input, unit) = unit(input)?;
factor_rest(input, unit)
factor_rest(input, unit, start_loc.into())
}

/// factor_rest = '.' IDENTIFIER next method_or_field factor_rest
/// | ε
fn factor_rest(
input: ParseInput,
expr: Box<dyn Instruction>,
start_loc: Location,
) -> ParseResult<ParseInput, Box<dyn Instruction>> {
match Token::dot(input) {
Ok((input, _)) => {
let (input, id) = Token::identifier(input)?;
let input = next(input);
let (input, expr) = method_or_field(input, expr, id)?;
factor_rest(input, expr)
let (input, expr) = method_or_field(input, expr, id, start_loc.clone())?;
factor_rest(input, expr, start_loc)
}
_ => Ok((input, expr)),
}
Expand All @@ -154,11 +156,14 @@ fn method_or_field(
input: ParseInput,
expr: Box<dyn Instruction>,
id: String,
start_loc: Location,
) -> ParseResult<ParseInput, Box<dyn Instruction>> {
if let Ok((input, _)) = Token::left_parenthesis(input) {
let input = next(input);
let (input, args) = args(input)?;
let method_call = MethodCall::new(expr, FunctionCall::new(id, vec![], args));
let (input, end_loc) = position(input)?;
let mut method_call = MethodCall::new(expr, FunctionCall::new(id, vec![], args));
method_call.set_location(SpanTuple::new(input.extra, start_loc, end_loc.into()));
Ok((input, Box::new(method_call)))
} else if let Ok((input, _)) = Token::left_bracket(input) {
let input = next(input);
Expand All @@ -167,7 +172,9 @@ fn method_or_field(
let (input, _) = Token::left_parenthesis(input)?;
let input = next(input);
let (input, args) = args(input)?;
let method_call = MethodCall::new(expr, FunctionCall::new(id, generics, args));
let (input, end_loc) = position(input)?;
let mut method_call = MethodCall::new(expr, FunctionCall::new(id, generics, args));
method_call.set_location(SpanTuple::new(input.extra, start_loc, end_loc.into()));
Ok((input, Box::new(method_call)))
} else {
Ok((input, Box::new(FieldAccess::new(expr, id))))
Expand Down

0 comments on commit 76cb85b

Please sign in to comment.