Skip to content

Commit

Permalink
Merge pull request #514 from jinko-core/dec-arg-location
Browse files Browse the repository at this point in the history
DecArg location
  • Loading branch information
CohenArthur authored Feb 20, 2022
2 parents 013868e + 6ed82a7 commit 010f43e
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 28 deletions.
4 changes: 2 additions & 2 deletions src/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl ErrorHandler {
if let Some(first_err) = self.errors.first() {
first_err.emit();
}
self.errors.iter().for_each(|e| {
self.errors.iter().skip(1).for_each(|e| {
eprintln!("----------------------------------------------------------------");
e.emit()
});
Expand Down Expand Up @@ -110,7 +110,7 @@ impl Error {
if let Some(ctx) = before_ctx {
ctx.emit('|', '_')
};
loc.emit("x".yellow(), "-".purple());
loc.emit(">".red().bold(), "-".purple());
after_ctx.emit('|', '_');
}

Expand Down
19 changes: 17 additions & 2 deletions src/instruction/dec_arg.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
use std::fmt::{Display, Formatter, Result};

use crate::typechecker::TypeId;
use crate::{typechecker::TypeId, SpanTuple};

#[derive(Clone, Debug, PartialEq)]
pub struct DecArg {
name: String,
ty: TypeId,
location: Option<SpanTuple>,
}

impl DecArg {
/// Create a new function declaration argument with a name and a type
pub fn new(name: String, ty: TypeId) -> DecArg {
DecArg { name, ty }
DecArg {
name,
ty,
location: None,
}
}

/// Return a reference to the argument's name
Expand All @@ -24,10 +29,20 @@ impl DecArg {
&self.ty
}

/// Get a reference to the argument's location
pub fn location(&self) -> Option<&SpanTuple> {
self.location.as_ref()
}

/// Set the type of the argument
pub fn set_type(&mut self, ty: TypeId) {
self.ty = ty
}

/// Set the location of the argument
pub fn set_location(&mut self, location: SpanTuple) {
self.location = Some(location)
}
}

impl Display for DecArg {
Expand Down
29 changes: 19 additions & 10 deletions src/instruction/function_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,15 @@ impl FunctionCall {
let mut instance = match call_arg.execute_expression(ctx) {
Some(i) => i,
None => {
ctx.error(Error::new(ErrKind::Context).with_msg(format!(
"trying to map statement to function argument: {} -> {}",
call_arg.print(),
func_arg
)));
ctx.error(
Error::new(ErrKind::Context)
.with_msg(format!(
"trying to map statement to function argument: {} -> {}",
call_arg.print(),
func_arg
))
.with_loc(func_arg.location().cloned()),
);
return;
}
};
Expand All @@ -102,7 +106,8 @@ impl FunctionCall {
None => {
ctx.error(
Error::new(ErrKind::Context)
.with_msg(format!("type not found: {}", func_arg.get_type().id())),
.with_msg(format!("type not found: {}", func_arg.get_type().id()))
.with_loc(func_arg.location().cloned()),
);
return;
}
Expand Down Expand Up @@ -289,10 +294,14 @@ impl TypeCheck for FunctionCall {
) {
let expected_ty = CheckedType::Resolved(dec_arg.get_type().clone());
if expected_ty != given_ty {
errors.push(Error::new(ErrKind::TypeChecker).with_msg(format!(
"invalid type used for function argument: expected `{}`, got `{}`",
expected_ty, given_ty
)));
errors.push(
Error::new(ErrKind::TypeChecker)
.with_msg(format!(
"invalid type used for function argument: expected `{}`, got `{}`",
expected_ty, given_ty
))
.with_loc(dec_arg.location().cloned()),
);
}

args.push((String::from(dec_arg.name()), expected_ty.clone()));
Expand Down
10 changes: 7 additions & 3 deletions src/location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ impl SpanTuple {
)
}

fn format_free_line<T: Display>(&self, separator: &T, line: &str) -> String {
format!(" {} {}", separator, line)
}

fn from_path<T1: Display, T2: Display>(
&self,
separator: &T1,
Expand Down Expand Up @@ -194,12 +198,12 @@ impl SpanTuple {
underline = format!("{}{}", underline, repetitor);
}

result.push_str(&self.format_line(&' ', i, &underline));
result.push_str(&self.format_free_line(&' ', &underline));
break;
}
// Four possible cases: First line, for which we need to skip
// start.column characters
else if i == 0 {
if i == 0 {
result.push_str(&self.format_line(separator, i, &line[(start_col - 1)..]));
}
// Last line, for which we only push up to end.column characters
Expand Down Expand Up @@ -246,7 +250,7 @@ mod tests {
assert_eq!(
span.to_string(&'>', &'-'),
r#" 1 > type Nothing;
1 ---"#
---"#
);
}

Expand Down
31 changes: 20 additions & 11 deletions src/parser/constructs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ fn unit_loop(input: ParseInput) -> ParseResult<ParseInput, Box<dyn Instruction>>
}

fn unit_for(input: ParseInput) -> ParseResult<ParseInput, Box<dyn Instruction>> {
let (input, id) = spaced_identifier(input)?;
let (input, (id, _)) = spaced_identifier(input)?;
let (input, _) = Token::in_tok(input)?;
let (input, expr) = expr(input)?;
let (input, block) = block(input)?;
Expand All @@ -263,7 +263,7 @@ fn unit_func<'i>(
}

fn unit_incl(input: ParseInput) -> ParseResult<ParseInput, Box<dyn Instruction>> {
let (input, path) = spaced_identifier(input)?;
let (input, (path, _)) = spaced_identifier(input)?;
if let Ok((input, _)) = Token::az_tok(input) {
let (input, alias) = preceded(nom_next, Token::identifier)(input)?;
Ok((input, Box::new(Incl::new(path, Some(alias)))))
Expand All @@ -274,7 +274,7 @@ fn unit_incl(input: ParseInput) -> ParseResult<ParseInput, Box<dyn Instruction>>

/// spaced_identifier '(' type_inst_arg (',' type_inst_arg)* ')'
fn unit_type_decl(input: ParseInput) -> ParseResult<ParseInput, Box<dyn Instruction>> {
let (input, name) = spaced_identifier(input)?;
let (input, (name, _)) = spaced_identifier(input)?;
let (input, generics) = maybe_generic_list(input)?;
let (input, type_dec) = if let Ok((input, _)) = Token::left_parenthesis(input) {
let (input, first_arg) = typed_arg(input)?;
Expand All @@ -293,7 +293,7 @@ fn unit_type_decl(input: ParseInput) -> ParseResult<ParseInput, Box<dyn Instruct

/// spaced_identifier '=' expr
fn unit_mut_var(input: ParseInput) -> ParseResult<ParseInput, Box<dyn Instruction>> {
let (input, symbol) = spaced_identifier(input)?;
let (input, (symbol, _)) = spaced_identifier(input)?;
let (input, _) = Token::equal(input)?;
let (input, value) = expr(input)?;

Expand Down Expand Up @@ -371,7 +371,7 @@ fn maybe_generic_list(input: ParseInput) -> ParseResult<ParseInput, Vec<TypeId>>
/// function_declaration = next spaced_identifier [ next '[' spaced_identifier ( ',' spaced_identifier )* ']' ] next '(' next typed_arg next return_type
fn func_declaration(input: ParseInput) -> ParseResult<ParseInput, FunctionDec> {
let input = next(input);
let (input, id) = spaced_identifier(input)?;
let (input, (id, _)) = spaced_identifier(input)?;
let input = next(input);

let (input, generics) = maybe_generic_list(input)?;
Expand All @@ -391,7 +391,7 @@ fn func_declaration(input: ParseInput) -> ParseResult<ParseInput, FunctionDec> {
fn return_type(input: ParseInput) -> ParseResult<ParseInput, Option<TypeId>> {
match Token::arrow(input) {
Ok((input, _)) => {
let (input, ty) = spaced_identifier(input)?;
let (input, (ty, _)) = spaced_identifier(input)?;
Ok((input, Some(TypeId::from(ty.as_str()))))
}
_ => Ok((input, None)),
Expand Down Expand Up @@ -542,18 +542,22 @@ fn multi_type(input: ParseInput) -> ParseResult<ParseInput, String> {

/// typed_arg = spaced_identifier ':' spaced_identifier
fn typed_arg(input: ParseInput) -> ParseResult<ParseInput, DecArg> {
let (input, id) = spaced_identifier(input)?;
let (input, (id, start_loc)) = spaced_identifier(input)?;
let (input, _) = Token::colon(input)?;
let input = next(input);
let (input, types) = multi_type(input)?;
let input = next(input);
let (input, end_loc) = position(input)?;

let mut dec_arg = DecArg::new(id, TypeId::new(types));
dec_arg.set_location(SpanTuple::new(input.extra, start_loc, end_loc.into()));

Ok((input, DecArg::new(id, TypeId::new(types))))
Ok((input, dec_arg))
}

/// type_inst_arg = spaced_identifier ':' expr
fn type_inst_arg(input: ParseInput) -> ParseResult<ParseInput, VarAssign> {
let (input, id) = spaced_identifier(input)?;
let (input, (id, _)) = spaced_identifier(input)?;
let (input, _) = Token::colon(input)?;
let input = next(input);
let (input, value) = expr(input)?;
Expand All @@ -562,8 +566,13 @@ fn type_inst_arg(input: ParseInput) -> ParseResult<ParseInput, VarAssign> {
Ok((input, VarAssign::new(false, id, value)))
}

fn spaced_identifier(input: ParseInput) -> ParseResult<ParseInput, String> {
delimited(nom_next, Token::identifier, nom_next)(input)
fn spaced_identifier(input: ParseInput) -> ParseResult<ParseInput, (String, Location)> {
let input = next(input);
let (input, loc) = position(input)?;
let (input, id) = Token::identifier(input)?;
let input = next(input);

Ok((input, (id, loc.into())))
}

/// next = extra*
Expand Down

0 comments on commit 010f43e

Please sign in to comment.