Skip to content

Commit

Permalink
Further refactoring of Span usage
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Feb 20, 2024
1 parent a6e7415 commit 731d1f9
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 77 deletions.
31 changes: 29 additions & 2 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::fmt::Display;


// Token span. Indices are INCLUSIVE
#[derive(Clone,Copy,Debug,PartialEq,Eq)]
#[derive(Clone,Copy,Debug,PartialEq,Eq,Hash)]
pub struct Span(pub usize, pub usize);

impl Span {
Expand Down Expand Up @@ -61,6 +61,20 @@ impl Span {
None
}
}
pub fn difference_left(outer : Span, inner : Span) -> Span {
assert!(outer.0 <= inner.0);
assert!(outer.1 >= inner.1);

Span(outer.0, inner.0 - 1) // temporary, because right now spans are still inclusive.
// Span(outer.0, inner.0)
}
pub fn difference_right(outer : Span, inner : Span) -> Span {
assert!(outer.0 <= inner.0);
assert!(outer.1 >= inner.1);

Span(inner.1 + 1, outer.1) // temporary, because right now spans are still inclusive.
// Span(inner.1, outer.1)
}
}

impl IntoIterator for Span {
Expand All @@ -73,6 +87,19 @@ impl IntoIterator for Span {
}
}

#[derive(Clone,Copy,Debug,PartialEq,Eq,Hash)]
pub struct BracketSpan(Span);

impl BracketSpan {
pub fn from_outer(span : Span) -> Self {Self(span)}
pub fn inner_span(&self) -> Span {
Span(self.0.0 + 1, self.0.1 - 1)
}
pub fn outer_span(&self) -> Span {
self.0
}
}

#[derive(Debug,Clone,Copy,PartialEq,Eq)]
pub enum IdentifierType {
Input,
Expand Down Expand Up @@ -139,7 +166,7 @@ pub enum Expression {
Constant(Value),
UnaryOp(Box<(Operator, usize/*Operator token */, SpanExpression)>),
BinOp(Box<(SpanExpression, Operator, usize/*Operator token */, SpanExpression)>),
Array(Box<(SpanExpression, SpanExpression, Span/*Brackets */)>), // first[second]
Array(Box<(SpanExpression, SpanExpression, BracketSpan)>), // first[second]
FuncCall(Vec<SpanExpression>) // first(second, third, ...)
}

Expand Down
12 changes: 8 additions & 4 deletions src/dev_aid/syntax_highlighting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,14 @@ fn pretty_print(file_text : &str, tokens : &TokenizeResult, ide_infos : &[IDETok

fn add_ide_bracket_depths_recursive<'a>(result : &mut [IDEToken], current_depth : usize, token_hierarchy : &[TokenTreeNode]) {
for tok in token_hierarchy {
if let TokenTreeNode::Block(_, sub_block, Span(left, right)) = tok {
result[*left].typ = IDETokenType::OpenBracket(current_depth);
if let TokenTreeNode::Block(_, sub_block, span) = tok {
let inner_span = span.inner_span();
let outer_span = span.outer_span();
let left_bracket_span = Span::difference_left(outer_span, inner_span);
let right_bracket_span = Span::difference_right(outer_span, inner_span);
result[left_bracket_span.assert_is_single_token()].typ = IDETokenType::OpenBracket(current_depth);
add_ide_bracket_depths_recursive(result, current_depth+1, sub_block);
result[*right].typ = IDETokenType::CloseBracket(current_depth);
result[right_bracket_span.assert_is_single_token()].typ = IDETokenType::CloseBracket(current_depth);
}
}
}
Expand Down Expand Up @@ -139,7 +143,7 @@ fn walk_name_color(all_objects : &[NameElem], linker : &Linker, result : &mut [I
Instruction::Write(conn) => {
let decl = module.flattened.instructions[conn.to.root].extract_wire_declaration();
if !decl.is_declared_in_this_module {continue;} // Virtual wires don't appear in this program text
result[conn.to.span.0].typ = IDETokenType::Identifier(IDEIdentifierType::Value(decl.identifier_type));
result[conn.to.root_span.assert_is_single_token()].typ = IDETokenType::Identifier(IDEIdentifierType::Value(decl.identifier_type));
}
Instruction::SubModule(sm) => {
set_span_name_color(sm.module_name_span, IDEIdentifierType::Interface, result);
Expand Down
21 changes: 11 additions & 10 deletions src/flattening/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub mod name_context;
use std::{ops::Deref, iter::zip};

use crate::{
arena_alloc::{ArenaAllocator, FlatAlloc, UUIDMarker, UUIDRange, UUID}, ast::{AssignableExpressionModifiers, CodeBlock, Expression, Identifier, IdentifierType, InterfacePorts, LeftExpression, Module, Operator, SignalDeclaration, Span, SpanExpression, SpanTypeExpression, Statement, TypeExpression}, errors::{error_info, ErrorCollector, ErrorInfo}, linker::{ConstantUUID, FileUUID, GlobalResolver, Linker, ModuleUUID, NameElem, NamedConstant, NamedType, ResolvedGlobals, ResolvedNameElem, TypeUUIDMarker}, tokenizer::TOKEN_IDENTIFIER, typing::{get_binary_operator_types, typecheck, typecheck_is_array_indexer, typecheck_unary_operator, Type, WrittenType, BOOL_TYPE, INT_TYPE}, value::Value
arena_alloc::{ArenaAllocator, FlatAlloc, UUIDMarker, UUIDRange, UUID}, ast::{AssignableExpressionModifiers, BracketSpan, CodeBlock, Expression, Identifier, IdentifierType, InterfacePorts, LeftExpression, Module, Operator, SignalDeclaration, Span, SpanExpression, SpanTypeExpression, Statement, TypeExpression}, errors::{error_info, ErrorCollector, ErrorInfo}, linker::{ConstantUUID, FileUUID, GlobalResolver, Linker, ModuleUUID, NameElem, NamedConstant, NamedType, ResolvedGlobals, ResolvedNameElem, TypeUUIDMarker}, tokenizer::TOKEN_IDENTIFIER, typing::{get_binary_operator_types, typecheck, typecheck_is_array_indexer, typecheck_unary_operator, Type, WrittenType, BOOL_TYPE, INT_TYPE}, value::Value
};

use self::name_context::LocalVariableContext;
Expand All @@ -18,7 +18,7 @@ pub type FlatIDRange = UUIDRange<FlatIDMarker>;

#[derive(Debug)]
pub enum ConnectionWritePathElement {
ArrayIdx{idx : FlatID, idx_span : Span},
ArrayIdx{idx : FlatID, bracket_span : BracketSpan},
//StructField(FieldID)
}
#[derive(Debug)]
Expand All @@ -30,6 +30,7 @@ pub enum ConnectionWritePathElementComputed {
#[derive(Debug)]
pub struct ConnectionWrite {
pub root : FlatID,
pub root_span : Span,
pub path : Vec<ConnectionWritePathElement>,
pub span : Span,
pub is_declared_in_this_module : bool
Expand Down Expand Up @@ -366,7 +367,7 @@ impl<'prev, 'inst, 'l, 'runtime> FlatteningContext<'prev, 'inst, 'l, 'runtime> {
for (field, arg_expr) in zip(inputs, args) {
let arg_read_side = self.flatten_expr(arg_expr);
let func_input_port = &submodule_local_wires.ports[field];
self.instructions.alloc(Instruction::Write(Write{write_type : WriteType::Connection{num_regs : 0, regs_span : None}, from: arg_read_side, to: ConnectionWrite{root : *func_input_port, path : Vec::new(), span : *name_expr_span, is_declared_in_this_module : self.is_declared_in_this_module}}));
self.instructions.alloc(Instruction::Write(Write{write_type : WriteType::Connection{num_regs : 0, regs_span : None}, from: arg_read_side, to: ConnectionWrite{root : *func_input_port, root_span : arg_expr.1, path : Vec::new(), span : *name_expr_span, is_declared_in_this_module : self.is_declared_in_this_module}}));
}

Some((md, submodule_local_wires))
Expand Down Expand Up @@ -439,18 +440,18 @@ impl<'prev, 'inst, 'l, 'runtime> FlatteningContext<'prev, 'inst, 'l, 'runtime> {
Expression::Named(local_idx) => {
let root = self.resolve_identifier(local_idx).expect_local("assignments")?;

Some(ConnectionWrite{root, path : Vec::new(), span, is_declared_in_this_module : self.is_declared_in_this_module})
Some(ConnectionWrite{root, root_span : span, path : Vec::new(), span, is_declared_in_this_module : self.is_declared_in_this_module})
}
Expression::Array(arr_box) => {
let (arr, idx_expr, _bracket_span) = arr_box.deref();
let (arr, idx_expr, bracket_span) = arr_box.deref();
let flattened_arr_expr_opt = self.flatten_assignable_expr(&arr.0, arr.1);

let idx = self.flatten_expr(idx_expr);

let mut flattened_arr_expr = flattened_arr_expr_opt?; // only unpack the subexpr after flattening the idx, so we catch all errors

flattened_arr_expr.path.push(ConnectionWritePathElement::ArrayIdx{idx, idx_span : idx_expr.1});

flattened_arr_expr.path.push(ConnectionWritePathElement::ArrayIdx{idx, bracket_span : *bracket_span});
flattened_arr_expr.span = Span::new_overarching(flattened_arr_expr.span, bracket_span.outer_span());
Some(flattened_arr_expr)
}
Expression::Constant(_) => {self.errors.error_basic(span, "Cannot assign to constant"); None},
Expand All @@ -466,7 +467,7 @@ impl<'prev, 'inst, 'l, 'runtime> FlatteningContext<'prev, 'inst, 'l, 'runtime> {
}
LeftExpression::Declaration(decl) => {
let root = self.flatten_declaration::<true>(decl, false, !gets_assigned);
Some(ConnectionWrite{root, path: Vec::new(), span, is_declared_in_this_module: true})
Some(ConnectionWrite{root, root_span : Span::new_single_token(decl.name_token), path: Vec::new(), span, is_declared_in_this_module: true})
}
}
}
Expand Down Expand Up @@ -590,11 +591,11 @@ impl<'prev, 'inst, 'l, 'runtime> FlatteningContext<'prev, 'inst, 'l, 'runtime> {
let mut write_to_type = Some(&conn_root.typ);
for p in &to.path {
match p {
&ConnectionWritePathElement::ArrayIdx{idx, idx_span} => {
&ConnectionWritePathElement::ArrayIdx{idx, bracket_span} => {
let idx_wire = self.instructions[idx].extract_wire();
self.typecheck_wire_is_of_type(idx_wire, &INT_TYPE, "array index");
if let Some(wr) = write_to_type {
write_to_type = typecheck_is_array_indexer(wr, idx_span, self.type_list_for_naming, &self.errors);
write_to_type = typecheck_is_array_indexer(wr, bracket_span.outer_span(), self.type_list_for_naming, &self.errors);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/instantiation/latency_algorithm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ mod tests {

let should_be_err = solve_latencies_infer_ports(&fanins, Vec::new());

let Err(LatencyCountingError::NetPositiveLatencyCycle{conflict_path, net_roundtrip_latency}) = should_be_err else {unreachable!()};
let Err(LatencyCountingError::NetPositiveLatencyCycle{conflict_path:_, net_roundtrip_latency}) = should_be_err else {unreachable!()};
assert_eq!(net_roundtrip_latency, 1);
}
}
Expand Down
38 changes: 19 additions & 19 deletions src/instantiation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
}
}
}
fn extract_integer_from_generative<'v, IntT : TryFrom<&'v BigInt>>(&'v self, idx : FlatID) -> Option<IntT> {
let val = self.get_generation_value(idx)?;
let span = self.flattened.instructions[idx].extract_wire().span;
self.extract_integer_from_value(val, span)
}

fn concretize_type(&self, typ : &Type, span : Span) -> Option<ConcreteType> {
match typ {
Type::Error | Type::Unknown => unreachable!("Bad types should be caught in flattening: {}", typ.to_string(&self.linker.types)),
Expand All @@ -200,11 +206,9 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
}
Type::Array(arr_box) => {
let (arr_content_typ, arr_size_wire) = arr_box.deref();
let inner_typ = self.concretize_type(arr_content_typ, span)?;
let size_val = &self.generation_state[*arr_size_wire];
let cv = size_val.extract_generation_value();
let arr_usize = self.extract_integer_from_value(cv, span)?;
Some(ConcreteType::Array(Box::new((inner_typ, arr_usize))))
let inner_typ = self.concretize_type(arr_content_typ, span);
let arr_size = self.extract_integer_from_generative(*arr_size_wire);
Some(ConcreteType::Array(Box::new((inner_typ?, arr_size?))))
}
}
}
Expand All @@ -215,7 +219,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {

for pe in to_path {
match pe {
ConnectionWritePathElement::ArrayIdx{idx, idx_span} => {
ConnectionWritePathElement::ArrayIdx{idx, bracket_span:_} => {
match &self.generation_state[*idx] {
SubModuleOrWire::SubModule(_) => unreachable!(),
SubModuleOrWire::Unnasigned => unreachable!(),
Expand All @@ -224,8 +228,8 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {

new_path.push(ConnectToPathElem::MuxArrayWrite{idx_wire : *idx_wire});
}
SubModuleOrWire::CompileTimeValue(v) => {
let idx = self.extract_integer_from_value(v, *idx_span)?;
SubModuleOrWire::CompileTimeValue(_) => {
let idx = self.extract_integer_from_generative(*idx)?;
new_path.push(ConnectToPathElem::ConstArrayWrite{idx});
}
}
Expand Down Expand Up @@ -257,9 +261,8 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
result.reserve(conn_path.len());
for p in conn_path {
match p {
ConnectionWritePathElement::ArrayIdx{idx, idx_span} => {
let idx_val = self.get_generation_value(*idx)?;
let idx_val = self.extract_integer_from_value::<usize>(idx_val, *idx_span)?;
ConnectionWritePathElement::ArrayIdx{idx, bracket_span:_} => {
let idx_val = self.extract_integer_from_generative(*idx)?;
result.push(ConnectionWritePathElementComputed::ArrayIdx(idx_val))
}
}
Expand Down Expand Up @@ -321,9 +324,8 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
}
&WireSource::ArrayAccess{arr, arr_idx} => {
let Value::Array(arr_val) = self.get_generation_value(arr)? else {return None};
let arr_idx_val = self.get_generation_value(arr_idx)?;
let arr_idx_wire = self.flattened.instructions[arr_idx].extract_wire();
let idx : usize = self.extract_integer_from_value(arr_idx_val, arr_idx_wire.span)?;
let idx : usize = self.extract_integer_from_generative(arr_idx)?;
if let Some(item) = arr_val.get(idx) {
item.clone()
} else {
Expand Down Expand Up @@ -378,9 +380,8 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
SubModuleOrWire::Wire(w) => {
RealWireDataSource::ArrayAccess{arr, arr_idx: *w}
}
SubModuleOrWire::CompileTimeValue(v) => {
let arr_idx_wire = self.flattened.instructions[arr_idx].extract_wire();
let arr_idx = self.extract_integer_from_value(v, arr_idx_wire.span)?;
SubModuleOrWire::CompileTimeValue(_) => {
let arr_idx = self.extract_integer_from_generative(arr_idx)?;
RealWireDataSource::ConstArrayAccess{arr, arr_idx}
}
}
Expand Down Expand Up @@ -438,7 +439,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
};
let absolute_latency = if let Some(spec) = &wire_decl.latency_specifier {
if wire_decl.is_declared_in_this_module {
self.extract_integer_from_value(self.get_generation_value(*spec)?, self.flattened.instructions[*spec].extract_wire().span)?
self.extract_integer_from_generative(*spec)?
} else {
CALCULATE_LATENCY_LATER
}
Expand All @@ -447,8 +448,7 @@ impl<'fl, 'l> InstantiationContext<'fl, 'l> {
};
let wire_id = self.wires.alloc(RealWire{name: wire_decl.name.clone(), typ, original_wire, source, absolute_latency, needed_until : CALCULATE_LATENCY_LATER});
if let Some(lat_spec_flat) = wire_decl.latency_specifier {
let val = self.get_generation_value(lat_spec_flat)?;
let specified_absolute_latency : i64 = self.extract_integer_from_value(val, self.flattened.instructions[lat_spec_flat].extract_wire().span)?;
let specified_absolute_latency : i64 = self.extract_integer_from_generative(lat_spec_flat)?;
self.specified_latencies.push((wire_id, specified_absolute_latency));
}
SubModuleOrWire::Wire(wire_id)
Expand Down
5 changes: 3 additions & 2 deletions src/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ impl Linker {
location_builder.update(wire.span, loc_info);
}
Instruction::Write(write) => {
location_builder.update(Span::new_single_token(write.to.span.0), LocationInfo::WireRef(md, write.to.root));
location_builder.update(write.to.root_span, LocationInfo::WireRef(md, write.to.root));
}
Instruction::IfStatement(_) | Instruction::ForStatement(_) => {}
};
Expand Down Expand Up @@ -470,7 +470,8 @@ impl<'linker> LocationInfoBuilder<'linker> {
}
fn update(&mut self, span : Span, info : LocationInfo<'linker>) {
if span.contains_token(self.token_idx) && span.size() <= self.best_span.size() {
assert!(span.size() < self.best_span.size());
//assert!(span.size() < self.best_span.size());
// May not be the case. Do prioritize later ones, as they tend to be nested
self.best_span = span;
self.best_instruction = Some(info);
}
Expand Down
Loading

0 comments on commit 731d1f9

Please sign in to comment.