Skip to content

Commit

Permalink
Remove builtin token printer, and switch to using ariadne byte spans
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Feb 29, 2024
1 parent 9013803 commit f83d753
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 90 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ tree-sitter-sus = {path = "tree-sitter-sus"}
# calyx-opt = {version = "0.6.1", optional = true}
# calyx-backend = {version = "0.6.1", optional = true}

# moore-circt = {version = "0.14.0", optional = true, path = "/home/lennart/Desktop/moore/src/circt"}
# moore-circt-sys = {version = "0.14.0", optional = true, path = "/home/lennart/Desktop/moore/src/circt-sys"}
moore-circt = {version = "0.14.0", optional = true}
moore-circt-sys = {version = "0.14.0", optional = true}
moore-circt = {version = "0.14.0", optional = true, path = "/home/lennart/Desktop/moore/src/circt"}
moore-circt-sys = {version = "0.14.0", optional = true, path = "/home/lennart/Desktop/moore/src/circt-sys"}
# moore-circt = {version = "0.14.0", optional = true}
# moore-circt-sys = {version = "0.14.0", optional = true}

#lsp
lsp-server = {version = "0.7.1", optional = true}
Expand Down
2 changes: 1 addition & 1 deletion ariadne
Submodule ariadne updated 3 files
+35 −12 src/lib.rs
+24 −0 src/source.rs
+192 −109 src/write.rs
3 changes: 3 additions & 0 deletions countConnectedCore.sus
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// These modules are counterparts to the Dedekind project's modules

// module monotonizeUp
9 changes: 7 additions & 2 deletions multiply_add.sus
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@


module multiply : int a, int b -> int r {
r = a * b;
}
Expand Down Expand Up @@ -508,11 +507,17 @@ module bad_cycle2 : int a -> int r {
r = test;
}

module module_taking_a_lot_of_time : int data_in'0 -> int data_out'300 {
module module_taking_a_lot_of_time : int data_in'0 -> int data_out'200 {
data_out = data_in;
}



/*extern*/ module offset_latency : int i'0 -> int o'-5 {

}


module good_cycle : int a -> int r {
state int test;
initial test = 0;
Expand Down
61 changes: 11 additions & 50 deletions src/dev_aid/syntax_highlighting.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

use std::{ops::Range, path::PathBuf};

use crate::{arena_alloc::ArenaVector, ast::*, errors::{CompileError, ErrorLevel}, file_position::{FileText, Span}, flattening::{Instruction, WireSource}, linker::{FileUUID, FileUUIDMarker, Linker, NameElem}, parser::*};
use crate::{arena_alloc::ArenaVector, ast::*, errors::{CompileError, ErrorLevel}, file_position::Span, flattening::{Instruction, WireSource}, linker::{FileUUID, FileUUIDMarker, Linker, NameElem}, parser::*};

use ariadne::*;

Expand Down Expand Up @@ -70,33 +70,6 @@ pub fn walk_name_color(all_objects : &[NameElem], linker : &Linker) -> Vec<(IDEI
result
}

// Outputs character_offsets.len() == tokens.len() + 1 to include EOF token
fn generate_character_offsets(file_text : &FileText) -> Vec<Range<usize>> {
let mut character_offsets : Vec<Range<usize>> = Vec::new();
character_offsets.reserve(file_text.num_tokens());

let mut cur_char = 0;
let mut whitespace_start = 0;
for tok_idx in 0..file_text.num_tokens() {
let tok_range = file_text.get_token_range(tok_idx);

// whitespace
cur_char += file_text.file_text[whitespace_start..tok_range.start].chars().count();
let token_start_char = cur_char;

// actual text
cur_char += file_text.file_text[tok_range.clone()].chars().count();
character_offsets.push(token_start_char..cur_char);
whitespace_start = tok_range.end;
}

// Final char offset for EOF
let num_chars_in_file = cur_char + file_text.file_text[whitespace_start..].chars().count();
character_offsets.push(cur_char..num_chars_in_file);

character_offsets
}

pub fn compile_all(file_paths : Vec<PathBuf>) -> (Linker, ArenaVector<(PathBuf, Source), FileUUIDMarker>) {
let mut linker = Linker::new();
let mut paths_arena : ArenaVector<(PathBuf, Source), FileUUIDMarker> = ArenaVector::new();
Expand All @@ -123,43 +96,33 @@ pub fn compile_all(file_paths : Vec<PathBuf>) -> (Linker, ArenaVector<(PathBuf,
(linker, paths_arena)
}


struct CustomSpan {
file : FileUUID,
span : Range<usize>
}
impl ariadne::Span for CustomSpan {
type SourceId = FileUUID;

fn source(&self) -> &FileUUID { &self.file }
fn start(&self) -> usize { self.span.start }
fn end(&self) -> usize { self.span.end }
}

// Requires that character_ranges.len() == tokens.len() + 1 to include EOF token
pub fn pretty_print_error<AriadneCache : Cache<FileUUID>>(error : &CompileError, file : FileUUID, character_ranges : &[Range<usize>], file_cache : &mut AriadneCache) {
pub fn pretty_print_error<AriadneCache : Cache<FileUUID>>(error : &CompileError, file : FileUUID, linker : &Linker, file_cache : &mut AriadneCache) {
// Generate & choose some colours for each of our elements
let (err_color, report_kind) = match error.level {
ErrorLevel::Error => (Color::Red, ReportKind::Error),
ErrorLevel::Warning => (Color::Yellow, ReportKind::Warning),
};
let info_color = Color::Blue;

let error_span = error.position.to_range(character_ranges);
let error_span = linker.files[file].file_text.get_span_range(error.position);

let mut report: ReportBuilder<'_, CustomSpan> = Report::build(report_kind, file, error_span.start);
let config =
Config::default()
.with_index_type(IndexType::Byte);
let mut report: ReportBuilder<'_, (FileUUID, Range<usize>)> = Report::build(report_kind, file, error_span.start).with_config(config);
report = report
.with_message(&error.reason)
.with_label(
Label::new(CustomSpan{file : file, span : error_span})
Label::new((file, error_span))
.with_message(&error.reason)
.with_color(err_color)
);

for info in &error.infos {
let info_span = info.position.to_range(character_ranges);
let info_span = linker.files[info.file].file_text.get_span_range(info.position);
report = report.with_label(
Label::new(CustomSpan{file : info.file, span : info_span})
Label::new((info.file, info_span))
.with_message(&info.info)
.with_color(info_color)
)
Expand All @@ -182,12 +145,10 @@ impl Cache<FileUUID> for ArenaVector<(PathBuf, Source<String>), FileUUIDMarker>

pub fn print_all_errors(linker : &Linker, paths_arena : &mut ArenaVector<(PathBuf, Source), FileUUIDMarker>) {
for (file_uuid, f) in &linker.files {
let token_offsets = generate_character_offsets(&f.file_text);

let errors = linker.get_all_errors_in_file(file_uuid);

for err in errors.get().0 {
pretty_print_error(&err, f.parsing_errors.file, &token_offsets, paths_arena);
pretty_print_error(&err, f.parsing_errors.file, linker, paths_arena);
}
}
}
33 changes: 6 additions & 27 deletions src/file_position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ impl Span {
/// Only really used for having a span with the maximum size.
pub const MAX_POSSIBLE_SPAN : Span = Span(0, usize::MAX);

pub fn to_range<T : Clone>(&self, tokens : &[Range<T>]) -> Range<T> {
let min = tokens[self.0].start.clone();
let max = tokens[self.1].end.clone();
min..max
}
pub fn new_overarching(left : Span, right : Span) -> Span {
assert!(left.0 <= right.0);
assert!(left.1 <= right.1);
Expand All @@ -21,22 +16,6 @@ impl Span {
pub fn new_single_token(tok_idx : usize) -> Span {
Span(tok_idx, tok_idx)
}
pub fn new_extend_to_include_token(left : Span, tok_idx : usize) -> Span {
Span::new_overarching(left, Span::new_single_token(tok_idx))
}
pub fn dont_include_last_token(self) -> Span {
self
}
pub fn only_last_token(self) -> Span {
Span(self.1, self.1)
}
pub fn new_extend_before(tok_idx : usize, right : Span) -> Span {
Span::new_overarching(Span::new_single_token(tok_idx), right)
}
pub fn new_across_tokens(start_tok : usize, end_tok : usize) -> Span {
assert!(start_tok <= end_tok);
Span(start_tok, end_tok)
}
pub fn contains_token(&self, token_idx : usize) -> bool {
token_idx >= self.0 && token_idx <= self.1
}
Expand Down Expand Up @@ -92,6 +71,12 @@ impl BracketSpan {
pub fn outer_span(&self) -> Span {
self.0
}
pub fn open_bracket(&self) -> SingleCharSpan {
SingleCharSpan{char_token : self.0.0}
}
pub fn close_bracket(&self) -> SingleCharSpan {
SingleCharSpan{char_token : self.0.1}
}
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
Expand Down Expand Up @@ -160,12 +145,6 @@ impl FileText {
pub fn num_tokens(&self) -> usize {
(self.token_boundaries.len() - 2) / 2
}
pub fn get_token_range(&self, token_idx : usize) -> Range<usize> {
self.token_boundaries[token_idx*2+1]..self.token_boundaries[token_idx*2+2]
}
pub fn get_token_linechar_range(&self, token_idx : usize) -> Range<CharLine> {
self.token_boundaries_as_char_lines[token_idx*2+1]..self.token_boundaries_as_char_lines[token_idx*2+2]
}
pub fn get_span_range(&self, span : Span) -> Range<usize> {
self.token_boundaries[span.0*2+1]..self.token_boundaries[span.1*2+2]
}
Expand Down
12 changes: 6 additions & 6 deletions src/flattening/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ impl<'prev, 'inst, 'l, 'runtime> FlatteningContext<'prev, 'inst, 'l, 'runtime> {
}))
}
// Returns the module, full interface, and the output range for the function call syntax
fn desugar_func_call(&mut self, func_and_args : &[SpanExpression], func_call_span : Span) -> Option<(&Module, InterfacePorts<FlatID>)> {
fn desugar_func_call(&mut self, func_and_args : &[SpanExpression], func_call_span : BracketSpan) -> Option<(&Module, InterfacePorts<FlatID>)> {
let (name_expr, name_expr_span) = &func_and_args[0]; // Function name is always there
let Expression::Named(name) = name_expr else {
self.errors.error_basic(*name_expr_span, "Function call name must be a simple identifier");
Expand Down Expand Up @@ -359,13 +359,13 @@ impl<'prev, 'inst, 'l, 'runtime> FlatteningContext<'prev, 'inst, 'l, 'runtime> {
let module_info = vec![error_info(md.link_info.span, md.link_info.file, "Interface defined here")];
if arg_count > expected_arg_count {
// Too many args, complain about excess args at the end
let excess_args_span = Span::new_overarching(args[expected_arg_count].1, func_call_span).dont_include_last_token();
let excess_args_span = Span::new_overarching(args[expected_arg_count].1, func_call_span.inner_span());
self.errors.error_with_info(excess_args_span, format!("Excess argument. Function takes {expected_arg_count} args, but {arg_count} were passed."), module_info);
// Shorten args to still get proper type checking for smaller arg array
args = &args[..expected_arg_count];
} else {
// Too few args, mention missing argument names
self.errors.error_with_info(func_call_span.only_last_token(), format!("Too few arguments. Function takes {expected_arg_count} args, but {arg_count} were passed."), module_info);
self.errors.error_with_info(func_call_span.close_bracket().into(), format!("Too few arguments. Function takes {expected_arg_count} args, but {arg_count} were passed."), module_info);
}
}

Expand Down Expand Up @@ -414,7 +414,7 @@ impl<'prev, 'inst, 'l, 'runtime> FlatteningContext<'prev, 'inst, 'l, 'runtime> {
WireSource::ArrayAccess{arr, arr_idx}
}
Expression::FuncCall(func_and_args) => {
if let Some((md, interface_wires)) = self.desugar_func_call(func_and_args, *expr_span) {
if let Some((md, interface_wires)) = self.desugar_func_call(func_and_args, BracketSpan::from_outer(*expr_span)) {
let output_range = interface_wires.func_call_syntax_outputs();

if output_range.len() != 1 {
Expand Down Expand Up @@ -500,7 +500,7 @@ impl<'prev, 'inst, 'l, 'runtime> FlatteningContext<'prev, 'inst, 'l, 'runtime> {
for (stmt, stmt_span) in &code.statements {
match stmt {
Statement::Assign{to, expr : Some((Expression::FuncCall(func_and_args), func_span)), eq_sign_position} => {
let Some((md, interface)) = self.desugar_func_call(&func_and_args, *func_span) else {continue};
let Some((md, interface)) = self.desugar_func_call(&func_and_args, BracketSpan::from_outer(*func_span)) else {continue};
let output_range = interface.func_call_syntax_outputs();
let outputs = &interface.ports[output_range];

Expand All @@ -510,7 +510,7 @@ impl<'prev, 'inst, 'l, 'runtime> FlatteningContext<'prev, 'inst, 'l, 'runtime> {
if num_targets != num_func_outputs {
let info = vec![error_info(md.link_info.span, md.link_info.file, "Module Defined here")];
if num_targets > num_func_outputs {
let excess_results_span = Span::new_overarching(to[num_func_outputs].span, *func_span).dont_include_last_token();
let excess_results_span = Span::new_overarching(to[num_func_outputs].span, to.last().unwrap().span);
self.errors.error_with_info(excess_results_span, format!("Excess output targets. Function returns {num_func_outputs} results, but {num_targets} targets were given."), info);
} else {
let too_few_targets_pos = if let Some(eq) = eq_sign_position {eq.into()} else {func_name_span};
Expand Down

0 comments on commit f83d753

Please sign in to comment.