mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-04 00:54:36 +00:00
parse header progress
This commit is contained in:
parent
c6e816dfbe
commit
45629a38d1
9 changed files with 323 additions and 160 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -25,8 +25,13 @@ editor/benches/resources/25000000_lines.roc
|
||||||
editor/benches/resources/50000_lines.roc
|
editor/benches/resources/50000_lines.roc
|
||||||
editor/benches/resources/500_lines.roc
|
editor/benches/resources/500_lines.roc
|
||||||
|
|
||||||
|
# file editor creates when none is selected
|
||||||
|
UntitledApp.roc
|
||||||
|
|
||||||
# rust cache (sccache folder)
|
# rust cache (sccache folder)
|
||||||
sccache_dir
|
sccache_dir
|
||||||
|
|
||||||
# self-contained benchmark folder
|
# self-contained benchmark folder
|
||||||
bench-folder*
|
bench-folder*
|
||||||
|
|
||||||
|
|
||||||
|
|
15
Cargo.lock
generated
15
Cargo.lock
generated
|
@ -1,5 +1,7 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ab_glyph"
|
name = "ab_glyph"
|
||||||
version = "0.2.11"
|
version = "0.2.11"
|
||||||
|
@ -3172,9 +3174,11 @@ dependencies = [
|
||||||
"quickcheck 1.0.3",
|
"quickcheck 1.0.3",
|
||||||
"quickcheck_macros 1.0.0",
|
"quickcheck_macros 1.0.0",
|
||||||
"rand 0.8.3",
|
"rand 0.8.3",
|
||||||
|
"roc_builtins",
|
||||||
"roc_can",
|
"roc_can",
|
||||||
"roc_collections",
|
"roc_collections",
|
||||||
"roc_fmt",
|
"roc_fmt",
|
||||||
|
"roc_load",
|
||||||
"roc_module",
|
"roc_module",
|
||||||
"roc_parse",
|
"roc_parse",
|
||||||
"roc_problem",
|
"roc_problem",
|
||||||
|
@ -3186,6 +3190,8 @@ dependencies = [
|
||||||
"ropey",
|
"ropey",
|
||||||
"serde",
|
"serde",
|
||||||
"snafu",
|
"snafu",
|
||||||
|
"tempfile",
|
||||||
|
"uuid",
|
||||||
"ven_graph",
|
"ven_graph",
|
||||||
"wgpu",
|
"wgpu",
|
||||||
"wgpu_glyph",
|
"wgpu_glyph",
|
||||||
|
@ -4189,6 +4195,15 @@ version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
|
checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.3",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vec_map"
|
name = "vec_map"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
|
|
|
@ -9,6 +9,8 @@ exclude = ["src/shaders/*.spv"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
roc_collections = { path = "../compiler/collections" }
|
roc_collections = { path = "../compiler/collections" }
|
||||||
|
roc_load = { path = "../compiler/load" }
|
||||||
|
roc_builtins = { path = "../compiler/builtins" }
|
||||||
roc_can = { path = "../compiler/can" }
|
roc_can = { path = "../compiler/can" }
|
||||||
roc_parse = { path = "../compiler/parse" }
|
roc_parse = { path = "../compiler/parse" }
|
||||||
roc_region = { path = "../compiler/region" }
|
roc_region = { path = "../compiler/region" }
|
||||||
|
@ -50,6 +52,8 @@ confy = { git = 'https://github.com/rust-cli/confy', features = [
|
||||||
], default-features = false }
|
], default-features = false }
|
||||||
serde = { version = "1.0.123", features = ["derive"] }
|
serde = { version = "1.0.123", features = ["derive"] }
|
||||||
nonempty = "0.6.0"
|
nonempty = "0.6.0"
|
||||||
|
tempfile = "3.2.0"
|
||||||
|
uuid = { version = "0.8", features = ["v4"] }
|
||||||
|
|
||||||
[dependencies.bytemuck]
|
[dependencies.bytemuck]
|
||||||
version = "1.4"
|
version = "1.4"
|
||||||
|
|
|
@ -165,7 +165,7 @@ pub enum EdError {
|
||||||
},
|
},
|
||||||
|
|
||||||
#[snafu(display("ParseError: Failed to parse AST: SyntaxError: {}.", syntax_err))]
|
#[snafu(display("ParseError: Failed to parse AST: SyntaxError: {}.", syntax_err))]
|
||||||
ParseError { syntax_err: String },
|
SrcParseError { syntax_err: String },
|
||||||
|
|
||||||
#[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 },
|
||||||
|
@ -187,13 +187,13 @@ pub fn print_err(err: &EdError) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_ui_err(err: &UIError) {
|
/*pub fn print_ui_err(err: &UIError) {
|
||||||
eprintln!("{}", format!("{}", err).truecolor(255, 0, 0));
|
eprintln!("{}", format!("{}", err).truecolor(255, 0, 0));
|
||||||
|
|
||||||
if let Some(backtrace) = ErrorCompat::backtrace(err) {
|
if let Some(backtrace) = ErrorCompat::backtrace(err) {
|
||||||
eprintln!("{}", color_backtrace(backtrace));
|
eprintln!("{}", color_backtrace(backtrace));
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
fn color_backtrace(backtrace: &snafu::Backtrace) -> String {
|
fn color_backtrace(backtrace: &snafu::Backtrace) -> String {
|
||||||
let backtrace_str = format!("{}", backtrace);
|
let backtrace_str = format!("{}", backtrace);
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
use super::keyboard_input;
|
use super::keyboard_input;
|
||||||
use super::mvc::ed_model::init_model_refs;
|
|
||||||
use super::style::CODE_TXT_XY;
|
use super::style::CODE_TXT_XY;
|
||||||
use crate::editor::ed_error::print_ui_err;
|
|
||||||
use crate::editor::mvc::ed_view;
|
use crate::editor::mvc::ed_view;
|
||||||
use crate::editor::mvc::ed_view::RenderedWgpu;
|
use crate::editor::mvc::ed_view::RenderedWgpu;
|
||||||
use crate::editor::resources::strings::NOTHING_OPENED;
|
use crate::editor::resources::strings::NOTHING_OPENED;
|
||||||
|
@ -21,17 +19,17 @@ use crate::graphics::{
|
||||||
};
|
};
|
||||||
use crate::lang::expr::Env;
|
use crate::lang::expr::Env;
|
||||||
use crate::lang::pool::Pool;
|
use crate::lang::pool::Pool;
|
||||||
use crate::ui::ui_error::UIError::FileOpenFailed;
|
|
||||||
use crate::ui::util::slice_get;
|
use crate::ui::util::slice_get;
|
||||||
use bumpalo::collections::String as BumpString;
|
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use cgmath::Vector2;
|
use cgmath::Vector2;
|
||||||
use pipelines::RectResources;
|
use pipelines::RectResources;
|
||||||
use roc_module::symbol::Interns;
|
use roc_can::builtins::builtin_defs_map;
|
||||||
use roc_module::symbol::{IdentIds, ModuleIds};
|
use roc_collections::all::MutMap;
|
||||||
|
use roc_load;
|
||||||
|
use roc_load::file::LoadedModule;
|
||||||
|
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::os::unix::fs;
|
|
||||||
use std::{error::Error, io, path::Path};
|
use std::{error::Error, io, path::Path};
|
||||||
use std::io::{Write};
|
use std::io::{Write};
|
||||||
use wgpu::{CommandEncoder, RenderPass, TextureView};
|
use wgpu::{CommandEncoder, RenderPass, TextureView};
|
||||||
|
@ -134,17 +132,38 @@ fn run_event_loop(file_path_opt: Option<&Path>) -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
let is_animating = true;
|
let is_animating = true;
|
||||||
|
|
||||||
let mut ed_model_refs = init_model_refs();
|
let mut env_pool = Pool::with_capacity(1024);
|
||||||
|
let env_arena = Bump::new();
|
||||||
|
let code_arena = Bump::new();
|
||||||
|
|
||||||
let (file_path, code_bump_str) = read_file(file_path_opt, &ed_model_refs.code_arena);
|
let (file_path, code_str) = read_file(file_path_opt);
|
||||||
|
|
||||||
|
let loaded_module = load_module(&file_path);
|
||||||
|
|
||||||
|
let mut var_store = VarStore::default();
|
||||||
|
let dep_idents = IdentIds::exposed_builtins(8);
|
||||||
|
let exposed_ident_ids = IdentIds::default();
|
||||||
|
let module_ids = loaded_module.interns.module_ids.clone();
|
||||||
|
|
||||||
|
let env = Env::new(
|
||||||
|
loaded_module.module_id,
|
||||||
|
&env_arena,
|
||||||
|
&mut env_pool,
|
||||||
|
&mut var_store,
|
||||||
|
dep_idents,
|
||||||
|
&module_ids,
|
||||||
|
exposed_ident_ids,
|
||||||
|
);
|
||||||
|
|
||||||
let ed_model_opt = {
|
let ed_model_opt = {
|
||||||
let ed_model_res =
|
let ed_model_res =
|
||||||
ed_model::init_model_and_env(
|
ed_model::init_model(
|
||||||
&code_bump_str,
|
&code_str,
|
||||||
file_path,
|
file_path,
|
||||||
"HelloApp".to_owned(),
|
env,
|
||||||
&mut ed_model_refs);
|
loaded_module,
|
||||||
|
&code_arena,
|
||||||
|
);
|
||||||
|
|
||||||
match ed_model_res {
|
match ed_model_res {
|
||||||
Ok(mut ed_model) => {
|
Ok(mut ed_model) => {
|
||||||
|
@ -383,7 +402,7 @@ fn begin_render_pass<'a>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_file<'a>(file_path_opt: Option<&'a Path>, code_arena: &'a Bump) -> (&'a Path, BumpString<'a>) {
|
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 {
|
||||||
|
|
||||||
|
@ -392,10 +411,8 @@ fn read_file<'a>(file_path_opt: Option<&'a Path>, code_arena: &'a Bump) -> (&'a
|
||||||
.expect(
|
.expect(
|
||||||
&format!("Failed to read from provided file path: {:?}", file_path)
|
&format!("Failed to read from provided file path: {:?}", file_path)
|
||||||
);
|
);
|
||||||
|
|
||||||
let code_str = BumpString::from_str_in(&file_as_str, code_arena);
|
|
||||||
|
|
||||||
(file_path, code_str)
|
(file_path, file_as_str)
|
||||||
} else {
|
} else {
|
||||||
let untitled_path = Path::new("UntitledApp.roc");
|
let untitled_path = Path::new("UntitledApp.roc");
|
||||||
|
|
||||||
|
@ -407,32 +424,66 @@ fn read_file<'a>(file_path_opt: Option<&'a Path>, code_arena: &'a Bump) -> (&'a
|
||||||
&format!("I wanted to create {:?}, but it failed.", untitled_path)
|
&format!("I wanted to create {:?}, but it failed.", untitled_path)
|
||||||
);
|
);
|
||||||
|
|
||||||
let hello_world_roc = r#"
|
let hello_world_roc = r#"app "untitled-app"
|
||||||
app "untitled-app"
|
packages { base: "platform" }
|
||||||
packages { base: "platform" }
|
imports []
|
||||||
imports []
|
provides [ main ] to base
|
||||||
provides [ main ] to base
|
|
||||||
|
|
||||||
main = "Hello, world!"
|
main = "Hello, world!"
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
write!(untitled_file, "{}", hello_world_roc)?;
|
write!(untitled_file, "{}", hello_world_roc)
|
||||||
|
.expect(
|
||||||
BumpString::from_str_in(hello_world_roc, code_arena)
|
&format!(
|
||||||
} else {
|
r#"I wanted to write:
|
||||||
let file_as_str =
|
|
||||||
std::fs::read_to_string(untitled_path)
|
{:?}
|
||||||
.expect(
|
|
||||||
&format!("I detected an existing {:?}, but I failed to read from it.", untitled_path)
|
to file {:?}, but it failed."#
|
||||||
);
|
, hello_world_roc
|
||||||
|
, untitled_file
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
hello_world_roc.to_string()
|
||||||
|
} else {
|
||||||
|
|
||||||
|
std::fs::read_to_string(untitled_path)
|
||||||
|
.expect(
|
||||||
|
&format!("I detected an existing {:?}, but I failed to read from it.", untitled_path)
|
||||||
|
)
|
||||||
|
|
||||||
BumpString::from_str_in(&file_as_str, code_arena)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
(untitled_path, code_str)
|
(untitled_path, code_str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_module(src_file: &Path) -> LoadedModule {
|
||||||
|
let subs_by_module = MutMap::default();
|
||||||
|
|
||||||
|
let arena = Bump::new();
|
||||||
|
let loaded = roc_load::file::load_and_typecheck(
|
||||||
|
&arena,
|
||||||
|
src_file.to_path_buf(),
|
||||||
|
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)),
|
||||||
|
subs_by_module,
|
||||||
|
8,
|
||||||
|
builtin_defs_map,
|
||||||
|
);
|
||||||
|
|
||||||
|
dbg!(&loaded);
|
||||||
|
|
||||||
|
match loaded {
|
||||||
|
Ok(x) => x,
|
||||||
|
Err(roc_load::file::LoadingProblem::FormattedReport(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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn queue_no_file_text(
|
fn queue_no_file_text(
|
||||||
size: &PhysicalSize<u32>,
|
size: &PhysicalSize<u32>,
|
||||||
text: &str,
|
text: &str,
|
||||||
|
|
|
@ -3,27 +3,23 @@ use crate::editor::grid_node_map::GridNodeMap;
|
||||||
use crate::editor::markup::common_nodes::new_blank_mn;
|
use crate::editor::markup::common_nodes::new_blank_mn;
|
||||||
use crate::editor::slow_pool::{MarkNodeId, SlowPool};
|
use crate::editor::slow_pool::{MarkNodeId, SlowPool};
|
||||||
use crate::editor::{
|
use crate::editor::{
|
||||||
ed_error::EdError::ParseError,
|
ed_error::EdError::SrcParseError,
|
||||||
ed_error::{EdResult, MissingParent, NoNodeAtCaretPosition},
|
ed_error::{EdResult, MissingParent, NoNodeAtCaretPosition},
|
||||||
markup::nodes::{expr2_to_markup, set_parent_for_all},
|
markup::nodes::{expr2_to_markup, set_parent_for_all},
|
||||||
};
|
};
|
||||||
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::{str_to_expr2, Env};
|
use crate::lang::expr::{Env};
|
||||||
use crate::lang::pool::{NodeId, Pool};
|
use crate::lang::parse::AST;
|
||||||
|
use crate::lang::pool::{NodeId};
|
||||||
use crate::lang::pool::PoolStr;
|
use crate::lang::pool::PoolStr;
|
||||||
use crate::lang::scope::Scope;
|
|
||||||
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;
|
||||||
use crate::ui::text::text_pos::TextPos;
|
use crate::ui::text::text_pos::TextPos;
|
||||||
use crate::ui::ui_error::UIResult;
|
use crate::ui::ui_error::UIResult;
|
||||||
use bumpalo::collections::String as BumpString;
|
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use nonempty::NonEmpty;
|
use nonempty::NonEmpty;
|
||||||
use roc_collections::all::MutMap;
|
use roc_load::file::LoadedModule;
|
||||||
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds};
|
|
||||||
use roc_region::all::Region;
|
|
||||||
use roc_types::subs::VarStore;
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -40,7 +36,7 @@ pub struct EdModel<'a> {
|
||||||
pub has_focus: bool,
|
pub has_focus: bool,
|
||||||
pub caret_w_select_vec: NonEmpty<(CaretWSelect, Option<MarkNodeId>)>,
|
pub caret_w_select_vec: NonEmpty<(CaretWSelect, Option<MarkNodeId>)>,
|
||||||
pub selected_expr_opt: Option<SelectedExpression>,
|
pub selected_expr_opt: Option<SelectedExpression>,
|
||||||
pub interns: Interns, // this should eventually come from LoadedModule, see #1442
|
pub loaded_module: LoadedModule,
|
||||||
pub show_debug_view: bool,
|
pub show_debug_view: bool,
|
||||||
// EdModel is dirty if it has changed since the previous render.
|
// EdModel is dirty if it has changed since the previous render.
|
||||||
pub dirty: bool,
|
pub dirty: bool,
|
||||||
|
@ -53,37 +49,15 @@ pub struct SelectedExpression {
|
||||||
pub type_str: PoolStr,
|
pub type_str: PoolStr,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_model_and_env<'a>(
|
pub fn init_model<'a>(
|
||||||
code_str: &'a BumpString,
|
code_str: &'a str,
|
||||||
file_path: &'a Path,
|
file_path: &'a Path,
|
||||||
module_name: String,
|
env: Env<'a>,
|
||||||
ed_model_refs: &'a mut EdModelRefs,
|
loaded_module: LoadedModule,
|
||||||
|
code_arena: &'a Bump,
|
||||||
) -> EdResult<EdModel<'a>> {
|
) -> EdResult<EdModel<'a>> {
|
||||||
|
|
||||||
let dep_idents = IdentIds::exposed_builtins(8);
|
let mut module = EdModule::new(&code_str, env, &code_arena)?;
|
||||||
let exposed_ident_ids = IdentIds::default();
|
|
||||||
|
|
||||||
let mut interns = Interns {
|
|
||||||
module_ids: ModuleIds::default(),
|
|
||||||
all_ident_ids: IdentIds::exposed_builtins(8),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mod_id =
|
|
||||||
interns
|
|
||||||
.module_ids
|
|
||||||
.get_or_insert(&module_name.into());
|
|
||||||
|
|
||||||
let env = Env::new(
|
|
||||||
mod_id,
|
|
||||||
&ed_model_refs.env_arena,
|
|
||||||
&mut ed_model_refs.env_pool,
|
|
||||||
&mut ed_model_refs.var_store,
|
|
||||||
dep_idents,
|
|
||||||
&interns.module_ids,
|
|
||||||
exposed_ident_ids,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut module = EdModule::new(&code_str, env, &mut interns.all_ident_ids, &ed_model_refs.code_arena)?;
|
|
||||||
|
|
||||||
let ast_root_id = module.ast_root_id;
|
let ast_root_id = module.ast_root_id;
|
||||||
let mut markup_node_pool = SlowPool::new();
|
let mut markup_node_pool = SlowPool::new();
|
||||||
|
@ -97,12 +71,12 @@ pub fn init_model_and_env<'a>(
|
||||||
let ast_root = &module.env.pool.get(ast_root_id);
|
let ast_root = &module.env.pool.get(ast_root_id);
|
||||||
|
|
||||||
let temp_markup_root_id = expr2_to_markup(
|
let temp_markup_root_id = expr2_to_markup(
|
||||||
&ed_model_refs.code_arena,
|
&code_arena,
|
||||||
&mut module.env,
|
&mut module.env,
|
||||||
ast_root,
|
ast_root,
|
||||||
ast_root_id,
|
ast_root_id,
|
||||||
&mut markup_node_pool,
|
&mut markup_node_pool,
|
||||||
&interns
|
&loaded_module.interns
|
||||||
)?;
|
)?;
|
||||||
set_parent_for_all(temp_markup_root_id, &mut markup_node_pool);
|
set_parent_for_all(temp_markup_root_id, &mut markup_node_pool);
|
||||||
|
|
||||||
|
@ -123,7 +97,7 @@ pub fn init_model_and_env<'a>(
|
||||||
has_focus: true,
|
has_focus: true,
|
||||||
caret_w_select_vec: NonEmpty::new((CaretWSelect::default(), None)),
|
caret_w_select_vec: NonEmpty::new((CaretWSelect::default(), None)),
|
||||||
selected_expr_opt: None,
|
selected_expr_opt: None,
|
||||||
interns,
|
loaded_module,
|
||||||
show_debug_view: false,
|
show_debug_view: false,
|
||||||
dirty: true,
|
dirty: true,
|
||||||
})
|
})
|
||||||
|
@ -180,76 +154,47 @@ impl<'a> EdModel<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EdModelRefs {
|
|
||||||
pub code_arena: Bump,
|
|
||||||
pub env_arena: Bump,
|
|
||||||
pub env_pool: Pool,
|
|
||||||
pub var_store: VarStore,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init_model_refs() -> EdModelRefs {
|
|
||||||
EdModelRefs {
|
|
||||||
code_arena: Bump::new(),
|
|
||||||
env_arena: Bump::new(),
|
|
||||||
env_pool: Pool::with_capacity(1024),
|
|
||||||
var_store: VarStore::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EdModule<'a> {
|
pub struct EdModule<'a> {
|
||||||
pub env: Env<'a>,
|
pub env: Env<'a>,
|
||||||
pub ast_root_id: NodeId<Expr2>,
|
pub ast: AST,
|
||||||
}
|
}
|
||||||
|
|
||||||
// for debugging
|
// for debugging
|
||||||
use crate::lang::ast::expr2_to_string;
|
//use crate::lang::ast::expr2_to_string;
|
||||||
|
|
||||||
impl<'a> EdModule<'a> {
|
impl<'a> EdModule<'a> {
|
||||||
pub fn new(code_str: &'a str, mut env: Env<'a>, all_ident_ids: &mut MutMap<ModuleId, IdentIds>, 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 mut scope = Scope::new(env.home, env.pool, env.var_store);
|
|
||||||
|
let parse_res = AST::parse_from_string(code_str, env, ast_arena);
|
||||||
|
|
||||||
let region = Region::new(0, 0, 0, 0);
|
match parse_res {
|
||||||
|
Ok(ast) => {
|
||||||
let expr2_result = str_to_expr2(&ast_arena, &code_str, &mut env, &mut scope, region);
|
Ok(
|
||||||
|
EdModule {
|
||||||
match expr2_result {
|
env,
|
||||||
Ok((expr2, output)) => {
|
ast,
|
||||||
|
}
|
||||||
let bound_symbols = output.references.bound_symbols;
|
)
|
||||||
|
},
|
||||||
let mut module_ident_ids =
|
Err(err) => Err(SrcParseError {
|
||||||
all_ident_ids
|
|
||||||
.get_mut(&env.home)
|
|
||||||
.unwrap_or_else(|| {
|
|
||||||
panic!(
|
|
||||||
"Could not find env.home (ModuleId: {:?}) in interns.all_ident_ids.keys: {:?}",
|
|
||||||
&env.home,
|
|
||||||
all_ident_ids.keys()
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
all_ident_ids
|
|
||||||
.insert(env.home, env.ident_ids);
|
|
||||||
|
|
||||||
|
|
||||||
let ast_root_id = env.pool.add(expr2);
|
|
||||||
|
|
||||||
// for debugging
|
|
||||||
dbg!(expr2_to_string(ast_root_id, env.pool));
|
|
||||||
|
|
||||||
Ok(EdModule { env, ast_root_id })
|
|
||||||
}
|
|
||||||
Err(err) => Err(ParseError {
|
|
||||||
syntax_err: format!("{:?}", err),
|
syntax_err: format!("{:?}", err),
|
||||||
}),
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
let ast_root_id = env.pool.add(Expr2::Blank);
|
let ast_root_id = env.pool.add(Expr2::Blank);
|
||||||
|
|
||||||
Ok(EdModule { env, ast_root_id })
|
Ok(
|
||||||
|
EdModule {
|
||||||
|
env,
|
||||||
|
ast: AST {
|
||||||
|
header: "".to_string(),
|
||||||
|
expressions: vec![ast_root_id],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,40 +202,119 @@ impl<'a> EdModule<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod test_ed_model {
|
pub mod test_ed_model {
|
||||||
use crate::editor::ed_error::EdResult;
|
use crate::editor::ed_error::EdResult;
|
||||||
|
use crate::editor::main::load_module;
|
||||||
use crate::editor::mvc::ed_model;
|
use crate::editor::mvc::ed_model;
|
||||||
|
use crate::lang::expr::Env;
|
||||||
|
use crate::lang::pool::Pool;
|
||||||
use crate::ui::text::caret_w_select::test_caret_w_select::convert_dsl_to_selection;
|
use crate::ui::text::caret_w_select::test_caret_w_select::convert_dsl_to_selection;
|
||||||
use crate::ui::text::caret_w_select::test_caret_w_select::convert_selection_to_dsl;
|
use crate::ui::text::caret_w_select::test_caret_w_select::convert_selection_to_dsl;
|
||||||
use crate::ui::text::lines::SelectableLines;
|
use crate::ui::text::lines::SelectableLines;
|
||||||
use crate::ui::ui_error::UIResult;
|
use crate::ui::ui_error::UIResult;
|
||||||
use bumpalo::collections::String as BumpString;
|
use bumpalo::Bump;
|
||||||
use ed_model::EdModel;
|
use ed_model::EdModel;
|
||||||
|
use roc_load::file::LoadedModule;
|
||||||
|
use roc_module::symbol::IdentIds;
|
||||||
|
use roc_module::symbol::ModuleIds;
|
||||||
|
use roc_types::subs::VarStore;
|
||||||
|
use tempfile::tempdir;
|
||||||
|
use uuid::Uuid;
|
||||||
|
use std::fs::File;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::path::PathBuf;
|
||||||
use super::EdModelRefs;
|
use std::io::Write;
|
||||||
|
|
||||||
pub fn init_dummy_model<'a>(
|
pub fn init_dummy_model<'a>(
|
||||||
code_str: &'a BumpString,
|
code_str: &'a str,
|
||||||
|
loaded_module: LoadedModule,
|
||||||
|
module_ids: &'a ModuleIds,
|
||||||
ed_model_refs: &'a mut EdModelRefs,
|
ed_model_refs: &'a mut EdModelRefs,
|
||||||
|
code_arena: &'a Bump,
|
||||||
) -> EdResult<EdModel<'a>> {
|
) -> EdResult<EdModel<'a>> {
|
||||||
let file_path = Path::new("");
|
let file_path = Path::new("");
|
||||||
|
|
||||||
ed_model::init_model_and_env(
|
let dep_idents = IdentIds::exposed_builtins(8);
|
||||||
&code_str,
|
let exposed_ident_ids = IdentIds::default();
|
||||||
|
|
||||||
|
let env = Env::new(
|
||||||
|
loaded_module.module_id,
|
||||||
|
&ed_model_refs.env_arena,
|
||||||
|
&mut ed_model_refs.env_pool,
|
||||||
|
&mut ed_model_refs.var_store,
|
||||||
|
dep_idents,
|
||||||
|
module_ids,
|
||||||
|
exposed_ident_ids,
|
||||||
|
);
|
||||||
|
|
||||||
|
ed_model::init_model(
|
||||||
|
code_str,
|
||||||
file_path,
|
file_path,
|
||||||
"TestApp".to_owned(),
|
env,
|
||||||
ed_model_refs,
|
loaded_module,
|
||||||
|
code_arena,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct EdModelRefs {
|
||||||
|
env_arena: Bump,
|
||||||
|
env_pool: Pool,
|
||||||
|
var_store: VarStore,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_model_refs() -> EdModelRefs {
|
||||||
|
EdModelRefs {
|
||||||
|
env_arena: Bump::new(),
|
||||||
|
env_pool: Pool::with_capacity(1024),
|
||||||
|
var_store: VarStore::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn ed_model_from_dsl<'a>(
|
pub fn ed_model_from_dsl<'a>(
|
||||||
clean_code_str: &'a BumpString,
|
clean_code_str: &'a mut String,
|
||||||
code_lines: &[&str],
|
code_lines: &[&str],
|
||||||
ed_model_refs: &'a mut EdModelRefs,
|
ed_model_refs: &'a mut EdModelRefs,
|
||||||
|
module_ids: &'a ModuleIds,
|
||||||
|
code_arena: &'a Bump,
|
||||||
) -> Result<EdModel<'a>, String> {
|
) -> Result<EdModel<'a>, String> {
|
||||||
let code_lines_vec: Vec<String> = (*code_lines).iter().map(|s| s.to_string()).collect();
|
let code_lines_vec: Vec<String> = (*code_lines).iter().map(|s| s.to_string()).collect();
|
||||||
let caret_w_select = convert_dsl_to_selection(&code_lines_vec)?;
|
let caret_w_select = convert_dsl_to_selection(&code_lines_vec)?;
|
||||||
|
|
||||||
let mut ed_model = init_dummy_model(clean_code_str, ed_model_refs)?;
|
let header_str = r#"
|
||||||
|
app "test-app"
|
||||||
|
packages { base: "platform" }
|
||||||
|
imports []
|
||||||
|
provides [ main ] to base
|
||||||
|
|
||||||
|
main = "Hello, world!"
|
||||||
|
|
||||||
|
"#;
|
||||||
|
|
||||||
|
*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_file_path_buf = 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 mut file = File::create(temp_file_full_path.clone())
|
||||||
|
.expect(
|
||||||
|
&format!("Failed to create temporary file for path {:?}", temp_file_full_path)
|
||||||
|
);
|
||||||
|
writeln!(file, "{}", clean_code_str)
|
||||||
|
.expect(
|
||||||
|
&format!("Failed to write {:?} to file: {:?}", clean_code_str, file)
|
||||||
|
);
|
||||||
|
|
||||||
|
let loaded_module = load_module(&temp_file_full_path);
|
||||||
|
|
||||||
|
let mut ed_model =
|
||||||
|
init_dummy_model(
|
||||||
|
clean_code_str,
|
||||||
|
loaded_module,
|
||||||
|
module_ids,
|
||||||
|
ed_model_refs,
|
||||||
|
code_arena,
|
||||||
|
)?;
|
||||||
|
|
||||||
ed_model.set_caret(caret_w_select.caret_pos);
|
ed_model.set_caret(caret_w_select.caret_pos);
|
||||||
|
|
||||||
|
|
|
@ -305,7 +305,7 @@ 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.interns),
|
&content_to_string(content, &subs, self.module.env.home, &self.loaded_module.interns),
|
||||||
self.module.env.pool,
|
self.module.env.pool,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -871,7 +871,7 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
|
||||||
pub mod test_ed_update {
|
pub mod test_ed_update {
|
||||||
use crate::editor::mvc::ed_model::test_ed_model::ed_model_from_dsl;
|
use crate::editor::mvc::ed_model::test_ed_model::ed_model_from_dsl;
|
||||||
use crate::editor::mvc::ed_model::test_ed_model::ed_model_to_dsl;
|
use crate::editor::mvc::ed_model::test_ed_model::ed_model_to_dsl;
|
||||||
use crate::editor::mvc::ed_model::init_model_refs;
|
use crate::editor::mvc::ed_model::test_ed_model::init_model_refs;
|
||||||
use crate::editor::mvc::ed_update::handle_new_char;
|
use crate::editor::mvc::ed_update::handle_new_char;
|
||||||
use crate::editor::mvc::ed_update::EdModel;
|
use crate::editor::mvc::ed_update::EdModel;
|
||||||
use crate::editor::mvc::ed_update::EdResult;
|
use crate::editor::mvc::ed_update::EdResult;
|
||||||
|
@ -880,8 +880,8 @@ pub mod test_ed_update {
|
||||||
use crate::window::keyboard_input::no_mods;
|
use crate::window::keyboard_input::no_mods;
|
||||||
use crate::window::keyboard_input::test_modifiers::ctrl_cmd_shift;
|
use crate::window::keyboard_input::test_modifiers::ctrl_cmd_shift;
|
||||||
use crate::window::keyboard_input::Modifiers;
|
use crate::window::keyboard_input::Modifiers;
|
||||||
use bumpalo::collections::String as BumpString;
|
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
use roc_module::symbol::ModuleIds;
|
||||||
use winit::event::VirtualKeyCode::*;
|
use winit::event::VirtualKeyCode::*;
|
||||||
|
|
||||||
fn ed_res_to_res<T>(ed_res: EdResult<T>) -> Result<T, String> {
|
fn ed_res_to_res<T>(ed_res: EdResult<T>) -> Result<T, String> {
|
||||||
|
@ -919,12 +919,14 @@ 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 test_arena = Bump::new();
|
|
||||||
let code_str = BumpString::from_str_in(&pre_lines.join("\n").replace("┃", ""), &test_arena);
|
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 module_ids = ModuleIds::default();
|
||||||
|
|
||||||
let mut ed_model = ed_model_from_dsl(&code_str, pre_lines, &mut model_refs)?;
|
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 == '🡲' {
|
||||||
|
@ -1808,12 +1810,14 @@ pub mod test_ed_update {
|
||||||
expected_post_lines: &[&str],
|
expected_post_lines: &[&str],
|
||||||
repeats: usize,
|
repeats: usize,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let test_arena = Bump::new();
|
|
||||||
let code_str = BumpString::from_str_in(&pre_lines.join("").replace("┃", ""), &test_arena);
|
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 module_ids = ModuleIds::default();
|
||||||
|
|
||||||
let mut ed_model = ed_model_from_dsl(&code_str, pre_lines, &mut model_refs)?;
|
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)?;
|
||||||
|
@ -2066,12 +2070,14 @@ pub mod test_ed_update {
|
||||||
expected_tooltips: &[&str],
|
expected_tooltips: &[&str],
|
||||||
new_char_seq: &str,
|
new_char_seq: &str,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let test_arena = Bump::new();
|
|
||||||
let code_str = BumpString::from_str_in(&pre_lines.join("").replace("┃", ""), &test_arena);
|
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 module_ids = ModuleIds::default();
|
||||||
|
|
||||||
let mut ed_model = ed_model_from_dsl(&code_str, pre_lines, &mut model_refs)?;
|
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 == '🡲' {
|
||||||
|
@ -2220,12 +2226,13 @@ pub mod test_ed_update {
|
||||||
repeats: usize,
|
repeats: usize,
|
||||||
move_caret_fun: ModelMoveCaretFun,
|
move_caret_fun: ModelMoveCaretFun,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let test_arena = Bump::new();
|
let mut code_str = pre_lines.join("").replace("┃", "");
|
||||||
let code_str = BumpString::from_str_in(&pre_lines.join("").replace("┃", ""), &test_arena);
|
|
||||||
|
|
||||||
let mut model_refs = init_model_refs();
|
let mut model_refs = init_model_refs();
|
||||||
|
let code_arena = Bump::new();
|
||||||
|
let module_ids = ModuleIds::default();
|
||||||
|
|
||||||
let mut ed_model = ed_model_from_dsl(&code_str, pre_lines, &mut model_refs)?;
|
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)?;
|
||||||
|
@ -2349,12 +2356,13 @@ pub mod test_ed_update {
|
||||||
expected_post_lines: &[&str],
|
expected_post_lines: &[&str],
|
||||||
repeats: usize,
|
repeats: usize,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let test_arena = Bump::new();
|
let mut code_str = pre_lines.join("").replace("┃", "");
|
||||||
let code_str = BumpString::from_str_in(&pre_lines.join("").replace("┃", ""), &test_arena);
|
|
||||||
|
|
||||||
let mut model_refs = init_model_refs();
|
let mut model_refs = init_model_refs();
|
||||||
|
let code_arena = Bump::new();
|
||||||
|
let module_ids = ModuleIds::default();
|
||||||
|
|
||||||
let mut ed_model = ed_model_from_dsl(&code_str, pre_lines, &mut model_refs)?;
|
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)?;
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
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;
|
||||||
|
|
55
editor/src/lang/parse.rs
Normal file
55
editor/src/lang/parse.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
use bumpalo::Bump;
|
||||||
|
use roc_parse::parser::SyntaxError;
|
||||||
|
use crate::lang::scope::Scope;
|
||||||
|
use roc_region::all::Region;
|
||||||
|
|
||||||
|
use super::{ast::ExprId, expr::{Env, str_to_expr2}};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// <temporary WIP zone>
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct AST {
|
||||||
|
pub header: String,
|
||||||
|
pub expressions: Vec<ExprId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AST {
|
||||||
|
pub fn parse_from_string<'a>(code_str: &str, mut env: Env<'a>, ast_arena: &Bump) -> Result<AST, SyntaxError<'a>> {
|
||||||
|
|
||||||
|
let mut split_string = code_str.split("\n\n");
|
||||||
|
|
||||||
|
let split_code_vec: Vec<&str> = split_string.collect();
|
||||||
|
|
||||||
|
if let Some((head, tail)) = split_code_vec.split_first() {
|
||||||
|
|
||||||
|
let mut scope = Scope::new(env.home, env.pool, env.var_store);
|
||||||
|
|
||||||
|
let region = Region::new(0, 0, 0, 0);
|
||||||
|
|
||||||
|
let expressions =
|
||||||
|
tail
|
||||||
|
.iter()
|
||||||
|
.map(|&expr_str|
|
||||||
|
{
|
||||||
|
let (expr2, _output) = str_to_expr2(&ast_arena, code_str, &mut env, &mut scope, region)?;
|
||||||
|
|
||||||
|
let expr_id = env.pool.add(expr2);
|
||||||
|
|
||||||
|
expr_id
|
||||||
|
}
|
||||||
|
).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
AST {
|
||||||
|
header: head.to_string(),
|
||||||
|
expressions,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
panic!("I was expecting a double newline to split header and rest of code.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// </temporary WIP zone>
|
Loading…
Add table
Add a link
Reference in a new issue