Skip to content

Commit

Permalink
refactor: encode more range info to env store values
Browse files Browse the repository at this point in the history
  • Loading branch information
jamestrew committed Dec 28, 2023
1 parent 5f06df2 commit ae92a60
Show file tree
Hide file tree
Showing 85 changed files with 189 additions and 141 deletions.
65 changes: 53 additions & 12 deletions src/eval/env/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,52 @@ use crate::eval::object::{Builtin, Object};
use crate::lexer::keyword_completions;
use crate::pos::{rng_str, OpsRange, Pos};

#[derive(PartialEq, Eq)]
pub struct Value {
pub ident_rng: Range,
pub stmt_rng: Range,
pub obj: Object,
}

impl Value {
pub fn new(ident_rng: Range, stmt_rng: Range, obj: Object) -> Self {
Self {
ident_rng,
stmt_rng,
obj,
}
}
}

impl std::fmt::Debug for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Value({:?}, {}, {})",
self.obj,
rng_str(&self.ident_rng),
rng_str(&self.stmt_rng)
)
}
}

impl PartialOrd for Value {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}

impl Ord for Value {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.stmt_rng
.start
.cmp(&other.stmt_rng.start)
.then_with(|| self.stmt_rng.end.cmp(&other.stmt_rng.end))
}
}

pub struct Scope {
pub store: HashMap<String, Arc<Pos<Object>>>,
pub store: HashMap<String, Arc<Value>>,
pub refs: Vec<Arc<Pos<String>>>,
pub range: Range,
parent: Option<Weak<RwLock<Scope>>>,
Expand Down Expand Up @@ -66,7 +110,7 @@ impl Env {

for func in Builtin::variants() {
let ident = &func.ident();
store.insert(ident.to_string(), Arc::new(func.pos_obj()));
store.insert(ident.to_string(), Arc::new(func.as_value()));
}
}

Expand All @@ -86,15 +130,15 @@ impl Env {
self.0.write().unwrap().children.push(child);
}

pub fn insert_store(&self, ident: &str, obj: &Arc<Pos<Object>>) {
pub fn insert_store(&self, ident: &str, obj: &Arc<Value>) {
self.0
.write()
.unwrap()
.store
.insert(ident.to_string(), Arc::clone(obj));
}

pub fn find_def(&self, ident: &str) -> Option<Arc<Pos<Object>>> {
pub fn find_def(&self, ident: &str) -> Option<Arc<Value>> {
let env = self.0.read().unwrap();
match env.store.get(ident) {
Some(obj) => Some(Arc::clone(obj)),
Expand Down Expand Up @@ -176,8 +220,8 @@ impl Env {
}

let def_env = pos_env.def_env(ident)?;
let def = def_env.find_def(ident)?;
Some(Range::new(def.start, def.end))
let ident_rng = def_env.find_def(ident)?.ident_rng;
Some(ident_rng)
}

pub fn find_references(&self, pos: &Position) -> Option<Vec<Range>> {
Expand Down Expand Up @@ -218,12 +262,9 @@ impl Env {
let mut items = env
.store
.iter()
.filter(|(ident, obj)| {
println!("{ident} {:?} {:?}", obj, pos);
!Builtin::includes(ident) && obj.end <= *pos
})
.map(|(ident, obj)| {
let kind = if matches!(***obj, Object::Function(_, _)) {
.filter(|(ident, value)| !Builtin::includes(ident) && value.stmt_rng.end <= *pos)
.map(|(ident, value)| {
let kind = if matches!(value.obj, Object::Function(_, _)) {
CompletionItemKind::FUNCTION
} else {
CompletionItemKind::VALUE
Expand Down
31 changes: 16 additions & 15 deletions src/eval/env/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use tower_lsp::lsp_types::*;

use crate::analyze_source;
use crate::eval::object::Builtin;
use crate::eval::Object;

const SOURCE: &str = r#"
let foo = 1 == 2;
Expand Down Expand Up @@ -30,18 +31,6 @@ let add_maybe = fn(x, y) {
puts(add_maybe(a, x));
"#;

fn foo_references() -> Vec<Range> {
vec![
Range::new(Position::new(1, 4), Position::new(1, 7)),
Range::new(Position::new(2, 5), Position::new(2, 8)),
Range::new(Position::new(4, 11), Position::new(4, 14)),
Range::new(Position::new(6, 15), Position::new(6, 18)),
Range::new(Position::new(10, 8), Position::new(10, 11)),
Range::new(Position::new(15, 8), Position::new(15, 11)),
Range::new(Position::new(16, 13), Position::new(16, 16)),
]
}

#[test]
fn no_diags_message() {
let (diags, _) = analyze_source(SOURCE);
Expand All @@ -53,7 +42,7 @@ fn find_same_scope_outer_def() {
let (_, env) = analyze_source(SOURCE);
assert_eq!(
env.find_pos_def(&Position::new(2, 5)),
Some(Range::new(Position::new(1, 0), Position::new(1, 17)))
Some(Range::new(Position::new(1, 4), Position::new(1, 7)))
);
}

Expand All @@ -62,7 +51,7 @@ fn def_is_in_outer_scope() {
let (_, env) = analyze_source(SOURCE);
assert_eq!(
env.find_pos_def(&Position::new(6, 15)),
Some(Range::new(Position::new(1, 0), Position::new(1, 17)))
Some(Range::new(Position::new(1, 4), Position::new(1, 7)))
);
}

Expand All @@ -71,7 +60,7 @@ fn def_is_in_deep_outer_scope() {
let (_, env) = analyze_source(SOURCE);
assert_eq!(
env.find_pos_def(&Position::new(16, 15)),
Some(Range::new(Position::new(1, 0), Position::new(1, 17)))
Some(Range::new(Position::new(1, 4), Position::new(1, 7)))
);
}

Expand All @@ -87,6 +76,18 @@ fn builtin_def() {
assert_eq!(env.find_pos_def(&Position::new(23, 0)), None);
}

fn foo_references() -> Vec<Range> {
vec![
Range::new(Position::new(1, 4), Position::new(1, 7)),
Range::new(Position::new(2, 5), Position::new(2, 8)),
Range::new(Position::new(4, 11), Position::new(4, 14)),
Range::new(Position::new(6, 15), Position::new(6, 18)),
Range::new(Position::new(10, 8), Position::new(10, 11)),
Range::new(Position::new(15, 8), Position::new(15, 11)),
Range::new(Position::new(16, 13), Position::new(16, 16)),
]
}

#[test]
fn no_ref_since_litera() {
let (_, env) = analyze_source(SOURCE);
Expand Down
19 changes: 12 additions & 7 deletions src/eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::sync::Arc;
pub use env::Env;
pub use object::Object;

use self::env::Value;
use crate::ast::{Node, Nodes, *};
use crate::diagnostics::{MonkeyError, MonkeyWarning, PosDiagnostic};

Expand Down Expand Up @@ -52,9 +53,11 @@ impl<'source> Eval {
let (obj, expr_diags) = self.eval_expression_stmt(&stmt.value, false);
diags.extend(expr_diags);

let obj = Arc::new(stmt.pos_wrap(obj));
let ident_rng = stmt.name.range();
let stmt_rng = stmt.range();
let value = Arc::new(Value::new(ident_rng, stmt_rng, obj));
let ident = stmt.name.name;
self.env.insert_store(ident, &obj);
self.env.insert_store(ident, &value);

let pos_ident = Arc::new(stmt.name.pos_wrap(ident.to_string()));
self.env.insert_ref(&pos_ident);
Expand Down Expand Up @@ -153,10 +156,10 @@ impl<'source> Eval {
let mut diags = Vec::new();
let ident = expr.name.to_string();
let obj = match self.env.find_def(&ident) {
Some(pos) => {
Some(value) => {
let pos_ident = Arc::new(expr.pos_wrap(ident));
self.env.insert_ref(&pos_ident);
(*pos).clone().take()
value.obj.clone()
}
None => {
diags.push(
Expand Down Expand Up @@ -291,7 +294,9 @@ impl<'source> Eval {
match param {
Ok(Expression::Identifier(ident_expr)) => {
let ident = ident_expr.name;
let pos_ident = Arc::new(ident_expr.pos_wrap(Object::Unknown));
let ident_rng = ident_expr.range();
let pos_ident =
Arc::new(Value::new(ident_rng, ident_rng, Object::Unknown));
child_env.insert_store(ident, &pos_ident);
}
Ok(_) => unreachable!(),
Expand Down Expand Up @@ -356,8 +361,8 @@ impl<'source> Eval {
}

if let Expression::Identifier(ident) = &*expr.func {
if let Some(func) = self.env.find_def(ident.name) {
if let Some(func_obj) = (*func).clone().take().function_return() {
if let Some(value) = self.env.find_def(ident.name) {
if let Some(func_obj) = value.obj.function_return() {
return (func_obj, diags);
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/eval/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use tower_lsp::lsp_types::{CompletionItem, CompletionItemKind};

use crate::ast::Call;
use crate::diagnostics::{MonkeyError, PosDiagnostic};
use crate::eval::env::Value;
use crate::pos::Pos;

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
Expand Down Expand Up @@ -71,12 +72,12 @@ pub enum Builtin {
}

impl Builtin {
pub fn pos_obj(&self) -> Pos<Object> {
Pos::new(
Default::default(),
Default::default(),
Object::Builtin(self.clone()),
)
pub fn as_value(&self) -> Value {
Value {
ident_rng: Default::default(),
stmt_rng: Default::default(),
obj: Object::Builtin(self.clone()),
}
}

pub fn ident(&self) -> &'static str {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Environment {
store: [
(
"x",
Pos(Array, (0,0)->(0,23)),
Value(Array, (0,4)->(0,5), (0,0)->(0,23)),
),
],
refs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Environment {
store: [
(
"x",
Pos(Unknown, (0,0)->(0,15)),
Value(Unknown, (0,4)->(0,5), (0,0)->(0,15)),
),
],
refs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Environment {
store: [
(
"x",
Pos(Unknown, (3,0)->(3,21)),
Value(Unknown, (3,4)->(3,5), (3,0)->(3,21)),
),
],
refs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Environment {
store: [
(
"x",
Pos(Unknown, (0,0)->(0,13)),
Value(Unknown, (0,4)->(0,5), (0,0)->(0,13)),
),
],
refs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Environment {
store: [
(
"x",
Pos(Array, (0,0)->(0,25)),
Value(Array, (0,4)->(0,5), (0,0)->(0,25)),
),
],
refs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Environment {
store: [
(
"x",
Pos(Unknown, (0,0)->(0,19)),
Value(Unknown, (0,4)->(0,5), (0,0)->(0,19)),
),
],
refs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Environment {
store: [
(
"foo",
Pos(Function(Some(0), Int), (0,0)->(0,29)),
Value(Function(Some(0), Int), (0,4)->(0,7), (0,0)->(0,29)),
),
],
refs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Environment {
store: [
(
"add",
Pos(Function(Some(2), Unknown), (0,0)->(0,36)),
Value(Function(Some(2), Unknown), (0,4)->(0,7), (0,0)->(0,36)),
),
],
refs: [
Expand All @@ -20,11 +20,11 @@ Environment {
store: [
(
"x",
Pos(Unknown, (0,13)->(0,14)),
Value(Unknown, (0,13)->(0,14), (0,13)->(0,14)),
),
(
"y",
Pos(Unknown, (0,15)->(0,16)),
Value(Unknown, (0,15)->(0,16), (0,15)->(0,16)),
),
],
refs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ Environment {
store: [
(
"add",
Pos(Function(Some(2), Unknown), (1,0)->(1,36)),
Value(Function(Some(2), Unknown), (1,4)->(1,7), (1,0)->(1,36)),
),
(
"x",
Pos(Unknown, (3,0)->(3,18)),
Value(Unknown, (3,4)->(3,5), (3,0)->(3,18)),
),
],
refs: [
Expand All @@ -26,11 +26,11 @@ Environment {
store: [
(
"x",
Pos(Unknown, (1,13)->(1,14)),
Value(Unknown, (1,13)->(1,14), (1,13)->(1,14)),
),
(
"y",
Pos(Unknown, (1,15)->(1,16)),
Value(Unknown, (1,15)->(1,16), (1,15)->(1,16)),
),
],
refs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Environment {
store: [
(
"x",
Pos(Hash, (0,0)->(0,27)),
Value(Hash, (0,4)->(0,5), (0,0)->(0,27)),
),
],
refs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Environment {
store: [
(
"x",
Pos(Unknown, (0,0)->(0,30)),
Value(Unknown, (0,4)->(0,5), (0,0)->(0,30)),
),
],
refs: [
Expand Down
Loading

0 comments on commit ae92a60

Please sign in to comment.