summaryrefslogtreecommitdiffstats
path: root/src/lib.rs
diff options
context:
space:
mode:
authorBrian Cully <bjc@spork.org>2025-08-24 09:16:11 -0400
committerBrian Cully <bjc@spork.org>2025-08-24 09:31:51 -0400
commit49ab2791b861884d01488de68f63bdd49d71c1b2 (patch)
tree54ee6f6db5be39093ffd22995461001d732f7dc2 /src/lib.rs
parent365312b14723503424a601a49827c191af82ad7a (diff)
downloadautomathon-49ab2791b861884d01488de68f63bdd49d71c1b2.tar.gz
automathon-49ab2791b861884d01488de68f63bdd49d71c1b2.zip
pass annotations to js so we can highlight program text
Diffstat (limited to 'src/lib.rs')
-rwxr-xr-xsrc/lib.rs60
1 files changed, 59 insertions, 1 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 850070a..71f7b7d 100755
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -50,15 +50,55 @@ impl ExportedByteCode {
}
}
+// ibid.
+#[wasm_bindgen]
+#[derive(Clone)]
+pub struct ExportedAnnotation {
+ pub start: usize,
+ pub end: usize,
+}
+
+impl From<(usize, usize)> for ExportedAnnotation {
+ fn from(v: (usize, usize)) -> Self {
+ Self {
+ start: v.0,
+ end: v.1,
+ }
+ }
+}
+
+// ibid.
+#[wasm_bindgen]
+#[derive(Clone)]
+pub struct ExportedWordAnnotations(Vec<ExportedAnnotation>);
+
+impl ExportedWordAnnotations {
+ pub fn from_word_annotations(annos: &Vec<forth::parser::Annotation>) -> Self {
+ ExportedWordAnnotations(annos.iter().map(|anno| anno.loc.into()).collect())
+ }
+}
+
+#[wasm_bindgen]
+impl ExportedWordAnnotations {
+ pub fn len(&self) -> usize {
+ self.0.len()
+ }
+
+ pub fn at(&self, offset: usize) -> ExportedAnnotation {
+ self.0[offset].clone()
+ }
+}
+
#[wasm_bindgen]
pub struct ExportedInterp {
+ annos: Vec<ExportedWordAnnotations>,
i: Option<forth::interp::Interp>,
}
#[wasm_bindgen]
impl ExportedInterp {
fn new() -> Self {
- Self { i: None }
+ Self { annos: vec![], i: None }
}
pub fn compile(&mut self, text: &str) -> bool {
@@ -67,6 +107,16 @@ impl ExportedInterp {
error!("couldn't parse program text: {:?}", e);
return false
}
+ self.annos = p.annotations.iter()
+ .map(|word_anno| -> ExportedWordAnnotations {
+ let v = word_anno.into_iter()
+ .map(|anno| -> ExportedAnnotation {
+ anno.loc.into()
+ })
+ .collect();
+ ExportedWordAnnotations(v)
+ })
+ .collect();
let interp = forth::interp::Interp::new(p.wordlist);
let _ = self.i.insert(interp);
true
@@ -105,6 +155,14 @@ impl ExportedInterp {
interp.wordlist.iter().map(|bc| ExportedByteCode::from_bc(bc)).collect()
}
+ pub fn annotations(&self) -> Vec<ExportedWordAnnotations> {
+ self.annos.clone()
+ }
+
+ pub fn annotation_at(&self, ip: &ExportedInstructionPointer) -> ExportedAnnotation {
+ self.annos[ip.word].0[ip.offset].clone()
+ }
+
pub fn callstack(&self) -> Vec<ExportedInstructionPointer> {
let Some(interp) = &self.i else {
return vec![]