This commit is contained in:
Anton-4 2021-08-18 18:50:39 +02:00
parent 10b9a7eda8
commit 5ed5e2e6ee
23 changed files with 472 additions and 549 deletions

View file

@ -66,7 +66,6 @@ impl Symbol {
} }
pub fn ident_string(self, interns: &Interns) -> &InlinableString { pub fn ident_string(self, interns: &Interns) -> &InlinableString {
let ident_ids = interns let ident_ids = interns
.all_ident_ids .all_ident_ids
.get(&self.module_id()) .get(&self.module_id())
@ -543,8 +542,11 @@ impl IdentIds {
} }
} }
pub fn update_key(&mut self, old_ident_name: InlinableString, new_ident_name: InlinableString) -> Result<IdentId, String> { pub fn update_key(
&mut self,
old_ident_name: InlinableString,
new_ident_name: InlinableString,
) -> Result<IdentId, String> {
let ident_id_ref_opt = self.by_ident.get(&old_ident_name); let ident_id_ref_opt = self.by_ident.get(&old_ident_name);
match ident_id_ref_opt { match ident_id_ref_opt {

View file

@ -1,11 +1,11 @@
use crate::ast; use crate::ast;
use crate::module::module_defs; use crate::module::module_defs;
// use crate::module::module_defs; // use crate::module::module_defs;
use crate::parser::{State, SyntaxError};
use bumpalo::Bump;
use bumpalo::collections::Vec as BumpVec;
use roc_region::all::Located;
use crate::parser::Parser; use crate::parser::Parser;
use crate::parser::{State, SyntaxError};
use bumpalo::collections::Vec as BumpVec;
use bumpalo::Bump;
use roc_region::all::Located;
pub fn parse_expr_with<'a>( pub fn parse_expr_with<'a>(
arena: &'a Bump, arena: &'a Bump,

View file

@ -46,9 +46,7 @@ pub enum EdError {
#[snafu(display( #[snafu(display(
"EmptyCodeString: I need to have a code string (code_str) that contains either an app, interface or Package-Config header. The code string was empty.", "EmptyCodeString: I need to have a code string (code_str) that contains either an app, interface or Package-Config header. The code string was empty.",
))] ))]
EmptyCodeString { EmptyCodeString { backtrace: Backtrace },
backtrace: Backtrace,
},
#[snafu(display("GetContentOnNestedNode: tried to get string content from Nested MarkupNode. Can only get content from Text or Blank nodes."))] #[snafu(display("GetContentOnNestedNode: tried to get string content from Nested MarkupNode. Can only get content from Text or Blank nodes."))]
GetContentOnNestedNode { backtrace: Backtrace }, GetContentOnNestedNode { backtrace: Backtrace },
@ -172,7 +170,10 @@ pub enum EdError {
}, },
#[snafu(display("ParseError: Failed to parse AST: SyntaxError: {}.", syntax_err))] #[snafu(display("ParseError: Failed to parse AST: SyntaxError: {}.", syntax_err))]
SrcParseError { syntax_err: String, backtrace: Backtrace }, SrcParseError {
syntax_err: String,
backtrace: Backtrace,
},
#[snafu(display("RecordWithoutFields: expected record to have at least one field because it is not an EmptyRecord."))] #[snafu(display("RecordWithoutFields: expected record to have at least one field because it is not an EmptyRecord."))]
RecordWithoutFields { backtrace: Backtrace }, RecordWithoutFields { backtrace: Backtrace },

View file

@ -30,8 +30,8 @@ use roc_load::file::LoadedModule;
use roc_module::symbol::IdentIds; use roc_module::symbol::IdentIds;
use roc_types::subs::VarStore; use roc_types::subs::VarStore;
use std::fs::File; use std::fs::File;
use std::io::Write;
use std::{error::Error, io, path::Path}; use std::{error::Error, io, path::Path};
use std::io::{Write};
use wgpu::{CommandEncoder, RenderPass, TextureView}; use wgpu::{CommandEncoder, RenderPass, TextureView};
use wgpu_glyph::GlyphBrush; use wgpu_glyph::GlyphBrush;
use winit::{ use winit::{
@ -157,13 +157,7 @@ fn run_event_loop(file_path_opt: Option<&Path>) -> Result<(), Box<dyn Error>> {
let ed_model_opt = { let ed_model_opt = {
let ed_model_res = let ed_model_res =
ed_model::init_model( ed_model::init_model(&code_str, file_path, env, loaded_module, &code_arena);
&code_str,
file_path,
env,
loaded_module,
&code_arena,
);
match ed_model_res { match ed_model_res {
Ok(mut ed_model) => { Ok(mut ed_model) => {
@ -403,26 +397,21 @@ fn begin_render_pass<'a>(
} }
fn read_file(file_path_opt: Option<&Path>) -> (&Path, String) { fn read_file(file_path_opt: Option<&Path>) -> (&Path, String) {
if let Some(file_path) = file_path_opt { if let Some(file_path) = file_path_opt {
let file_as_str = std::fs::read_to_string(file_path).expect(&format!(
let file_as_str = "Failed to read from provided file path: {:?}",
std::fs::read_to_string(file_path) file_path
.expect( ));
&format!("Failed to read from provided file path: {:?}", file_path)
);
(file_path, file_as_str) (file_path, file_as_str)
} else { } else {
let untitled_path = Path::new("UntitledApp.roc"); let untitled_path = Path::new("UntitledApp.roc");
let code_str = let code_str = if !untitled_path.exists() {
if !untitled_path.exists() { let mut untitled_file = File::create(untitled_path).expect(&format!(
let mut untitled_file = "I wanted to create {:?}, but it failed.",
File::create(untitled_path) untitled_path
.expect( ));
&format!("I wanted to create {:?}, but it failed.", untitled_path)
);
let hello_world_roc = r#"app "untitled-app" let hello_world_roc = r#"app "untitled-app"
packages { base: "platform" } packages { base: "platform" }
@ -432,27 +421,21 @@ fn read_file(file_path_opt: Option<&Path>) -> (&Path, String) {
main = "Hello, world!" main = "Hello, world!"
"#; "#;
write!(untitled_file, "{}", hello_world_roc) write!(untitled_file, "{}", hello_world_roc).expect(&format!(
.expect(
&format!(
r#"I wanted to write: r#"I wanted to write:
{:?} {:?}
to file {:?}, but it failed."# to file {:?}, but it failed."#,
, hello_world_roc hello_world_roc, untitled_file
, untitled_file ));
)
);
hello_world_roc.to_string() hello_world_roc.to_string()
} else { } else {
std::fs::read_to_string(untitled_path).expect(&format!(
std::fs::read_to_string(untitled_path) "I detected an existing {:?}, but I failed to read from it.",
.expect( untitled_path
&format!("I detected an existing {:?}, but I failed to read from it.", untitled_path) ))
)
}; };
(untitled_path, code_str) (untitled_path, code_str)
@ -467,7 +450,10 @@ pub fn load_module(src_file: &Path) -> LoadedModule {
&arena, &arena,
src_file.to_path_buf(), src_file.to_path_buf(),
arena.alloc(roc_builtins::std::standard_stdlib()), arena.alloc(roc_builtins::std::standard_stdlib()),
src_file.parent().expect(&format!("src_file {:?} did not have a parent directory but I need to have one.", src_file)), src_file.parent().expect(&format!(
"src_file {:?} did not have a parent directory but I need to have one.",
src_file
)),
subs_by_module, subs_by_module,
8, 8,
builtin_defs_map, builtin_defs_map,
@ -476,9 +462,15 @@ pub fn load_module(src_file: &Path) -> LoadedModule {
match loaded { match loaded {
Ok(x) => x, Ok(x) => x,
Err(roc_load::file::LoadingProblem::FormattedReport(report)) => { Err(roc_load::file::LoadingProblem::FormattedReport(report)) => {
panic!("Failed to load module from src_file {:?}. Report: {:?}", src_file,report); panic!(
"Failed to load module from src_file {:?}. Report: {:?}",
src_file, report
);
} }
Err(e) => panic!("Failed to load module from src_file {:?}: {:?}", src_file, e), Err(e) => panic!(
"Failed to load module from src_file {:?}: {:?}",
src_file, e
),
} }
} }

View file

@ -1,7 +1,9 @@
use crate::{editor::{slow_pool::{MarkNodeId}, syntax_highlight::HighlightStyle}, lang::ast::ExprId}; use crate::{
editor::{slow_pool::MarkNodeId, syntax_highlight::HighlightStyle},
use super::{attribute::Attributes, nodes::MarkupNode, nodes}; lang::ast::ExprId,
};
use super::{attribute::Attributes, nodes, nodes::MarkupNode};
pub fn new_equals_mn(ast_node_id: ExprId, parent_id_opt: Option<MarkNodeId>) -> MarkupNode { pub fn new_equals_mn(ast_node_id: ExprId, parent_id_opt: Option<MarkNodeId>) -> MarkupNode {
MarkupNode::Text { MarkupNode::Text {
@ -48,7 +50,7 @@ pub fn new_left_accolade_mn(ast_node_id: ExprId, parent_id_opt: Option<MarkNodeI
ast_node_id, ast_node_id,
syn_high_style: HighlightStyle::Bracket, syn_high_style: HighlightStyle::Bracket,
attributes: Attributes::new(), attributes: Attributes::new(),
parent_id_opt parent_id_opt,
} }
} }
@ -58,7 +60,7 @@ pub fn new_right_accolade_mn(ast_node_id: ExprId, parent_id_opt: Option<MarkNode
ast_node_id, ast_node_id,
syn_high_style: HighlightStyle::Bracket, syn_high_style: HighlightStyle::Bracket,
attributes: Attributes::new(), attributes: Attributes::new(),
parent_id_opt parent_id_opt,
} }
} }
@ -91,4 +93,3 @@ pub fn new_line_mn(ast_node_id: ExprId, parent_id_opt: Option<MarkNodeId>) -> Ma
parent_id_opt, parent_id_opt,
} }
} }

View file

@ -1,3 +1,3 @@
pub mod attribute; pub mod attribute;
pub mod nodes;
pub mod common_nodes; pub mod common_nodes;
pub mod nodes;

View file

@ -187,8 +187,7 @@ impl MarkupNode {
} }
pub fn is_all_alphanumeric(&self) -> bool { pub fn is_all_alphanumeric(&self) -> bool {
self self.get_content()
.get_content()
.chars() .chars()
.all(|chr| chr.is_ascii_alphanumeric()) .all(|chr| chr.is_ascii_alphanumeric())
} }
@ -265,7 +264,6 @@ pub fn expr2_to_markup<'a, 'b>(
markup_node_pool: &mut SlowPool, markup_node_pool: &mut SlowPool,
interns: &Interns, interns: &Interns,
) -> EdResult<MarkNodeId> { ) -> EdResult<MarkNodeId> {
let mark_node_id = match expr2 { let mark_node_id = match expr2 {
Expr2::SmallInt { text, .. } Expr2::SmallInt { text, .. }
| Expr2::I128 { text, .. } | Expr2::I128 { text, .. }
@ -307,14 +305,8 @@ pub fn expr2_to_markup<'a, 'b>(
) )
} }
Expr2::List { elems, .. } => { Expr2::List { elems, .. } => {
let mut children_ids = vec![ let mut children_ids =
markup_node_pool.add( vec![markup_node_pool.add(new_left_square_mn(expr2_node_id, None))];
new_left_square_mn(
expr2_node_id,
None
)
)
];
let indexed_node_ids: Vec<(usize, ExprId)> = let indexed_node_ids: Vec<(usize, ExprId)> =
elems.iter(env.pool).copied().enumerate().collect(); elems.iter(env.pool).copied().enumerate().collect();
@ -328,28 +320,14 @@ pub fn expr2_to_markup<'a, 'b>(
sub_expr2, sub_expr2,
*node_id, *node_id,
markup_node_pool, markup_node_pool,
interns interns,
)?); )?);
if idx + 1 < elems.len() { if idx + 1 < elems.len() {
children_ids.push( children_ids.push(markup_node_pool.add(new_comma_mn(expr2_node_id, None)));
markup_node_pool.add(
new_comma_mn(
expr2_node_id,
None
)
)
);
} }
} }
children_ids.push( children_ids.push(markup_node_pool.add(new_right_square_mn(expr2_node_id, None)));
markup_node_pool.add(
new_right_square_mn(
expr2_node_id,
None
)
)
);
let list_node = MarkupNode::Nested { let list_node = MarkupNode::Nested {
ast_node_id: expr2_node_id, ast_node_id: expr2_node_id,
@ -361,18 +339,8 @@ pub fn expr2_to_markup<'a, 'b>(
} }
Expr2::EmptyRecord => { Expr2::EmptyRecord => {
let children_ids = vec![ let children_ids = vec![
markup_node_pool.add( markup_node_pool.add(new_left_accolade_mn(expr2_node_id, None)),
new_left_accolade_mn( markup_node_pool.add(new_right_accolade_mn(expr2_node_id, None)),
expr2_node_id,
None
)
),
markup_node_pool.add(
new_right_accolade_mn(
expr2_node_id,
None
)
),
]; ];
let record_node = MarkupNode::Nested { let record_node = MarkupNode::Nested {
@ -384,12 +352,8 @@ pub fn expr2_to_markup<'a, 'b>(
markup_node_pool.add(record_node) markup_node_pool.add(record_node)
} }
Expr2::Record { fields, .. } => { Expr2::Record { fields, .. } => {
let mut children_ids = vec![markup_node_pool.add( let mut children_ids =
new_left_accolade_mn( vec![markup_node_pool.add(new_left_accolade_mn(expr2_node_id, None))];
expr2_node_id,
None
)
)];
for (idx, field_node_id) in fields.iter_node_ids().enumerate() { for (idx, field_node_id) in fields.iter_node_ids().enumerate() {
let record_field = env.pool.get(field_node_id); let record_field = env.pool.get(field_node_id);
@ -407,15 +371,7 @@ pub fn expr2_to_markup<'a, 'b>(
RecordField::InvalidLabelOnly(_, _) => (), RecordField::InvalidLabelOnly(_, _) => (),
RecordField::LabelOnly(_, _, _) => (), RecordField::LabelOnly(_, _, _) => (),
RecordField::LabeledValue(_, _, sub_expr2_node_id) => { RecordField::LabeledValue(_, _, sub_expr2_node_id) => {
children_ids.push(markup_node_pool.add(new_colon_mn(expr2_node_id, None)));
children_ids.push(
markup_node_pool.add(
new_colon_mn(
expr2_node_id,
None
)
)
);
let sub_expr2 = env.pool.get(*sub_expr2_node_id); let sub_expr2 = env.pool.get(*sub_expr2_node_id);
children_ids.push(expr2_to_markup( children_ids.push(expr2_to_markup(
@ -424,31 +380,17 @@ pub fn expr2_to_markup<'a, 'b>(
sub_expr2, sub_expr2,
*sub_expr2_node_id, *sub_expr2_node_id,
markup_node_pool, markup_node_pool,
interns interns,
)?); )?);
} }
} }
if idx + 1 < fields.len() { if idx + 1 < fields.len() {
children_ids.push( children_ids.push(markup_node_pool.add(new_comma_mn(expr2_node_id, None)));
markup_node_pool.add(
new_comma_mn(
expr2_node_id,
None
)
)
);
} }
} }
children_ids.push( children_ids.push(markup_node_pool.add(new_right_accolade_mn(expr2_node_id, None)));
markup_node_pool.add(
new_right_accolade_mn(
expr2_node_id,
None
)
)
);
let record_node = MarkupNode::Nested { let record_node = MarkupNode::Nested {
ast_node_id: expr2_node_id, ast_node_id: expr2_node_id,
@ -458,27 +400,22 @@ pub fn expr2_to_markup<'a, 'b>(
markup_node_pool.add(record_node) markup_node_pool.add(record_node)
} }
Expr2::Blank => markup_node_pool.add( Expr2::Blank => markup_node_pool.add(new_blank_mn(expr2_node_id, None)),
new_blank_mn( Expr2::LetValue {
expr2_node_id, def_id,
None body_id: _,
) body_var: _,
), } => {
Expr2::LetValue { def_id, body_id:_, body_var:_} => { let pattern_id = env.pool.get(*def_id).get_pattern_id();
let pattern_id = let pattern2 = env.pool.get(pattern_id);
env.pool.get(*def_id).get_pattern_id();
let pattern2 =
env.pool.get(pattern_id);
//TODO remove me //TODO remove me
/*dbg!(env.pool.get(expr_id)); /*dbg!(env.pool.get(expr_id));
dbg!(env.pool.get(env.pool.get(*def_id).get_pattern_id())); dbg!(env.pool.get(env.pool.get(*def_id).get_pattern_id()));
dbg!(env.pool.get(*body_id));*/ dbg!(env.pool.get(*body_id));*/
let val_name = let val_name = get_identifier_string(pattern2, interns)?;
get_identifier_string(pattern2, interns)?;
let val_name_mn = MarkupNode::Text { let val_name_mn = MarkupNode::Text {
content: val_name, content: val_name,
@ -506,7 +443,7 @@ pub fn expr2_to_markup<'a, 'b>(
env.pool.get(*expr_id), env.pool.get(*expr_id),
*expr_id, *expr_id,
markup_node_pool, markup_node_pool,
interns interns,
)?; )?;
let full_let_node = MarkupNode::Nested { let full_let_node = MarkupNode::Nested {
@ -516,12 +453,15 @@ pub fn expr2_to_markup<'a, 'b>(
}; };
markup_node_pool.add(full_let_node) markup_node_pool.add(full_let_node)
}, }
other => { other => {
unimplemented!("I don't know how to convert {:?} into a MarkupNode yet.", other) unimplemented!(
"I don't know how to convert {:?} into a MarkupNode yet.",
other
)
}
} }
} }
},
Expr2::RuntimeError() => new_markup_node( Expr2::RuntimeError() => new_markup_node(
"RunTimeError".to_string(), "RunTimeError".to_string(),
expr2_node_id, expr2_node_id,
@ -591,7 +531,12 @@ fn header_mn(content: String, ast_node_id: ExprId, mark_node_pool: &mut SlowPool
mark_node_pool.add(mark_node) mark_node_pool.add(mark_node)
} }
fn header_val_mn(content: String, ast_node_id: ExprId, highlight_style: HighlightStyle, mark_node_pool: &mut SlowPool) -> MarkNodeId { fn header_val_mn(
content: String,
ast_node_id: ExprId,
highlight_style: HighlightStyle,
mark_node_pool: &mut SlowPool,
) -> MarkNodeId {
let mark_node = MarkupNode::Text { let mark_node = MarkupNode::Text {
content: content, content: content,
ast_node_id, ast_node_id,
@ -606,15 +551,13 @@ fn header_val_mn(content: String, ast_node_id: ExprId, highlight_style: Highligh
pub fn header_to_markup(app_header: &AppHeader, mark_node_pool: &mut SlowPool) -> MarkNodeId { pub fn header_to_markup(app_header: &AppHeader, mark_node_pool: &mut SlowPool) -> MarkNodeId {
let ast_node_id = app_header.ast_node_id; let ast_node_id = app_header.ast_node_id;
let app_node_id = let app_node_id = header_mn("app ".to_owned(), ast_node_id, mark_node_pool);
header_mn("app ".to_owned(), ast_node_id, mark_node_pool);
let app_name_node_id = let app_name_node_id = header_val_mn(
header_val_mn(
app_header.app_name.clone(), app_header.app_name.clone(),
ast_node_id, ast_node_id,
HighlightStyle::String, HighlightStyle::String,
mark_node_pool mark_node_pool,
); );
let full_app_node = MarkupNode::Nested { let full_app_node = MarkupNode::Nested {
@ -623,119 +566,105 @@ pub fn header_to_markup(app_header: &AppHeader, mark_node_pool: &mut SlowPool) -
parent_id_opt: None, parent_id_opt: None,
}; };
let packages_node_id = let packages_node_id = header_mn(" packages ".to_owned(), ast_node_id, mark_node_pool);
header_mn(" packages ".to_owned(), ast_node_id, mark_node_pool);
let pack_left_acc_node_id = mark_node_pool.add(new_left_accolade_mn(ast_node_id, None)); let pack_left_acc_node_id = mark_node_pool.add(new_left_accolade_mn(ast_node_id, None));
let pack_base_node_id = let pack_base_node_id = header_val_mn(
header_val_mn(
"base: ".to_owned(), "base: ".to_owned(),
ast_node_id, ast_node_id,
HighlightStyle::RecordField, HighlightStyle::RecordField,
mark_node_pool mark_node_pool,
); );
let pack_val_node_id = let pack_val_node_id = header_val_mn(
header_val_mn(
app_header.packages_base.clone(), app_header.packages_base.clone(),
ast_node_id, ast_node_id,
HighlightStyle::String, HighlightStyle::String,
mark_node_pool mark_node_pool,
); );
let pack_right_acc_node_id = mark_node_pool.add(new_right_accolade_mn(ast_node_id, None)); let pack_right_acc_node_id = mark_node_pool.add(new_right_accolade_mn(ast_node_id, None));
let full_packages_node = MarkupNode::Nested { let full_packages_node = MarkupNode::Nested {
ast_node_id, ast_node_id,
children_ids: vec![packages_node_id, pack_left_acc_node_id, pack_base_node_id, pack_val_node_id, pack_right_acc_node_id], children_ids: vec![
packages_node_id,
pack_left_acc_node_id,
pack_base_node_id,
pack_val_node_id,
pack_right_acc_node_id,
],
parent_id_opt: None, parent_id_opt: None,
}; };
let imports_node_id = let imports_node_id = header_mn(" imports ".to_owned(), ast_node_id, mark_node_pool);
header_mn(" imports ".to_owned(), ast_node_id, mark_node_pool);
let imports_left_square_node_id = let imports_left_square_node_id = mark_node_pool.add(new_left_square_mn(ast_node_id, None));
mark_node_pool.add(new_left_square_mn(ast_node_id, None));
let nr_of_imports = app_header.imports.len(); let nr_of_imports = app_header.imports.len();
let mut import_child_ids: Vec<MarkNodeId> = let mut import_child_ids: Vec<MarkNodeId> = app_header
app_header.imports.iter().enumerate().map(|(indx, import)| { .imports
.iter()
let import_val_mn_id = .enumerate()
header_val_mn( .map(|(indx, import)| {
let import_val_mn_id = header_val_mn(
import.to_owned(), import.to_owned(),
ast_node_id, ast_node_id,
HighlightStyle::Import, HighlightStyle::Import,
mark_node_pool mark_node_pool,
); );
if indx != nr_of_imports - 1 { if indx != nr_of_imports - 1 {
vec![ vec![
import_val_mn_id, import_val_mn_id,
mark_node_pool.add(new_comma_mn(ast_node_id, None)) mark_node_pool.add(new_comma_mn(ast_node_id, None)),
] ]
} else { } else {
vec![ vec![import_val_mn_id]
import_val_mn_id
]
} }
}).flatten().collect(); })
.flatten()
.collect();
let imports_right_square_node_id = let imports_right_square_node_id = mark_node_pool.add(new_right_square_mn(ast_node_id, None));
mark_node_pool.add(new_right_square_mn(ast_node_id, None));
let mut full_import_children = vec![imports_node_id, imports_left_square_node_id]; let mut full_import_children = vec![imports_node_id, imports_left_square_node_id];
full_import_children.append(&mut import_child_ids); full_import_children.append(&mut import_child_ids);
full_import_children.push(imports_right_square_node_id); full_import_children.push(imports_right_square_node_id);
let full_import_node = let full_import_node = MarkupNode::Nested {
MarkupNode::Nested {
ast_node_id, ast_node_id,
children_ids: full_import_children, children_ids: full_import_children,
parent_id_opt: None, parent_id_opt: None,
}; };
let provides_node_id = let provides_node_id = header_mn(" provides ".to_owned(), ast_node_id, mark_node_pool);
header_mn(
" provides ".to_owned(),
ast_node_id,
mark_node_pool
);
let provides_left_square_node_id = let provides_left_square_node_id = mark_node_pool.add(new_left_square_mn(ast_node_id, None));
mark_node_pool.add(new_left_square_mn(ast_node_id, None));
let provides_val_node_id = let provides_val_node_id = header_val_mn(
header_val_mn(
// TODO iter over provides like with imports // TODO iter over provides like with imports
app_header.provides.first().unwrap().to_owned(), app_header.provides.first().unwrap().to_owned(),
ast_node_id, ast_node_id,
HighlightStyle::Provides, HighlightStyle::Provides,
mark_node_pool mark_node_pool,
); );
let provides_right_square_node_id = let provides_right_square_node_id = mark_node_pool.add(new_right_square_mn(ast_node_id, None));
mark_node_pool.add(new_right_square_mn(ast_node_id, None));
let provides_end_node_id = let provides_end_node_id = header_mn(" to base".to_owned(), ast_node_id, mark_node_pool);
header_mn(
" to base".to_owned(),
ast_node_id,
mark_node_pool
);
let full_provides_node = let full_provides_node = MarkupNode::Nested {
MarkupNode::Nested {
ast_node_id, ast_node_id,
children_ids: vec![ children_ids: vec![
provides_node_id, provides_node_id,
provides_left_square_node_id, provides_left_square_node_id,
provides_val_node_id, provides_val_node_id,
provides_right_square_node_id, provides_right_square_node_id,
provides_end_node_id provides_end_node_id,
], ],
parent_id_opt: None, parent_id_opt: None,
}; };
@ -750,8 +679,7 @@ pub fn header_to_markup(app_header: &AppHeader, mark_node_pool: &mut SlowPool) -
let newline_node_id_4 = mark_node_pool.add(new_line_mn(ast_node_id, None)); let newline_node_id_4 = mark_node_pool.add(new_line_mn(ast_node_id, None));
let newline_node_id_5 = mark_node_pool.add(new_line_mn(ast_node_id, None)); let newline_node_id_5 = mark_node_pool.add(new_line_mn(ast_node_id, None));
let header_mark_node = let header_mark_node = MarkupNode::Nested {
MarkupNode::Nested {
ast_node_id, ast_node_id,
children_ids: vec![ children_ids: vec![
full_app_node_id, full_app_node_id,
@ -779,13 +707,11 @@ pub fn ast_to_mark_nodes<'a, 'b>(
env: &mut Env<'b>, env: &mut Env<'b>,
ast: &AST, ast: &AST,
mark_node_pool: &mut SlowPool, mark_node_pool: &mut SlowPool,
interns: &Interns,) -> EdResult<Vec<MarkNodeId>> { interns: &Interns,
) -> EdResult<Vec<MarkNodeId>> {
let mut all_mark_node_ids = vec![]; let mut all_mark_node_ids = vec![];
all_mark_node_ids.push( all_mark_node_ids.push(header_to_markup(&ast.header, mark_node_pool));
header_to_markup(&ast.header, mark_node_pool)
);
for &expr_id in ast.expression_ids.iter() { for &expr_id in ast.expression_ids.iter() {
let expr2 = env.pool.get(expr_id); let expr2 = env.pool.get(expr_id);
@ -794,9 +720,7 @@ pub fn ast_to_mark_nodes<'a, 'b>(
set_parent_for_all(expr2_markup_id, mark_node_pool); set_parent_for_all(expr2_markup_id, mark_node_pool);
all_mark_node_ids.push( all_mark_node_ids.push(expr2_markup_id);
expr2_markup_id
);
} }
Ok(all_mark_node_ids) Ok(all_mark_node_ids)
@ -804,12 +728,7 @@ pub fn ast_to_mark_nodes<'a, 'b>(
impl fmt::Display for MarkupNode { impl fmt::Display for MarkupNode {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!( write!(f, "{} ({})", self.node_type_as_string(), self.get_content())
f,
"{} ({})",
self.node_type_as_string(),
self.get_content()
)
} }
} }

View file

@ -4,13 +4,13 @@ use crate::editor::markup::nodes::ast_to_mark_nodes;
use crate::editor::slow_pool::{MarkNodeId, SlowPool}; use crate::editor::slow_pool::{MarkNodeId, SlowPool};
use crate::editor::{ use crate::editor::{
ed_error::SrcParseError, ed_error::SrcParseError,
ed_error::{EdResult, MissingParent, NoNodeAtCaretPosition, EmptyCodeString}, ed_error::{EdResult, EmptyCodeString, MissingParent, NoNodeAtCaretPosition},
}; };
use crate::graphics::primitives::rect::Rect; use crate::graphics::primitives::rect::Rect;
use crate::lang::ast::{Expr2}; use crate::lang::ast::Expr2;
use crate::lang::expr::{Env}; use crate::lang::expr::Env;
use crate::lang::parse::AST; use crate::lang::parse::AST;
use crate::lang::pool::{NodeId}; use crate::lang::pool::NodeId;
use crate::lang::pool::PoolStr; use crate::lang::pool::PoolStr;
use crate::ui::text::caret_w_select::CaretWSelect; use crate::ui::text::caret_w_select::CaretWSelect;
use crate::ui::text::lines::SelectableLines; use crate::ui::text::lines::SelectableLines;
@ -55,26 +55,20 @@ pub fn init_model<'a>(
loaded_module: LoadedModule, loaded_module: LoadedModule,
code_arena: &'a Bump, code_arena: &'a Bump,
) -> EdResult<EdModel<'a>> { ) -> EdResult<EdModel<'a>> {
let mut module = EdModule::new(&code_str, env, &code_arena)?; let mut module = EdModule::new(&code_str, env, &code_arena)?;
let mut markup_node_pool = SlowPool::new(); let mut markup_node_pool = SlowPool::new();
let markup_ids = let markup_ids = if code_str.is_empty() {
if code_str.is_empty() {
EmptyCodeString {}.fail() EmptyCodeString {}.fail()
} else { } else {
ast_to_mark_nodes( ast_to_mark_nodes(
&code_arena, &code_arena,
&mut module.env, &mut module.env,
&module.ast, &module.ast,
&mut markup_node_pool, &mut markup_node_pool,
&loaded_module.interns &loaded_module.interns,
) )
}?; }?;
let code_lines = EdModel::build_code_lines_from_markup(&markup_ids, &markup_node_pool)?; let code_lines = EdModel::build_code_lines_from_markup(&markup_ids, &markup_node_pool)?;
@ -160,23 +154,15 @@ pub struct EdModule<'a> {
impl<'a> EdModule<'a> { impl<'a> EdModule<'a> {
pub fn new(code_str: &'a str, mut env: Env<'a>, ast_arena: &'a Bump) -> EdResult<EdModule<'a>> { pub fn new(code_str: &'a str, mut env: Env<'a>, ast_arena: &'a Bump) -> EdResult<EdModule<'a>> {
if !code_str.is_empty() { if !code_str.is_empty() {
let parse_res = AST::parse_from_string(code_str, &mut env, ast_arena); let parse_res = AST::parse_from_string(code_str, &mut env, ast_arena);
match parse_res { match parse_res {
Ok(ast) => { Ok(ast) => Ok(EdModule { env, ast }),
Ok(
EdModule {
env,
ast,
}
)
},
Err(err) => SrcParseError { Err(err) => SrcParseError {
syntax_err: format!("{:?}", err), syntax_err: format!("{:?}", err),
}.fail()
} }
.fail(),
}
} else { } else {
EmptyCodeString {}.fail() EmptyCodeString {}.fail()
} }
@ -200,12 +186,12 @@ pub mod test_ed_model {
use roc_module::symbol::IdentIds; use roc_module::symbol::IdentIds;
use roc_module::symbol::ModuleIds; use roc_module::symbol::ModuleIds;
use roc_types::subs::VarStore; use roc_types::subs::VarStore;
use tempfile::tempdir;
use uuid::Uuid;
use std::fs::File; use std::fs::File;
use std::io::Write;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::io::Write; use tempfile::tempdir;
use uuid::Uuid;
pub fn init_dummy_model<'a>( pub fn init_dummy_model<'a>(
code_str: &'a str, code_str: &'a str,
@ -229,13 +215,7 @@ pub mod test_ed_model {
exposed_ident_ids, exposed_ident_ids,
); );
ed_model::init_model( ed_model::init_model(code_str, file_path, env, loaded_module, code_arena)
code_str,
file_path,
env,
loaded_module,
code_arena,
)
} }
pub struct EdModelRefs { pub struct EdModelRefs {
@ -274,24 +254,22 @@ main = "Hello, world!"
*clean_code_str = [header_str, clean_code_str.as_str()].join(""); *clean_code_str = [header_str, clean_code_str.as_str()].join("");
let temp_dir = tempdir().expect("Failed to create temporary directory for test."); let temp_dir = tempdir().expect("Failed to create temporary directory for test.");
let temp_file_path_buf = PathBuf::from( let temp_file_path_buf =
[Uuid::new_v4().to_string(), ".roc".to_string()].join("") PathBuf::from([Uuid::new_v4().to_string(), ".roc".to_string()].join(""));
);
let temp_file_full_path = temp_dir.path().join(temp_file_path_buf); let temp_file_full_path = temp_dir.path().join(temp_file_path_buf);
let mut file = File::create(temp_file_full_path.clone()) let mut file = File::create(temp_file_full_path.clone()).expect(&format!(
.expect( "Failed to create temporary file for path {:?}",
&format!("Failed to create temporary file for path {:?}", temp_file_full_path) temp_file_full_path
); ));
writeln!(file, "{}", clean_code_str) writeln!(file, "{}", clean_code_str).expect(&format!(
.expect( "Failed to write {:?} to file: {:?}",
&format!("Failed to write {:?} to file: {:?}", clean_code_str, file) clean_code_str, file
); ));
let loaded_module = load_module(&temp_file_full_path); let loaded_module = load_module(&temp_file_full_path);
let mut ed_model = let mut ed_model = init_dummy_model(
init_dummy_model(
clean_code_str, clean_code_str,
loaded_module, loaded_module,
module_ids, module_ids,

View file

@ -96,12 +96,16 @@ impl<'a> EdModel<'a> {
markup_ids: &[MarkNodeId], markup_ids: &[MarkNodeId],
markup_node_pool: &SlowPool, markup_node_pool: &SlowPool,
) -> EdResult<GridNodeMap> { ) -> EdResult<GridNodeMap> {
let mut grid_node_map = GridNodeMap::new(); let mut grid_node_map = GridNodeMap::new();
let mut line_ctr = 0; let mut line_ctr = 0;
for mark_id in markup_ids.iter() { for mark_id in markup_ids.iter() {
EdModel::build_grid_node_map(*mark_id, &mut grid_node_map, &mut line_ctr, markup_node_pool)?; EdModel::build_grid_node_map(
*mark_id,
&mut grid_node_map,
&mut line_ctr,
markup_node_pool,
)?;
} }
Ok(grid_node_map) Ok(grid_node_map)
@ -191,16 +195,20 @@ impl<'a> EdModel<'a> {
index: usize, index: usize,
node_ids: &[MarkNodeId], node_ids: &[MarkNodeId],
) -> UIResult<()> { ) -> UIResult<()> {
let mut col_nr = index; let mut col_nr = index;
for &node_id in node_ids { for &node_id in node_ids {
let node_content_str = self.markup_node_pool.get(node_id).get_content(); let node_content_str = self.markup_node_pool.get(node_id).get_content();
self.grid_node_map self.grid_node_map.insert_between_line(
.insert_between_line(line_nr, col_nr, node_content_str.len(), node_id)?; line_nr,
col_nr,
node_content_str.len(),
node_id,
)?;
self.code_lines.insert_between_line(line_nr, col_nr, &node_content_str)?; self.code_lines
.insert_between_line(line_nr, col_nr, &node_content_str)?;
col_nr += node_content_str.len(); col_nr += node_content_str.len();
} }
@ -317,7 +325,12 @@ impl<'a> EdModel<'a> {
let content = subs.get(var).content; let content = subs.get(var).content;
PoolStr::new( PoolStr::new(
&content_to_string(content, &subs, self.module.env.home, &self.loaded_module.interns), &content_to_string(
content,
&subs,
self.module.env.home,
&self.loaded_module.interns,
),
self.module.env.pool, self.module.env.pool,
) )
} }
@ -931,14 +944,19 @@ pub mod test_ed_update {
expected_post_lines: &[&str], expected_post_lines: &[&str],
new_char_seq: &str, new_char_seq: &str,
) -> Result<(), String> { ) -> Result<(), String> {
let mut code_str = pre_lines.join("\n").replace("", ""); let mut code_str = pre_lines.join("\n").replace("", "");
let mut model_refs = init_model_refs(); let mut model_refs = init_model_refs();
let code_arena = Bump::new(); let code_arena = Bump::new();
let module_ids = ModuleIds::default(); let module_ids = ModuleIds::default();
let mut ed_model = ed_model_from_dsl(&mut code_str, pre_lines, &mut model_refs, &module_ids, &code_arena)?; let mut ed_model = ed_model_from_dsl(
&mut code_str,
pre_lines,
&mut model_refs,
&module_ids,
&code_arena,
)?;
for input_char in new_char_seq.chars() { for input_char in new_char_seq.chars() {
if input_char == '🡲' { if input_char == '🡲' {
@ -1822,14 +1840,19 @@ pub mod test_ed_update {
expected_post_lines: &[&str], expected_post_lines: &[&str],
repeats: usize, repeats: usize,
) -> Result<(), String> { ) -> Result<(), String> {
let mut code_str = pre_lines.join("").replace("", ""); let mut code_str = pre_lines.join("").replace("", "");
let mut model_refs = init_model_refs(); let mut model_refs = init_model_refs();
let code_arena = Bump::new(); let code_arena = Bump::new();
let module_ids = ModuleIds::default(); let module_ids = ModuleIds::default();
let mut ed_model = ed_model_from_dsl(&mut code_str, pre_lines, &mut model_refs, &module_ids, &code_arena)?; let mut ed_model = ed_model_from_dsl(
&mut code_str,
pre_lines,
&mut model_refs,
&module_ids,
&code_arena,
)?;
for _ in 0..repeats { for _ in 0..repeats {
ed_model.ed_handle_key_down(&ctrl_cmd_shift(), Up)?; ed_model.ed_handle_key_down(&ctrl_cmd_shift(), Up)?;
@ -2082,14 +2105,19 @@ pub mod test_ed_update {
expected_tooltips: &[&str], expected_tooltips: &[&str],
new_char_seq: &str, new_char_seq: &str,
) -> Result<(), String> { ) -> Result<(), String> {
let mut code_str = pre_lines.join("").replace("", ""); let mut code_str = pre_lines.join("").replace("", "");
let mut model_refs = init_model_refs(); let mut model_refs = init_model_refs();
let code_arena = Bump::new(); let code_arena = Bump::new();
let module_ids = ModuleIds::default(); let module_ids = ModuleIds::default();
let mut ed_model = ed_model_from_dsl(&mut code_str, pre_lines, &mut model_refs, &module_ids, &code_arena)?; let mut ed_model = ed_model_from_dsl(
&mut code_str,
pre_lines,
&mut model_refs,
&module_ids,
&code_arena,
)?;
for input_char in new_char_seq.chars() { for input_char in new_char_seq.chars() {
if input_char == '🡲' { if input_char == '🡲' {
@ -2244,7 +2272,13 @@ pub mod test_ed_update {
let code_arena = Bump::new(); let code_arena = Bump::new();
let module_ids = ModuleIds::default(); let module_ids = ModuleIds::default();
let mut ed_model = ed_model_from_dsl(&mut code_str, pre_lines, &mut model_refs, &module_ids, &code_arena)?; let mut ed_model = ed_model_from_dsl(
&mut code_str,
pre_lines,
&mut model_refs,
&module_ids,
&code_arena,
)?;
for _ in 0..repeats { for _ in 0..repeats {
ed_model.ed_handle_key_down(&ctrl_cmd_shift(), Up)?; ed_model.ed_handle_key_down(&ctrl_cmd_shift(), Up)?;
@ -2374,7 +2408,13 @@ pub mod test_ed_update {
let code_arena = Bump::new(); let code_arena = Bump::new();
let module_ids = ModuleIds::default(); let module_ids = ModuleIds::default();
let mut ed_model = ed_model_from_dsl(&mut code_str, pre_lines, &mut model_refs, &module_ids, &code_arena)?; let mut ed_model = ed_model_from_dsl(
&mut code_str,
pre_lines,
&mut model_refs,
&module_ids,
&code_arena,
)?;
for _ in 0..repeats { for _ in 0..repeats {
ed_model.ed_handle_key_down(&ctrl_cmd_shift(), Up)?; ed_model.ed_handle_key_down(&ctrl_cmd_shift(), Up)?;

View file

@ -1,7 +1,7 @@
use inlinable_string::InlinableString; use inlinable_string::InlinableString;
use roc_module::symbol::Symbol; use roc_module::symbol::Symbol;
use crate::editor::ed_error::{EdResult}; use crate::editor::ed_error::EdResult;
use crate::editor::markup::attribute::Attributes; use crate::editor::markup::attribute::Attributes;
use crate::editor::markup::common_nodes::new_blank_mn; use crate::editor::markup::common_nodes::new_blank_mn;
use crate::editor::markup::common_nodes::new_equals_mn; use crate::editor::markup::common_nodes::new_equals_mn;
@ -18,7 +18,6 @@ use crate::lang::pool::NodeId;
use crate::ui::text::lines::SelectableLines; use crate::ui::text::lines::SelectableLines;
use std::iter::FromIterator; use std::iter::FromIterator;
pub fn start_new_let_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<InputOutcome> { pub fn start_new_let_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<InputOutcome> {
let NodeContext { let NodeContext {
old_caret_pos, old_caret_pos,
@ -44,11 +43,10 @@ pub fn start_new_let_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<
let pattern = Pattern2::Identifier(var_symbol); let pattern = Pattern2::Identifier(var_symbol);
let pattern_id = ed_model.module.env.pool.add(pattern); let pattern_id = ed_model.module.env.pool.add(pattern);
let value_def = let value_def = ValueDef::NoAnnotation {
ValueDef::NoAnnotation {
pattern_id, pattern_id,
expr_id: val_expr_id, expr_id: val_expr_id,
expr_var: ed_model.module.env.var_store.fresh() expr_var: ed_model.module.env.var_store.fresh(),
}; };
let def_id = ed_model.module.env.pool.add(value_def); let def_id = ed_model.module.env.pool.add(value_def);
@ -104,7 +102,13 @@ pub fn start_new_let_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<
} }
} }
pub fn update_let_value(val_name_mn_id: MarkNodeId, def_id: NodeId<ValueDef>, body_id: NodeId<Expr2>, ed_model: &mut EdModel, new_char: &char) -> EdResult<InputOutcome> { pub fn update_let_value(
val_name_mn_id: MarkNodeId,
def_id: NodeId<ValueDef>,
body_id: NodeId<Expr2>,
ed_model: &mut EdModel,
new_char: &char,
) -> EdResult<InputOutcome> {
if new_char.is_ascii_alphanumeric() { if new_char.is_ascii_alphanumeric() {
let old_caret_pos = ed_model.get_caret(); let old_caret_pos = ed_model.get_caret();
@ -128,13 +132,26 @@ pub fn update_let_value(val_name_mn_id: MarkNodeId, def_id: NodeId<ValueDef>, bo
let ident_string = InlinableString::from_iter(content_str_mut.chars()); let ident_string = InlinableString::from_iter(content_str_mut.chars());
// TODO no unwrap // TODO no unwrap
let ident_id = ed_model.module.env.ident_ids.update_key(old_val_ident_string, ident_string).unwrap(); let ident_id = ed_model
.module
.env
.ident_ids
.update_key(old_val_ident_string, ident_string)
.unwrap();
let new_var_symbol = Symbol::new(ed_model.module.env.home, ident_id); let new_var_symbol = Symbol::new(ed_model.module.env.home, ident_id);
ed_model.module.env.pool.set(value_ident_pattern_id, Pattern2::Identifier(new_var_symbol)); ed_model
.module
.env
.pool
.set(value_ident_pattern_id, Pattern2::Identifier(new_var_symbol));
ed_model.module.env.pool.set(body_id, Expr2::Var(new_var_symbol)); ed_model
.module
.env
.pool
.set(body_id, Expr2::Var(new_var_symbol));
// update GridNodeMap and CodeLines // update GridNodeMap and CodeLines
ed_model.insert_between_line( ed_model.insert_between_line(
@ -151,7 +168,6 @@ pub fn update_let_value(val_name_mn_id: MarkNodeId, def_id: NodeId<ValueDef>, bo
} else { } else {
Ok(InputOutcome::Ignored) Ok(InputOutcome::Ignored)
} }
} else { } else {
Ok(InputOutcome::Ignored) Ok(InputOutcome::Ignored)
} }

View file

@ -1,6 +1,8 @@
use crate::editor::ed_error::EdResult; use crate::editor::ed_error::EdResult;
use crate::editor::ed_error::{MissingParent, UnexpectedASTNode}; use crate::editor::ed_error::{MissingParent, UnexpectedASTNode};
use crate::editor::markup::common_nodes::{new_blank_mn, new_comma_mn, new_left_square_mn, new_right_square_mn}; use crate::editor::markup::common_nodes::{
new_blank_mn, new_comma_mn, new_left_square_mn, new_right_square_mn,
};
use crate::editor::markup::nodes; use crate::editor::markup::nodes;
use crate::editor::markup::nodes::MarkupNode; use crate::editor::markup::nodes::MarkupNode;
use crate::editor::mvc::app_update::InputOutcome; use crate::editor::mvc::app_update::InputOutcome;
@ -32,14 +34,10 @@ pub fn start_new_list(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
ed_model.module.env.pool.set(ast_node_id, expr2_node); ed_model.module.env.pool.set(ast_node_id, expr2_node);
let left_bracket_node_id = let left_bracket_node_id =
ed_model.add_mark_node( ed_model.add_mark_node(new_left_square_mn(ast_node_id, Some(curr_mark_node_id)));
new_left_square_mn(ast_node_id, Some(curr_mark_node_id))
);
let right_bracket_node_id = let right_bracket_node_id =
ed_model.add_mark_node( ed_model.add_mark_node(new_right_square_mn(ast_node_id, Some(curr_mark_node_id)));
new_right_square_mn(ast_node_id, Some(curr_mark_node_id))
);
let nested_node = MarkupNode::Nested { let nested_node = MarkupNode::Nested {
ast_node_id, ast_node_id,
@ -48,7 +46,9 @@ pub fn start_new_list(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
}; };
if is_blank_node { if is_blank_node {
ed_model.markup_node_pool.replace_node(curr_mark_node_id, nested_node); ed_model
.markup_node_pool
.replace_node(curr_mark_node_id, nested_node);
// remove data corresponding to Blank node // remove data corresponding to Blank node
ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?; ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?;
@ -178,23 +178,13 @@ pub fn update_mark_children(
parent_id_opt: Option<MarkNodeId>, parent_id_opt: Option<MarkNodeId>,
ed_model: &mut EdModel, ed_model: &mut EdModel,
) -> EdResult<Vec<MarkNodeId>> { ) -> EdResult<Vec<MarkNodeId>> {
let blank_mark_node_id = ed_model.add_mark_node(new_blank_mn(blank_elt_id, parent_id_opt));
let blank_mark_node_id =
ed_model
.add_mark_node(
new_blank_mn(blank_elt_id, parent_id_opt)
);
let mut children: Vec<MarkNodeId> = vec![]; let mut children: Vec<MarkNodeId> = vec![];
if new_child_index > 1 { if new_child_index > 1 {
let comma_mark_node_id = let comma_mark_node_id =
ed_model ed_model.add_mark_node(new_comma_mn(list_ast_node_id, parent_id_opt));
.add_mark_node(
new_comma_mn(list_ast_node_id, parent_id_opt)
);
ed_model.simple_move_carets_right(nodes::COMMA.len()); ed_model.simple_move_carets_right(nodes::COMMA.len());

View file

@ -4,8 +4,8 @@ pub mod ed_model;
pub mod ed_update; pub mod ed_update;
pub mod ed_view; pub mod ed_view;
mod int_update; mod int_update;
mod list_update;
mod let_update; mod let_update;
mod list_update;
mod lookup_update; mod lookup_update;
mod record_update; mod record_update;
mod string_update; mod string_update;

View file

@ -37,14 +37,10 @@ pub fn start_new_record(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
ast_pool.set(ast_node_id, expr2_node); ast_pool.set(ast_node_id, expr2_node);
let left_bracket_node_id = let left_bracket_node_id =
ed_model.add_mark_node( ed_model.add_mark_node(new_left_accolade_mn(ast_node_id, Some(curr_mark_node_id)));
new_left_accolade_mn(ast_node_id, Some(curr_mark_node_id))
);
let right_bracket_node_id = let right_bracket_node_id =
ed_model.add_mark_node( ed_model.add_mark_node(new_right_accolade_mn(ast_node_id, Some(curr_mark_node_id)));
new_right_accolade_mn(ast_node_id, Some(curr_mark_node_id))
);
let nested_node = MarkupNode::Nested { let nested_node = MarkupNode::Nested {
ast_node_id, ast_node_id,
@ -53,7 +49,9 @@ pub fn start_new_record(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
}; };
if is_blank_node { if is_blank_node {
ed_model.markup_node_pool.replace_node(curr_mark_node_id, nested_node); ed_model
.markup_node_pool
.replace_node(curr_mark_node_id, nested_node);
// remove data corresponding to Blank node // remove data corresponding to Blank node
ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?; ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?;
@ -64,7 +62,7 @@ pub fn start_new_record(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
ed_model.insert_all_between_line( ed_model.insert_all_between_line(
old_caret_pos.line, old_caret_pos.line,
old_caret_pos.column, old_caret_pos.column,
&vec![left_bracket_node_id, right_bracket_node_id] &vec![left_bracket_node_id, right_bracket_node_id],
)?; )?;
Ok(InputOutcome::Accepted) Ok(InputOutcome::Accepted)
@ -232,11 +230,8 @@ pub fn update_record_colon(
.get_mut(parent_id) .get_mut(parent_id)
.add_child_at_index(new_child_index, record_colon_node_id)?; .add_child_at_index(new_child_index, record_colon_node_id)?;
let record_blank_node_id = let record_blank_node_id = ed_model
ed_model .add_mark_node(new_blank_mn(new_field_val_id, Some(parent_id)));
.add_mark_node(
new_blank_mn(new_field_val_id, Some(parent_id))
);
ed_model ed_model
.markup_node_pool .markup_node_pool

View file

@ -7,9 +7,9 @@ use crate::editor::mvc::ed_model::EdModel;
use crate::editor::mvc::ed_update::get_node_context; use crate::editor::mvc::ed_update::get_node_context;
use crate::editor::mvc::ed_update::NodeContext; use crate::editor::mvc::ed_update::NodeContext;
use crate::editor::syntax_highlight::HighlightStyle; use crate::editor::syntax_highlight::HighlightStyle;
use crate::lang::ast::update_str_expr;
use crate::lang::ast::ArrString; use crate::lang::ast::ArrString;
use crate::lang::ast::Expr2; use crate::lang::ast::Expr2;
use crate::lang::ast::update_str_expr;
use crate::lang::pool::PoolStr; use crate::lang::pool::PoolStr;
pub fn update_small_string( pub fn update_small_string(
@ -74,10 +74,7 @@ pub fn update_small_string(
} }
} }
pub fn update_string( pub fn update_string(new_char: char, ed_model: &mut EdModel) -> EdResult<InputOutcome> {
new_char: char,
ed_model: &mut EdModel,
) -> EdResult<InputOutcome> {
let NodeContext { let NodeContext {
old_caret_pos, old_caret_pos,
curr_mark_node_id, curr_mark_node_id,
@ -105,7 +102,12 @@ pub fn update_string(
)?; )?;
// update ast // update ast
update_str_expr(ast_node_id, new_char, node_caret_offset, &mut ed_model.module.env.pool)?; update_str_expr(
ast_node_id,
new_char,
node_caret_offset,
&mut ed_model.module.env.pool,
)?;
// update caret // update caret
ed_model.simple_move_carets_right(1); ed_model.simple_move_carets_right(1);

View file

@ -32,20 +32,12 @@ pub fn build_debug_graphics(
let mut mark_node_trees_string = "\nmark node trees:".to_owned(); let mut mark_node_trees_string = "\nmark node trees:".to_owned();
for mark_id in ed_model.markup_ids.iter() { for mark_id in ed_model.markup_ids.iter() {
mark_node_trees_string.push_str(&tree_as_string(*mark_id, &ed_model.markup_node_pool));
mark_node_trees_string.push_str(
&tree_as_string(
*mark_id,
&ed_model.markup_node_pool,
)
);
mark_node_trees_string.push_str("\n"); mark_node_trees_string.push_str("\n");
} }
let mark_node_tree_text = glyph_brush::OwnedText::new( let mark_node_tree_text = glyph_brush::OwnedText::new(mark_node_trees_string)
mark_node_trees_string
)
.with_color(colors::to_slice(from_hsb(266, 31, 96))) .with_color(colors::to_slice(from_hsb(266, 31, 96)))
.with_scale(config.code_font_size); .with_scale(config.code_font_size);
@ -53,18 +45,13 @@ pub fn build_debug_graphics(
.with_color(colors::to_slice(from_hsb(110, 45, 82))) .with_color(colors::to_slice(from_hsb(110, 45, 82)))
.with_scale(config.code_font_size); .with_scale(config.code_font_size);
let mut ast_node_text_str = "AST:\n".to_owned(); let mut ast_node_text_str = "AST:\n".to_owned();
for expr_id in ed_model.module.ast.expression_ids.iter() { for expr_id in ed_model.module.ast.expression_ids.iter() {
ast_node_text_str.push_str( ast_node_text_str.push_str(&expr2_to_string(*expr_id, ed_model.module.env.pool))
&expr2_to_string(*expr_id, ed_model.module.env.pool)
)
} }
let ast_node_text = glyph_brush::OwnedText::new( let ast_node_text = glyph_brush::OwnedText::new(ast_node_text_str)
ast_node_text_str
)
.with_color(colors::to_slice(from_hsb(211, 80, 100))) .with_color(colors::to_slice(from_hsb(211, 80, 100)))
.with_scale(config.code_font_size); .with_scale(config.code_font_size);

View file

@ -3,11 +3,11 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::hash::BuildHasherDefault; use std::hash::BuildHasherDefault;
use crate::editor::ed_error::{EdResult, UnexpectedASTNode};
use crate::lang::pattern::{Pattern2, PatternId}; use crate::lang::pattern::{Pattern2, PatternId};
use crate::lang::pool::Pool; use crate::lang::pool::Pool;
use crate::lang::pool::{NodeId, PoolStr, PoolVec, ShallowClone}; use crate::lang::pool::{NodeId, PoolStr, PoolVec, ShallowClone};
use crate::lang::types::{Type2, TypeId}; use crate::lang::types::{Type2, TypeId};
use crate::editor::ed_error::{EdResult, UnexpectedASTNode};
use arraystring::{typenum::U30, ArrayString}; use arraystring::{typenum::U30, ArrayString};
use roc_can::expr::Recursive; use roc_can::expr::Recursive;
use roc_collections::all::WyHash; use roc_collections::all::WyHash;
@ -564,8 +564,13 @@ fn expr2_to_string_helper(
Expr2::SmallInt { text, .. } => { Expr2::SmallInt { text, .. } => {
out_string.push_str(&format!("SmallInt({})", text.as_str(pool))); out_string.push_str(&format!("SmallInt({})", text.as_str(pool)));
} }
Expr2::LetValue {def_id, body_id, .. } => { Expr2::LetValue {
out_string.push_str(&format!("LetValue(def_id: {}, body_id: {})", def_id.index, body_id.index)); def_id, body_id, ..
} => {
out_string.push_str(&format!(
"LetValue(def_id: {}, body_id: {})",
def_id.index, body_id.index
));
} }
other => todo!("Implement for {:?}", other), other => todo!("Implement for {:?}", other),
} }
@ -580,26 +585,22 @@ fn var_to_string(some_var: &Variable, indent_level: usize) -> String {
// get string from SmallStr or Str // get string from SmallStr or Str
pub fn get_string_from_expr2(node_id: ExprId, pool: &Pool) -> EdResult<String> { pub fn get_string_from_expr2(node_id: ExprId, pool: &Pool) -> EdResult<String> {
match pool.get(node_id) { match pool.get(node_id) {
Expr2::SmallStr(arr_string) => { Expr2::SmallStr(arr_string) => Ok(arr_string.as_str().to_string()),
Ok( Expr2::Str(pool_str) => Ok(pool_str.as_str(pool).to_owned()),
arr_string.as_str().to_string() other => UnexpectedASTNode {
)
},
Expr2::Str(pool_str) => {
Ok(
pool_str.as_str(pool).to_owned()
)
}
other => {
UnexpectedASTNode{
required_node_type: "SmallStr or Str", required_node_type: "SmallStr or Str",
encountered_node_type: format!("{:?}", other) encountered_node_type: format!("{:?}", other),
}.fail()?
} }
.fail()?,
} }
} }
pub fn update_str_expr(node_id: ExprId, new_char: char, insert_index: usize, pool: &mut Pool) -> EdResult<()> { pub fn update_str_expr(
node_id: ExprId,
new_char: char,
insert_index: usize,
pool: &mut Pool,
) -> EdResult<()> {
let str_expr = pool.get_mut(node_id); let str_expr = pool.get_mut(node_id);
enum Either { enum Either {
@ -610,8 +611,7 @@ pub fn update_str_expr(node_id: ExprId, new_char: char, insert_index: usize, poo
let insert_either = match str_expr { let insert_either = match str_expr {
Expr2::SmallStr(arr_string) => { Expr2::SmallStr(arr_string) => {
let insert_res = let insert_res = arr_string.try_insert(insert_index as u8, new_char);
arr_string.try_insert(insert_index as u8, new_char);
match insert_res { match insert_res {
Ok(_) => Either::Done, Ok(_) => Either::Done,
@ -622,16 +622,13 @@ pub fn update_str_expr(node_id: ExprId, new_char: char, insert_index: usize, poo
Either::MyString(new_string) Either::MyString(new_string)
} }
} }
},
Expr2::Str(old_pool_str) => {
Either::MyPoolStr(*old_pool_str)
},
other => {
UnexpectedASTNode{
required_node_type: "SmallStr or Str",
encountered_node_type: format!("{:?}", other)
}.fail()?
} }
Expr2::Str(old_pool_str) => Either::MyPoolStr(*old_pool_str),
other => UnexpectedASTNode {
required_node_type: "SmallStr or Str",
encountered_node_type: format!("{:?}", other),
}
.fail()?,
}; };
match insert_either { match insert_either {
@ -639,7 +636,7 @@ pub fn update_str_expr(node_id: ExprId, new_char: char, insert_index: usize, poo
let new_pool_str = PoolStr::new(&new_string, pool); let new_pool_str = PoolStr::new(&new_string, pool);
pool.set(node_id, Expr2::Str(new_pool_str)) pool.set(node_id, Expr2::Str(new_pool_str))
}, }
Either::MyPoolStr(old_pool_str) => { Either::MyPoolStr(old_pool_str) => {
let mut new_string = old_pool_str.as_str(pool).to_owned(); let mut new_string = old_pool_str.as_str(pool).to_owned();
new_string.insert(insert_index, new_char); new_string.insert(insert_index, new_char);
@ -647,7 +644,7 @@ pub fn update_str_expr(node_id: ExprId, new_char: char, insert_index: usize, poo
let new_pool_str = PoolStr::new(&new_string, pool); let new_pool_str = PoolStr::new(&new_string, pool);
pool.set(node_id, Expr2::Str(new_pool_str)) pool.set(node_id, Expr2::Str(new_pool_str))
}, }
Either::Done => (), Either::Done => (),
} }

View file

@ -6,7 +6,10 @@ use inlinable_string::InlinableString;
use std::collections::HashMap; use std::collections::HashMap;
use std::iter::FromIterator; use std::iter::FromIterator;
use crate::lang::ast::{ClosureExtra, Expr2, ExprId, FloatVal, IntStyle, IntVal, RecordField, ValueDef, WhenBranch, expr2_to_string}; use crate::lang::ast::{
expr2_to_string, ClosureExtra, Expr2, ExprId, FloatVal, IntStyle, IntVal, RecordField,
ValueDef, WhenBranch,
};
use crate::lang::def::{ use crate::lang::def::{
canonicalize_defs, sort_can_defs, CanDefs, Declaration, Def, PendingDef, References, canonicalize_defs, sort_can_defs, CanDefs, Declaration, Def, PendingDef, References,
}; };
@ -296,16 +299,13 @@ pub fn str_to_expr2_w_defs<'a>(
region: Region, region: Region,
) -> Result<Vec<Expr2>, SyntaxError<'a>> { ) -> Result<Vec<Expr2>, SyntaxError<'a>> {
match roc_parse::test_helpers::parse_defs_with(arena, input.trim()) { match roc_parse::test_helpers::parse_defs_with(arena, input.trim()) {
Ok(vec_loc_def) => { Ok(vec_loc_def) => Ok(to_expr2_from_defs(
Ok(to_expr2_from_defs(
arena, arena,
env, env,
scope, scope,
arena.alloc(vec_loc_def), arena.alloc(vec_loc_def),
region, region,
)) )),
}
Err(fail) => Err(fail), Err(fail) => Err(fail),
} }
} }
@ -318,9 +318,7 @@ pub fn str_to_expr2<'a>(
region: Region, region: Region,
) -> Result<(Expr2, self::Output), SyntaxError<'a>> { ) -> Result<(Expr2, self::Output), SyntaxError<'a>> {
match roc_parse::test_helpers::parse_loc_with(arena, input.trim()) { match roc_parse::test_helpers::parse_loc_with(arena, input.trim()) {
Ok(loc_expr) => { Ok(loc_expr) => Ok(loc_expr_to_expr2(arena, loc_expr, env, scope, region)),
Ok(loc_expr_to_expr2(arena, loc_expr, env, scope, region))
}
Err(fail) => Err(fail), Err(fail) => Err(fail),
} }
} }
@ -334,12 +332,7 @@ fn loc_expr_to_expr2<'a>(
) -> (Expr2, self::Output) { ) -> (Expr2, self::Output) {
let desugared_loc_expr = desugar_expr(arena, arena.alloc(loc_expr)); let desugared_loc_expr = desugar_expr(arena, arena.alloc(loc_expr));
to_expr2( to_expr2(env, scope, arena.alloc(desugared_loc_expr.value), region)
env,
scope,
arena.alloc(desugared_loc_expr.value),
region,
)
} }
pub fn to_expr2<'a>( pub fn to_expr2<'a>(
@ -1009,10 +1002,10 @@ pub fn to_expr2_from_defs<'a>(
) -> Vec<Expr2> { ) -> Vec<Expr2> {
use roc_parse::ast::Expr::*; use roc_parse::ast::Expr::*;
parsed_defs.iter().map(|loc| { parsed_defs
to_expr2_from_def(arena, env, scope, &loc.value, region) .iter()
}).collect() .map(|loc| to_expr2_from_def(arena, env, scope, &loc.value, region))
.collect()
} }
pub fn to_expr2_from_def<'a>( pub fn to_expr2_from_def<'a>(
@ -1025,12 +1018,8 @@ pub fn to_expr2_from_def<'a>(
use roc_parse::ast::Def::*; use roc_parse::ast::Def::*;
match parsed_def { match parsed_def {
SpaceBefore(inner_def, _) => { SpaceBefore(inner_def, _) => to_expr2_from_def(arena, env, scope, inner_def, region),
to_expr2_from_def(arena, env, scope, inner_def, region) SpaceAfter(inner_def, _) => to_expr2_from_def(arena, env, scope, inner_def, region),
},
SpaceAfter(inner_def, _) => {
to_expr2_from_def(arena, env, scope, inner_def, region)
}
Body(&loc_pattern, &loc_expr) => { Body(&loc_pattern, &loc_expr) => {
// TODO loc_pattern use identifier // TODO loc_pattern use identifier
let body_expr2 = loc_expr_to_expr2(arena, loc_expr, env, scope, region).0; let body_expr2 = loc_expr_to_expr2(arena, loc_expr, env, scope, region).0;
@ -1041,7 +1030,13 @@ pub fn to_expr2_from_def<'a>(
match loc_pattern.value { match loc_pattern.value {
Identifier(str_ref) => { Identifier(str_ref) => {
let (_, pattern2) = to_pattern2(env, scope, PatternType::TopLevelDef, &loc_pattern.value, region); let (_, pattern2) = to_pattern2(
env,
scope,
PatternType::TopLevelDef,
&loc_pattern.value,
region,
);
let pattern_id = env.pool.add(pattern2); let pattern_id = env.pool.add(pattern2);
// TODO support with annotation // TODO support with annotation
@ -1053,7 +1048,8 @@ pub fn to_expr2_from_def<'a>(
let value_def_id = env.pool.add(value_def); let value_def_id = env.pool.add(value_def);
let ident_string = inlinable_string::InlinableString::from_iter(str_ref.chars()); let ident_string =
inlinable_string::InlinableString::from_iter(str_ref.chars());
let ident_id = env.ident_ids.add(ident_string); let ident_id = env.ident_ids.add(ident_string);
let var_symbol = Symbol::new(env.home, ident_id); let var_symbol = Symbol::new(env.home, ident_id);
let body = Expr2::Var(var_symbol); let body = Expr2::Var(var_symbol);
@ -1064,14 +1060,20 @@ pub fn to_expr2_from_def<'a>(
body_var: env.var_store.fresh(), body_var: env.var_store.fresh(),
body_id, body_id,
} }
}, }
other => { other => {
unimplemented!("I don't yet know how to convert the pattern {:?} into an expr2", other) unimplemented!(
"I don't yet know how to convert the pattern {:?} into an expr2",
other
)
} }
} }
} }
other => { other => {
unimplemented!("I don't know how to make an expr2 from this def yet: {:?}", other) unimplemented!(
"I don't know how to make an expr2 from this def yet: {:?}",
other
)
} }
} }
} }
@ -1520,15 +1522,18 @@ fn decl_to_let(pool: &mut Pool, var_store: &mut VarStore, decl: Declaration, ret
Declaration::Declare(def) => match def { Declaration::Declare(def) => match def {
Def::AnnotationOnly { .. } => todo!(), Def::AnnotationOnly { .. } => todo!(),
Def::Value(value_def) => { Def::Value(value_def) => {
// TODO remove me // TODO remove me
match &value_def { match &value_def {
ValueDef::NoAnnotation{ pattern_id, expr_id, expr_var} => { ValueDef::NoAnnotation {
pattern_id,
expr_id,
expr_var,
} => {
dbg!(pool.get(*pattern_id)); dbg!(pool.get(*pattern_id));
dbg!(pool.get(*expr_id)); dbg!(pool.get(*expr_id));
dbg!(expr_var); dbg!(expr_var);
} }
_ => panic!("REMOVE THIS BLOCK") _ => panic!("REMOVE THIS BLOCK"),
} }
let def_id = pool.add(value_def); let def_id = pool.add(value_def);

View file

@ -1,9 +1,9 @@
pub mod ast; pub mod ast;
pub mod parse;
pub mod constrain; pub mod constrain;
mod def; mod def;
pub mod expr; pub mod expr;
mod module; mod module;
pub mod parse;
pub mod pattern; pub mod pattern;
pub mod pool; pub mod pool;
pub mod roc_file; pub mod roc_file;

View file

@ -1,10 +1,12 @@
use crate::lang::scope::Scope;
use bumpalo::Bump; use bumpalo::Bump;
use roc_parse::parser::SyntaxError; use roc_parse::parser::SyntaxError;
use crate::lang::scope::Scope;
use roc_region::all::Region; use roc_region::all::Region;
use super::{ast::{Expr2, ExprId}, expr::{Env, str_to_expr2_w_defs}}; use super::{
ast::{Expr2, ExprId},
expr::{str_to_expr2_w_defs, Env},
};
// WORK IN PROGRESS FILE // WORK IN PROGRESS FILE
@ -24,9 +26,14 @@ pub struct AppHeader {
} }
impl AST { impl AST {
pub fn parse_from_string<'a>(code_str: &'a str, env: &mut Env<'a>, ast_arena: &'a Bump) -> Result<AST, SyntaxError<'a>> { pub fn parse_from_string<'a>(
code_str: &'a str,
let blank_line_indx = code_str.find("\n\n").expect("I was expecting a double newline to split header and rest of code."); env: &mut Env<'a>,
ast_arena: &'a Bump,
) -> Result<AST, SyntaxError<'a>> {
let blank_line_indx = code_str
.find("\n\n")
.expect("I was expecting a double newline to split header and rest of code.");
let header_str = &code_str[0..blank_line_indx]; let header_str = &code_str[0..blank_line_indx];
let tail_str = &code_str[blank_line_indx..]; let tail_str = &code_str[blank_line_indx..];
@ -36,7 +43,6 @@ impl AST {
let mut expression_ids = Vec::<ExprId>::new(); let mut expression_ids = Vec::<ExprId>::new();
let expr2_vec = str_to_expr2_w_defs(&ast_arena, tail_str, env, &mut scope, region)?; let expr2_vec = str_to_expr2_w_defs(&ast_arena, tail_str, env, &mut scope, region)?;
for expr2 in expr2_vec { for expr2 in expr2_vec {
@ -47,27 +53,22 @@ impl AST {
let ast_node_id = env.pool.add(Expr2::Blank); let ast_node_id = env.pool.add(Expr2::Blank);
Ok( Ok(AST {
AST {
header: AppHeader::parse_from_string(header_str, ast_node_id), header: AppHeader::parse_from_string(header_str, ast_node_id),
expression_ids, expression_ids,
} })
)
} }
} }
impl AppHeader { impl AppHeader {
// TODO don't use mock struct and actually parse string // TODO don't use mock struct and actually parse string
pub fn parse_from_string(_header_str: &str, ast_node_id: ExprId) -> Self { pub fn parse_from_string(_header_str: &str, ast_node_id: ExprId) -> Self {
AppHeader { AppHeader {
app_name: "\"untitled_app\"".to_owned(), app_name: "\"untitled_app\"".to_owned(),
packages_base: "\"platform\"".to_owned(), packages_base: "\"platform\"".to_owned(),
imports: vec![], imports: vec![],
provides: vec!["main".to_owned()], provides: vec!["main".to_owned()],
ast_node_id ast_node_id,
} }
} }
} }

View file

@ -485,15 +485,12 @@ pub fn symbols_from_pattern(pool: &Pool, initial: &Pattern2) -> Vec<Symbol> {
pub fn get_identifier_string(pattern: &Pattern2, interns: &Interns) -> EdResult<String> { pub fn get_identifier_string(pattern: &Pattern2, interns: &Interns) -> EdResult<String> {
match pattern { match pattern {
Pattern2::Identifier(symbol) => { Pattern2::Identifier(symbol) => Ok(symbol.ident_string(interns).to_string()),
Ok(symbol.ident_string(interns).to_string()) other => UnexpectedPattern2Variant {
}
other => {
UnexpectedPattern2Variant {
required_pattern2: "Identifier".to_string(), required_pattern2: "Identifier".to_string(),
encountered_pattern2: format!("{:?}", other) encountered_pattern2: format!("{:?}", other),
}.fail()?
} }
.fail()?,
} }
} }