Skip to content

Commit

Permalink
Further Span refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
VonTum committed Feb 26, 2024
1 parent 7e65cee commit 344e500
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 44 deletions.
45 changes: 19 additions & 26 deletions src/file_position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,6 @@ impl Span {
pub fn size(&self) -> usize {
self.1 - self.0
}
#[track_caller]
pub fn assert_is_single_token(&self) -> usize {
assert!(self.1 == self.0, "Span is not singleton! {}..{}", self.0, self.1);
self.0
}
pub fn is_single_token(&self) -> Option<usize> {
if self.0 == self.1 {
Some(self.0)
} else {
None
}
}
pub fn difference_left(outer : Span, inner : Span) -> Span {
assert!(outer.0 <= inner.0);
assert!(outer.1 >= inner.1);
Expand All @@ -70,15 +58,20 @@ impl Span {
Span(inner.1 + 1, outer.1) // temporary, because right now spans are still inclusive.
// Span(inner.1, outer.1)
}
pub fn into_single_char_span(self) -> SingleCharSpan {
// todo assert(self.1 == self.0+1)
SingleCharSpan{char_token: self.0}
}
}

impl IntoIterator for Span {
type Item = usize;

type IntoIter = <std::ops::Range<usize> as IntoIterator>::IntoIter;

fn into_iter(self) -> Self::IntoIter {
Range{start : self.0, end : self.1 + 1}.into_iter()
impl PartialOrd for Span {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
}
impl Ord for Span {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.cmp(&other.0)
}
}

Expand All @@ -101,14 +94,14 @@ impl BracketSpan {
}
}

impl PartialOrd for Span {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.0.partial_cmp(&other.0)
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct SingleCharSpan {
pub char_token : usize
}
impl Ord for Span {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.0.cmp(&other.0)

impl Into<Span> for SingleCharSpan {
fn into(self) -> Span {
Span(self.char_token, self.char_token)
}
}

Expand Down
16 changes: 10 additions & 6 deletions src/flattening/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ 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, SpanExpression, SpanTypeExpression, Statement, TypeExpression}, errors::{error_info, ErrorCollector, ErrorInfo}, file_position::{BracketSpan, Span}, 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, CodeBlock, Expression, Identifier, IdentifierType, InterfacePorts, LeftExpression, Module, Operator, SignalDeclaration, SpanExpression, SpanTypeExpression, Statement, TypeExpression},
errors::{error_info, ErrorCollector, ErrorInfo},
file_position::{BracketSpan, Span},
linker::{ConstantUUID, FileUUID, GlobalResolver, Linker, ModuleUUID, NameElem, NamedConstant, NamedType, ResolvedGlobals, ResolvedNameElem, TypeUUIDMarker},
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 Down Expand Up @@ -281,11 +287,9 @@ impl<'prev, 'inst, 'l, 'runtime> FlatteningContext<'prev, 'inst, 'l, 'runtime> {
}
fn resolve_identifier(&self, identifier : &Identifier) -> LocalOrGlobal {
// Possibly local
if let Some(single_tok_idx) = identifier.span.is_single_token() {
assert!(self.linker.file.tokens[single_tok_idx] == TOKEN_IDENTIFIER);
if let Some(decl_id) = self.local_variable_context.get_declaration_for(&self.linker.file.file_text[Span::new_single_token(single_tok_idx)]) {
return LocalOrGlobal::Local(decl_id);
}
let name_text = &self.linker.file.file_text[identifier.span];
if let Some(decl_id) = self.local_variable_context.get_declaration_for(name_text) {
return LocalOrGlobal::Local(decl_id);
}
// Global identifier
LocalOrGlobal::Global(self.linker.resolve_global(identifier.span, &self.errors))
Expand Down
26 changes: 14 additions & 12 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

use num::BigInt;

use crate::{ast::*, errors::*, file_position::{BracketSpan, FileText, Span}, flattening::FlattenedModule, instantiation::InstantiationList, linker::FileUUID, tokenizer::*, value::Value};
use crate::{ast::*, errors::*, file_position::{BracketSpan, FileText, SingleCharSpan, Span}, flattening::FlattenedModule, instantiation::InstantiationList, linker::FileUUID, tokenizer::*, value::Value};

use std::{iter::Peekable, ops::Range, str::FromStr};
use core::slice::Iter;
Expand Down Expand Up @@ -33,21 +33,21 @@ impl TokenTreeNode {
}


fn error_unclosed_bracket(open_pos : usize, open_typ : TokenTypeIdx, close_before_pos : usize, errors : &ErrorCollector) {
fn error_unclosed_bracket(open_pos : SingleCharSpan, open_typ : TokenTypeIdx, close_before_pos : SingleCharSpan, errors : &ErrorCollector) {
let open_name = get_token_type_name(open_typ);
let reason = format!("Unclosed bracket {open_name}");
let file_name = errors.file.clone();
errors.error_with_info(Span::new_single_token(open_pos), reason, vec![error_info(Span::new_single_token(close_before_pos), file_name, "must be closed before this")])
errors.error_with_info(open_pos.into(), reason, vec![error_info(close_before_pos.into(), file_name, "must be closed before this")])
}
fn error_unopened_bracket(close_pos : usize, close_typ : TokenTypeIdx, open_after_pos : usize, errors : &ErrorCollector) {
fn error_unopened_bracket(close_pos : SingleCharSpan, close_typ : TokenTypeIdx, open_after_pos : SingleCharSpan, errors : &ErrorCollector) {
let close_name = get_token_type_name(close_typ);
let reason = format!("Unopened bracket. Closing bracket {close_name} found but was not opened.");
let file_name = errors.file.clone();
errors.error_with_info(Span::new_single_token(close_pos), reason, vec![error_info(Span::new_single_token(open_after_pos), file_name, "must be opened in scope after this")])
errors.error_with_info(close_pos.into(), reason, vec![error_info(open_after_pos.into(), file_name, "must be opened in scope after this")])
}
struct TokenHierarchyStackElem {
open_bracket : TokenTypeIdx,
open_bracket_pos : usize,
open_bracket_span : SingleCharSpan,
parent : Vec<TokenTreeNode>
}

Expand All @@ -61,29 +61,31 @@ pub fn to_token_hierarchy(token_types : &[TokenTypeIdx], file_text : &FileText,
}
match is_bracket(tok_typ) {
IsBracket::Open => {
stack.push(TokenHierarchyStackElem{open_bracket : tok_typ, open_bracket_pos : tok_idx, parent : cur_token_slab});
let open_bracket_span = Span::new_single_token(tok_idx).into_single_char_span();
stack.push(TokenHierarchyStackElem{open_bracket : tok_typ, open_bracket_span, parent : cur_token_slab});
cur_token_slab = Vec::new();
},
IsBracket::Close => {
let close_bracket_span = Span::new_single_token(tok_idx).into_single_char_span();
loop { // Loop for bracket stack unrolling, for correct code only runs once
if let Some(cur_block) = stack.pop() {
if closes(cur_block.open_bracket, tok_typ) { // All is well. This bracket was closed properly. Happy path!
let mut parent_cur_token_slab = cur_block.parent;
parent_cur_token_slab.push(TokenTreeNode::Block(cur_block.open_bracket, cur_token_slab, BracketSpan::from_outer(Span::new_across_tokens(cur_block.open_bracket_pos, tok_idx))));
parent_cur_token_slab.push(TokenTreeNode::Block(cur_block.open_bracket, cur_token_slab, BracketSpan::from_outer(Span::new_overarching(cur_block.open_bracket_span.into(), close_bracket_span.into()))));
cur_token_slab = parent_cur_token_slab;
break;
} else {
if !stack.iter().any(|prev_bracket| closes(prev_bracket.open_bracket, tok_typ)) { // Any bracket in the stack closes this?
error_unopened_bracket(tok_idx, tok_typ, cur_block.open_bracket_pos, errors);
error_unopened_bracket(close_bracket_span, tok_typ, cur_block.open_bracket_span, errors);
stack.push(cur_block); // Push the previous bracket back onto bracket stack, as we disregarded erroneous closing bracket
break;
} else {
error_unclosed_bracket(cur_block.open_bracket_pos, token_types[cur_block.open_bracket_pos], tok_idx, errors);
error_unclosed_bracket(cur_block.open_bracket_span, cur_block.open_bracket, close_bracket_span, errors);
}
}
} else {
// Too many close brackets
errors.error_basic(Span::new_single_token(tok_idx), "A close bracket had no corresponding opening bracket.");
errors.error_basic(close_bracket_span.into(), "A close bracket had no corresponding opening bracket.");
break;
}
}
Expand All @@ -95,7 +97,7 @@ pub fn to_token_hierarchy(token_types : &[TokenTypeIdx], file_text : &FileText,
}

while let Some(unclosed) = stack.pop() {
errors.error_basic(Span::new_single_token(unclosed.open_bracket_pos), "Bracket was not closed before EOF")
errors.error_basic(unclosed.open_bracket_span.into(), "Bracket was not closed before EOF")
}

cur_token_slab
Expand Down

0 comments on commit 344e500

Please sign in to comment.