partway towards commands
I got very confused and started mucking about with "spawn" when in fact all I needed was the "inline" extension type in orcx that allows the interpreter to expose custom constants.
This commit is contained in:
@@ -7,25 +7,34 @@ use std::ops::{Add, AddAssign, Range};
|
||||
use futures::future::join_all;
|
||||
use trait_set::trait_set;
|
||||
|
||||
use crate::error::ErrPos;
|
||||
use crate::interner::{IStr, es, is};
|
||||
use crate::name::Sym;
|
||||
use crate::{api, match_mapping, sym};
|
||||
use crate::{ErrPos, IStr, IteratorPrint, Sym, api, es, is, match_mapping, sym};
|
||||
|
||||
trait_set! {
|
||||
pub trait GetSrc = FnMut(&Sym) -> IStr;
|
||||
}
|
||||
|
||||
/// One or more positions in code that are associated with an event, value, or
|
||||
/// other consequence of that code
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum Pos {
|
||||
/// Location not known, for example because the expression was decoded from a
|
||||
/// source that doesn't have a meaningful location attached, from a format
|
||||
/// that does not encode location data
|
||||
None,
|
||||
/// If the expression in question is a slot, it receives the substituted
|
||||
/// expression's position. If the expression is being placed into a slot, this
|
||||
/// is discarded. In all other cases, it is a conflict and an error
|
||||
SlotTarget,
|
||||
/// Used in functions to denote the generated code that carries on the
|
||||
/// location of the call. Not allowed in the const tree.
|
||||
/// location of the call. Not allowed in the const tree
|
||||
Inherit,
|
||||
/// ID and parameters of a generator (such as an extension)
|
||||
Gen(CodeGenInfo),
|
||||
/// Range and file
|
||||
SrcRange(SrcRange),
|
||||
/// More than one positions. This vec should not contain another [Pos::Multi]
|
||||
/// and should be `>=2` long. To ensure this, use `+` and `+=` to combine
|
||||
/// positions and do not construct this directly.
|
||||
Multi(Vec<Pos>),
|
||||
}
|
||||
impl Pos {
|
||||
@@ -33,6 +42,7 @@ impl Pos {
|
||||
match self {
|
||||
Self::Gen(g) => g.to_string(),
|
||||
Self::SrcRange(sr) => sr.pretty_print(&get_src(&sr.path)),
|
||||
Self::Multi(posv) => posv.iter().display("and").to_string(),
|
||||
// Can't pretty print partial and meta-location
|
||||
other => format!("{other:?}"),
|
||||
}
|
||||
@@ -106,7 +116,7 @@ impl SrcRange {
|
||||
pub fn new(range: Range<u32>, path: &Sym) -> Self {
|
||||
Self { range: range.clone(), path: path.clone() }
|
||||
}
|
||||
/// Create a dud [SourceRange] for testing. Its value is unspecified and
|
||||
/// Create a dud [SrcRange] for testing. Its value is unspecified and
|
||||
/// volatile.
|
||||
pub async fn mock() -> Self { Self { range: 0..1, path: sym!(test) } }
|
||||
/// Path the source text was loaded from
|
||||
@@ -123,6 +133,10 @@ impl SrcRange {
|
||||
pub fn map_range(&self, map: impl FnOnce(Range<u32>) -> Range<u32>) -> Self {
|
||||
Self { range: map(self.range()), path: self.path() }
|
||||
}
|
||||
/// Format the range in a way that VSCode can convert to a link and is
|
||||
/// human-readable. For this operation we need the source code text, but
|
||||
/// holding it in the position object is a bit heavy so instead we take it as
|
||||
/// an argument
|
||||
pub fn pretty_print(&self, src: &str) -> String {
|
||||
let (sl, sc) = pos2lc(src, self.range.start);
|
||||
let (el, ec) = pos2lc(src, self.range.end);
|
||||
@@ -132,13 +146,21 @@ impl SrcRange {
|
||||
(false, _) => format!("{sl}:{sc}..{el}:{ec}"),
|
||||
}
|
||||
}
|
||||
/// Zero-width position at a certain offset
|
||||
pub fn zw(path: Sym, pos: u32) -> Self { Self { path, range: pos..pos } }
|
||||
/// Deserialize from a message
|
||||
pub async fn from_api(api: &api::SourceRange) -> Self {
|
||||
Self { path: Sym::from_api(api.path).await, range: api.range.clone() }
|
||||
}
|
||||
/// Serialize to a message
|
||||
pub fn to_api(&self) -> api::SourceRange {
|
||||
api::SourceRange { path: self.path.to_api(), range: self.range.clone() }
|
||||
}
|
||||
/// Connect two ranges into one
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// if the ranges are not from the same file
|
||||
pub fn to(&self, rhs: &Self) -> Self {
|
||||
assert_eq!(self.path, rhs.path, "Range continues across files");
|
||||
Self { path: self.path(), range: self.start().min(rhs.start())..self.end().max(rhs.end()) }
|
||||
@@ -173,9 +195,11 @@ impl CodeGenInfo {
|
||||
}
|
||||
/// Syntactic location
|
||||
pub fn pos(&self) -> Pos { Pos::Gen(self.clone()) }
|
||||
/// Deserialize from a message
|
||||
pub async fn from_api(api: &api::CodeGenInfo) -> Self {
|
||||
Self { generator: Sym::from_api(api.generator).await, details: es(api.details).await }
|
||||
}
|
||||
/// Serialize to a message
|
||||
pub fn to_api(&self) -> api::CodeGenInfo {
|
||||
api::CodeGenInfo { generator: self.generator.to_api(), details: self.details.to_api() }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user