updating TLD value name works!

This commit is contained in:
Anton-4 2021-08-30 19:49:47 +02:00
parent 6c889b35b9
commit 3c858cff96
10 changed files with 280 additions and 25 deletions

View file

@ -81,8 +81,6 @@ impl Symbol {
)
});
dbg!(ident_ids);
ident_ids
.get_name(self.ident_id())
.unwrap_or_else(|| {
@ -576,7 +574,7 @@ impl IdentIds {
if let Some(vec_elt) = by_id.get_mut(key_index) {
*vec_elt = new_ident_name.into();
} else {
// we get the index from by_id so unless there is a bug in the rust std lib, this is unreachable
// we get the index from by_id
unreachable!()
}
@ -592,7 +590,7 @@ impl IdentIds {
}
}
None => {
Err("Tried to update key in IdentIds but I could not find the key.".to_string())
Err(format!("Tried to update key in IdentIds ({:?}) but I could not find the key ({}).", self.by_ident, old_ident_name))
}
}
}

View file

@ -13,6 +13,15 @@ use snafu::{Backtrace, ErrorCompat, NoneError, ResultExt, Snafu};
#[snafu(visibility(pub))]
pub enum EdError {
#[snafu(display(
"ASTNodeIdWithoutDefId: The expr_id_opt in ASTNode({:?}) was `None` but I was expexting `Some(DefId)` .",
ast_node_id
))]
ASTNodeIdWithoutDefId {
ast_node_id: ASTNodeId,
backtrace: Backtrace,
},
#[snafu(display(
"ASTNodeIdWithoutExprId: The expr_id_opt in ASTNode({:?}) was `None` but I was expexting `Some(ExprId)` .",
ast_node_id

View file

@ -148,8 +148,8 @@ impl GridNodeMap {
}
}
// returns start and end pos of Expr2, relevant AST node and MarkNodeId of the corresponding MarkupNode
pub fn get_expr_start_end_pos(
// returns start and end pos of Expr2/Def2, relevant AST node and MarkNodeId of the corresponding MarkupNode
pub fn get_block_start_end_pos(
&self,
caret_pos: TextPos,
ed_model: &EdModel,

View file

@ -3,6 +3,7 @@ use crate::editor::ed_error::EdResult;
use crate::editor::ed_error::ExpectedTextNode;
use crate::editor::ed_error::{NestedNodeMissingChild, NestedNodeRequired};
use crate::editor::markup::common_nodes::new_blank_mn;
use crate::editor::markup::common_nodes::new_blank_mn_w_nl;
use crate::editor::markup::common_nodes::new_colon_mn;
use crate::editor::markup::common_nodes::new_comma_mn;
use crate::editor::markup::common_nodes::new_equals_mn;
@ -19,7 +20,7 @@ use crate::lang::ast::DefId;
use crate::lang::ast::ExprId;
use crate::lang::ast::RecordField;
use crate::lang::ast::ValueDef;
use crate::lang::ast::expr2_to_string;
use crate::editor::mvc::tld_value_update::tld_mark_node;
use crate::lang::parse::ASTNodeId;
use crate::lang::parse::{AppHeader, AST};
use crate::lang::pattern::get_identifier_string;
@ -284,7 +285,39 @@ pub fn def2_to_markup<'a, 'b>(
mark_node_pool: &mut SlowPool,
interns: &Interns,
) -> EdResult<MarkNodeId> {
unimplemented!();
let ast_node_id = ASTNodeId::ADefId(def2_node_id);
let mark_node_id = match def2 {
Def2::ValueDef { identifier_id, expr_id } => {
let expr_mn_id = expr2_to_markup(
arena,
env,
env.pool.get(*expr_id),
*expr_id,
mark_node_pool,
interns,
)?;
let expr_mn = mark_node_pool.get_mut(expr_mn_id);
expr_mn.add_newline_at_end();
let tld_mn = tld_mark_node(*identifier_id, expr_mn_id, ast_node_id, mark_node_pool, env, interns)?;
mark_node_pool.add(
tld_mn
)
},
Def2::Blank => {
mark_node_pool.add(
new_blank_mn_w_nl(ast_node_id, None)
)
},
};
Ok(mark_node_id)
}
// make Markup Nodes: generate String representation, assign Highlighting Style
@ -296,7 +329,6 @@ pub fn expr2_to_markup<'a, 'b>(
mark_node_pool: &mut SlowPool,
interns: &Interns,
) -> EdResult<MarkNodeId> {
dbg!(expr2_to_string(expr2_node_id, env.pool));
let ast_node_id = ASTNodeId::AExprId(expr2_node_id);
@ -442,17 +474,14 @@ pub fn expr2_to_markup<'a, 'b>(
Expr2::Blank => mark_node_pool.add(new_blank_mn(ast_node_id, None)),
Expr2::LetValue {
def_id,
body_id,
body_var,
body_id:_,
body_var:_,
} => {
/*dbg!(expr2);
dbg!(env.pool.get(*body_id));
dbg!(env.pool.get(*def_id));
dbg!(body_var);*/
let pattern_id = env.pool.get(*def_id).get_pattern_id();
let pattern2 = env.pool.get(pattern_id);
dbg!(pattern2);
let val_name = get_identifier_string(pattern2, interns)?;
let val_name_mn = MarkupNode::Text {

View file

@ -8,6 +8,7 @@ use crate::editor::grid_node_map::GridNodeMap;
use crate::editor::markup::attribute::Attributes;
use crate::editor::markup::common_nodes::new_blank_mn;
use crate::editor::markup::nodes;
use crate::editor::markup::nodes::EQUALS;
use crate::editor::markup::nodes::MarkupNode;
use crate::editor::mvc::app_update::InputOutcome;
use crate::editor::mvc::ed_model::EdModel;
@ -26,6 +27,7 @@ use crate::editor::mvc::string_update::update_string;
use crate::editor::slow_pool::MarkNodeId;
use crate::editor::slow_pool::SlowPool;
use crate::editor::syntax_highlight::HighlightStyle;
use crate::editor::mvc::tld_value_update::{start_new_tld_value, update_tld_val_name};
use crate::lang::ast::Def2;
use crate::lang::ast::{Expr2, ExprId};
use crate::lang::constrain::constrain_expr;
@ -85,6 +87,18 @@ impl<'a> EdModel<'a> {
}
}
// disregards EdModel.code_lines because the caller knows the resulting caret position will be valid.
// allows us to prevent multiple updates to EdModel.code_lines
// TODO error if no match was found for old_caret_pos
pub fn simple_move_caret_right(&mut self, old_caret_pos: TextPos, repeat: usize) {
for caret_tup in self.caret_w_select_vec.iter_mut() {
if caret_tup.0.caret_pos == old_caret_pos {
caret_tup.0.caret_pos.column += 1;
caret_tup.1 = None;
}
}
}
// disregards EdModel.code_lines because the caller knows the resulting caret position will be valid.
// allows us to prevent multiple updates to EdModel.code_lines
pub fn simple_move_carets_left(&mut self, repeat: usize) {
@ -106,6 +120,7 @@ impl<'a> EdModel<'a> {
// disregards EdModel.code_lines because the caller knows the resulting caret position will be valid.
// allows us to prevent multiple updates to EdModel.code_lines
// TODO error if no match was found for old_caret_pos
pub fn simple_move_caret_down(&mut self, old_caret_pos: TextPos, repeat: usize) {
for caret_tup in self.caret_w_select_vec.iter_mut() {
if caret_tup.0.caret_pos == old_caret_pos {
@ -311,7 +326,7 @@ impl<'a> EdModel<'a> {
if self.grid_node_map.node_exists_at_pos(caret_pos) {
let (expr_start_pos, expr_end_pos, ast_node_id, mark_node_id) = self
.grid_node_map
.get_expr_start_end_pos(self.get_caret(), self)?;
.get_block_start_end_pos(self.get_caret(), self)?;
self.set_selected_expr(expr_start_pos, expr_end_pos, ast_node_id, mark_node_id)?;
} else if self
@ -320,7 +335,7 @@ impl<'a> EdModel<'a> {
{
let (expr_start_pos, expr_end_pos, ast_node_id, mark_node_id) = self
.grid_node_map
.get_expr_start_end_pos(self.get_caret().decrement_col(), self)?;
.get_block_start_end_pos(self.get_caret().decrement_col(), self)?;
self.set_selected_expr(expr_start_pos, expr_end_pos, ast_node_id, mark_node_id)?;
}
@ -686,10 +701,37 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
let ast_node_id = curr_mark_node.get_ast_node_id();
match ast_node_id {
ASTNodeId::ADefId(_) => {
//let def_ref = ed_model.module.env.pool.get(def_id);
ASTNodeId::ADefId(def_id) => {
let def_ref = ed_model.module.env.pool.get(def_id);
unimplemented!("TODO")
match def_ref {
Def2::Blank {..} => {
match ch {
'a'..='z' => {
start_new_tld_value(ed_model, ch)?
},
_ => InputOutcome::Ignored
}
}
Def2::ValueDef { .. } => {
let val_name_mn_id = if curr_mark_node.get_content() == EQUALS {
if let Some(prev_mark_node_id) = prev_mark_node_id_opt {
prev_mark_node_id
} else {
unreachable!()
}
} else {
curr_mark_node_id
};
update_tld_val_name(
val_name_mn_id,
ed_model.get_caret(), // TODO update for multiple carets
ed_model,
ch
)?
},
}
},
ASTNodeId::AExprId(expr_id) => {
let expr_ref = ed_model.module.env.pool.get(expr_id);

View file

@ -128,7 +128,7 @@ pub fn update_let_value(
.grid_node_map
.get_offset_to_node_id(old_caret_pos, val_name_mn_id)?;
if node_caret_offset != 0 && node_caret_offset <= content_str_mut.len() {
if node_caret_offset <= content_str_mut.len() {
content_str_mut.insert(node_caret_offset, *new_char);
// update ast

View file

@ -5,6 +5,7 @@ pub mod ed_update;
pub mod ed_view;
mod int_update;
mod let_update;
pub mod tld_value_update;
mod list_update;
mod lookup_update;
mod record_update;

View file

@ -0,0 +1,165 @@
use roc_module::symbol::{Interns, Symbol};
use crate::{editor::{ed_error::{EdResult, KeyNotFound}, markup::{attribute::Attributes, common_nodes::{new_blank_mn_w_nl, new_equals_mn}, nodes::MarkupNode}, slow_pool::{MarkNodeId, SlowPool}, syntax_highlight::HighlightStyle}, lang::{ast::{Def2, Expr2}, expr::Env, parse::ASTNodeId, pattern::{Pattern2, get_identifier_string}, pool::NodeId}, ui::text::text_pos::TextPos};
use super::{app_update::InputOutcome, ed_model::EdModel, ed_update::{NodeContext, get_node_context}};
// Top Level Defined Value. example: `main = "Hello, World!"`
pub fn tld_mark_node<'a>(
identifier_id: NodeId<Pattern2>,
expr_mark_node_id: MarkNodeId,
ast_node_id: ASTNodeId,
mark_node_pool: &mut SlowPool,
env: &Env<'a>,
interns: &Interns,
) -> EdResult<MarkupNode> {
let pattern2 = env.pool.get(identifier_id);
let val_name = get_identifier_string(pattern2, interns)?;
let val_name_mn = MarkupNode::Text {
content: val_name,
ast_node_id,
syn_high_style: HighlightStyle::Variable,
attributes: Attributes::new(),
parent_id_opt: None,
newline_at_end: false,
};
let val_name_mn_id = mark_node_pool.add(val_name_mn);
let equals_mn_id = mark_node_pool.add(new_equals_mn(ast_node_id, None));
let expr_mn = mark_node_pool.get_mut(expr_mark_node_id);
expr_mn.add_newline_at_end();
let full_let_node = MarkupNode::Nested {
ast_node_id,
children_ids: vec![val_name_mn_id, equals_mn_id, expr_mark_node_id],
parent_id_opt: None,
newline_at_end: true,
};
Ok(
full_let_node
)
}
pub fn start_new_tld_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<InputOutcome> {
let NodeContext {
old_caret_pos,
curr_mark_node_id,
curr_mark_node:_,
parent_id_opt:_,
ast_node_id,
} = get_node_context(ed_model)?;
let val_expr_node = Expr2::Blank;
let val_expr_id = ed_model.module.env.pool.add(val_expr_node);
let val_expr_mn = new_blank_mn_w_nl(ASTNodeId::AExprId(val_expr_id), None);
let val_expr_mn_id = ed_model.mark_node_pool.add(val_expr_mn);
let val_name_string = new_char.to_string();
let ident_id = ed_model
.module
.env
.ident_ids
.add(val_name_string.clone().into());
let module_ident_ids_opt = ed_model.loaded_module.interns.all_ident_ids.get_mut(&ed_model.module.env.home);
if let Some(module_ident_ids_ref) = module_ident_ids_opt {
// this might create different IdentId for interns and env.ident_ids which may be a problem
module_ident_ids_ref.add(val_name_string.clone().into());
} else {
KeyNotFound {
key_str: format!("{:?}", ed_model.module.env.home)
}.fail()?
}
let val_symbol = Symbol::new(ed_model.module.env.home, ident_id);
let patt2 = Pattern2::Identifier(val_symbol);
let patt2_id = ed_model.module.env.pool.add(patt2);
let tld_mark_node = tld_mark_node(
patt2_id,
val_expr_mn_id,
ast_node_id,
&mut ed_model.mark_node_pool,
&ed_model.module.env,
&ed_model.loaded_module.interns
)?;
let new_ast_node =
Def2::ValueDef {
identifier_id: patt2_id,
expr_id: val_expr_id,
};
ed_model.module.env.pool.set(ast_node_id.to_def_id()?, new_ast_node);
ed_model
.mark_node_pool
.replace_node(curr_mark_node_id, tld_mark_node);
// remove data corresponding to old Blank node
ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?;
let char_len = 1;
ed_model.simple_move_carets_right(char_len);
ed_model.insert_all_between_line(
old_caret_pos.line,
old_caret_pos.column,
&ed_model.mark_node_pool.get(curr_mark_node_id).get_children_ids(),
)?;
Ok(InputOutcome::Accepted)
}
pub fn update_tld_val_name(val_name_mn_id: MarkNodeId, old_caret_pos: TextPos, ed_model: &mut EdModel, new_char: &char) -> EdResult<InputOutcome> {
if new_char.is_ascii_alphanumeric() {
// update markup
let val_name_mn_mut = ed_model.mark_node_pool.get_mut(val_name_mn_id);
let content_str_mut = val_name_mn_mut.get_content_mut()?;
let old_val_name = content_str_mut.clone();
let node_caret_offset = ed_model
.grid_node_map
.get_offset_to_node_id(old_caret_pos, val_name_mn_id)?;
if node_caret_offset <= content_str_mut.len() {
content_str_mut.insert(node_caret_offset, *new_char);
// TODO no unwrap
ed_model
.module
.env
.ident_ids
.update_key(&old_val_name, content_str_mut)
.unwrap();
ed_model.insert_between_line(
old_caret_pos.line,
old_caret_pos.column,
&new_char.to_string(),
val_name_mn_id,
)?;
ed_model.simple_move_caret_right(old_caret_pos, 1);
Ok(InputOutcome::Accepted)
} else {
Ok(InputOutcome::Ignored)
}
} else {
Ok(InputOutcome::Ignored)
}
}

View file

@ -1017,14 +1017,12 @@ pub fn to_def2_from_def<'a>(
Body(&loc_pattern, &loc_expr) => {
// TODO loc_pattern use identifier
let expr2 = loc_expr_to_expr2(arena, loc_expr, env, scope, region).0;
dbg!(&expr2);
let expr_id = env.pool.add(expr2);
dbg!(expr_id);
use roc_parse::ast::Pattern::*;
match loc_pattern.value {
Identifier(str_ref) => {
Identifier(_) => {
let (_, pattern2) = to_pattern2(
env,
scope,

View file

@ -32,6 +32,19 @@ impl ASTNodeId {
}
}
}
pub fn to_def_id(&self) -> EdResult<DefId>{
match self {
ASTNodeId::ADefId(def_id) => {
Ok(*def_id)
},
_ => {
ASTNodeIdWithoutExprId {
ast_node_id: *self
}.fail()?
}
}
}
}
#[derive(Debug)]