parse header progress

This commit is contained in:
Anton-4 2021-08-13 19:54:35 +02:00
parent c6e816dfbe
commit 45629a38d1
9 changed files with 323 additions and 160 deletions

5
.gitignore vendored
View file

@ -25,8 +25,13 @@ editor/benches/resources/25000000_lines.roc
editor/benches/resources/50000_lines.roc
editor/benches/resources/500_lines.roc
# file editor creates when none is selected
UntitledApp.roc
# rust cache (sccache folder)
sccache_dir
# self-contained benchmark folder
bench-folder*

15
Cargo.lock generated
View file

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "ab_glyph"
version = "0.2.11"
@ -3172,9 +3174,11 @@ dependencies = [
"quickcheck 1.0.3",
"quickcheck_macros 1.0.0",
"rand 0.8.3",
"roc_builtins",
"roc_can",
"roc_collections",
"roc_fmt",
"roc_load",
"roc_module",
"roc_parse",
"roc_problem",
@ -3186,6 +3190,8 @@ dependencies = [
"ropey",
"serde",
"snafu",
"tempfile",
"uuid",
"ven_graph",
"wgpu",
"wgpu_glyph",
@ -4189,6 +4195,15 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "vec_map"
version = "0.8.2"

View file

@ -9,6 +9,8 @@ exclude = ["src/shaders/*.spv"]
[dependencies]
roc_collections = { path = "../compiler/collections" }
roc_load = { path = "../compiler/load" }
roc_builtins = { path = "../compiler/builtins" }
roc_can = { path = "../compiler/can" }
roc_parse = { path = "../compiler/parse" }
roc_region = { path = "../compiler/region" }
@ -50,6 +52,8 @@ confy = { git = 'https://github.com/rust-cli/confy', features = [
], default-features = false }
serde = { version = "1.0.123", features = ["derive"] }
nonempty = "0.6.0"
tempfile = "3.2.0"
uuid = { version = "0.8", features = ["v4"] }
[dependencies.bytemuck]
version = "1.4"

View file

@ -165,7 +165,7 @@ pub enum EdError {
},
#[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."))]
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));
if let Some(backtrace) = ErrorCompat::backtrace(err) {
eprintln!("{}", color_backtrace(backtrace));
}
}
}*/
fn color_backtrace(backtrace: &snafu::Backtrace) -> String {
let backtrace_str = format!("{}", backtrace);

View file

@ -1,7 +1,5 @@
use super::keyboard_input;
use super::mvc::ed_model::init_model_refs;
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::RenderedWgpu;
use crate::editor::resources::strings::NOTHING_OPENED;
@ -21,17 +19,17 @@ use crate::graphics::{
};
use crate::lang::expr::Env;
use crate::lang::pool::Pool;
use crate::ui::ui_error::UIError::FileOpenFailed;
use crate::ui::util::slice_get;
use bumpalo::collections::String as BumpString;
use bumpalo::Bump;
use cgmath::Vector2;
use pipelines::RectResources;
use roc_module::symbol::Interns;
use roc_module::symbol::{IdentIds, ModuleIds};
use roc_can::builtins::builtin_defs_map;
use roc_collections::all::MutMap;
use roc_load;
use roc_load::file::LoadedModule;
use roc_module::symbol::IdentIds;
use roc_types::subs::VarStore;
use std::fs::File;
use std::os::unix::fs;
use std::{error::Error, io, path::Path};
use std::io::{Write};
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 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_res =
ed_model::init_model_and_env(
&code_bump_str,
ed_model::init_model(
&code_str,
file_path,
"HelloApp".to_owned(),
&mut ed_model_refs);
env,
loaded_module,
&code_arena,
);
match ed_model_res {
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 {
@ -393,9 +412,7 @@ fn read_file<'a>(file_path_opt: Option<&'a Path>, code_arena: &'a Bump) -> (&'a
&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 {
let untitled_path = Path::new("UntitledApp.roc");
@ -407,8 +424,7 @@ 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)
);
let hello_world_roc = r#"
app "untitled-app"
let hello_world_roc = r#"app "untitled-app"
packages { base: "platform" }
imports []
provides [ main ] to base
@ -416,23 +432,58 @@ provides [ main ] to base
main = "Hello, world!"
"#;
write!(untitled_file, "{}", hello_world_roc)?;
write!(untitled_file, "{}", hello_world_roc)
.expect(
&format!(
r#"I wanted to write:
BumpString::from_str_in(hello_world_roc, code_arena)
{:?}
to file {:?}, but it failed."#
, hello_world_roc
, untitled_file
)
);
hello_world_roc.to_string()
} else {
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)
);
)
BumpString::from_str_in(&file_as_str, code_arena)
};
(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(
size: &PhysicalSize<u32>,
text: &str,

View file

@ -3,27 +3,23 @@ use crate::editor::grid_node_map::GridNodeMap;
use crate::editor::markup::common_nodes::new_blank_mn;
use crate::editor::slow_pool::{MarkNodeId, SlowPool};
use crate::editor::{
ed_error::EdError::ParseError,
ed_error::EdError::SrcParseError,
ed_error::{EdResult, MissingParent, NoNodeAtCaretPosition},
markup::nodes::{expr2_to_markup, set_parent_for_all},
};
use crate::graphics::primitives::rect::Rect;
use crate::lang::ast::Expr2;
use crate::lang::expr::{str_to_expr2, Env};
use crate::lang::pool::{NodeId, Pool};
use crate::lang::ast::{Expr2};
use crate::lang::expr::{Env};
use crate::lang::parse::AST;
use crate::lang::pool::{NodeId};
use crate::lang::pool::PoolStr;
use crate::lang::scope::Scope;
use crate::ui::text::caret_w_select::CaretWSelect;
use crate::ui::text::lines::SelectableLines;
use crate::ui::text::text_pos::TextPos;
use crate::ui::ui_error::UIResult;
use bumpalo::collections::String as BumpString;
use bumpalo::Bump;
use nonempty::NonEmpty;
use roc_collections::all::MutMap;
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds};
use roc_region::all::Region;
use roc_types::subs::VarStore;
use roc_load::file::LoadedModule;
use std::path::Path;
#[derive(Debug)]
@ -40,7 +36,7 @@ pub struct EdModel<'a> {
pub has_focus: bool,
pub caret_w_select_vec: NonEmpty<(CaretWSelect, Option<MarkNodeId>)>,
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,
// EdModel is dirty if it has changed since the previous render.
pub dirty: bool,
@ -53,37 +49,15 @@ pub struct SelectedExpression {
pub type_str: PoolStr,
}
pub fn init_model_and_env<'a>(
code_str: &'a BumpString,
pub fn init_model<'a>(
code_str: &'a str,
file_path: &'a Path,
module_name: String,
ed_model_refs: &'a mut EdModelRefs,
env: Env<'a>,
loaded_module: LoadedModule,
code_arena: &'a Bump,
) -> EdResult<EdModel<'a>> {
let dep_idents = IdentIds::exposed_builtins(8);
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 mut module = EdModule::new(&code_str, env, &code_arena)?;
let ast_root_id = module.ast_root_id;
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 temp_markup_root_id = expr2_to_markup(
&ed_model_refs.code_arena,
&code_arena,
&mut module.env,
ast_root,
ast_root_id,
&mut markup_node_pool,
&interns
&loaded_module.interns
)?;
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,
caret_w_select_vec: NonEmpty::new((CaretWSelect::default(), None)),
selected_expr_opt: None,
interns,
loaded_module,
show_debug_view: false,
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)]
pub struct EdModule<'a> {
pub env: Env<'a>,
pub ast_root_id: NodeId<Expr2>,
pub ast: AST,
}
// for debugging
use crate::lang::ast::expr2_to_string;
//use crate::lang::ast::expr2_to_string;
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() {
let mut scope = Scope::new(env.home, env.pool, env.var_store);
let region = Region::new(0, 0, 0, 0);
let parse_res = AST::parse_from_string(code_str, env, ast_arena);
let expr2_result = str_to_expr2(&ast_arena, &code_str, &mut env, &mut scope, region);
match expr2_result {
Ok((expr2, output)) => {
let bound_symbols = output.references.bound_symbols;
let mut module_ident_ids =
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()
match parse_res {
Ok(ast) => {
Ok(
EdModule {
env,
ast,
}
)
});
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 {
},
Err(err) => Err(SrcParseError {
syntax_err: format!("{:?}", err),
}),
})
}
} else {
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)]
pub mod test_ed_model {
use crate::editor::ed_error::EdResult;
use crate::editor::main::load_module;
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_selection_to_dsl;
use crate::ui::text::lines::SelectableLines;
use crate::ui::ui_error::UIResult;
use bumpalo::collections::String as BumpString;
use bumpalo::Bump;
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 super::EdModelRefs;
use std::path::PathBuf;
use std::io::Write;
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,
code_arena: &'a Bump,
) -> EdResult<EdModel<'a>> {
let file_path = Path::new("");
ed_model::init_model_and_env(
&code_str,
let dep_idents = IdentIds::exposed_builtins(8);
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,
"TestApp".to_owned(),
ed_model_refs,
env,
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>(
clean_code_str: &'a BumpString,
clean_code_str: &'a mut String,
code_lines: &[&str],
ed_model_refs: &'a mut EdModelRefs,
module_ids: &'a ModuleIds,
code_arena: &'a Bump,
) -> Result<EdModel<'a>, String> {
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 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);

View file

@ -305,7 +305,7 @@ impl<'a> EdModel<'a> {
let content = subs.get(var).content;
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,
)
}
@ -871,7 +871,7 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
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_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::EdModel;
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::test_modifiers::ctrl_cmd_shift;
use crate::window::keyboard_input::Modifiers;
use bumpalo::collections::String as BumpString;
use bumpalo::Bump;
use roc_module::symbol::ModuleIds;
use winit::event::VirtualKeyCode::*;
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],
new_char_seq: &str,
) -> 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 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() {
if input_char == '🡲' {
@ -1808,12 +1810,14 @@ pub mod test_ed_update {
expected_post_lines: &[&str],
repeats: usize,
) -> 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 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 {
ed_model.ed_handle_key_down(&ctrl_cmd_shift(), Up)?;
@ -2066,12 +2070,14 @@ pub mod test_ed_update {
expected_tooltips: &[&str],
new_char_seq: &str,
) -> 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 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() {
if input_char == '🡲' {
@ -2220,12 +2226,13 @@ pub mod test_ed_update {
repeats: usize,
move_caret_fun: ModelMoveCaretFun,
) -> 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 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 {
ed_model.ed_handle_key_down(&ctrl_cmd_shift(), Up)?;
@ -2349,12 +2356,13 @@ pub mod test_ed_update {
expected_post_lines: &[&str],
repeats: usize,
) -> 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 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 {
ed_model.ed_handle_key_down(&ctrl_cmd_shift(), Up)?;

View file

@ -1,4 +1,5 @@
pub mod ast;
pub mod parse;
pub mod constrain;
mod def;
pub mod expr;

55
editor/src/lang/parse.rs Normal file
View 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>