diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 40b73ec..c1389b4 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -7,11 +7,17 @@
-
+
+
+
+
+
+
+
@@ -106,7 +112,7 @@
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
"org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",
"org.rust.first.attach.projects": "true",
- "settings.editor.selected.configurable": "language.rust.cargo.check",
+ "settings.editor.selected.configurable": "preferences.pluginManager",
"vue.rearranger.settings.migration": "true"
},
"keyToStringList": {
@@ -281,14 +287,9 @@
-
-
-
- 1718889832262
-
-
-
- 1718889832262
+
+
+
@@ -674,7 +675,15 @@
1723054195988
-
+
+
+ 1723213598029
+
+
+
+ 1723213598029
+
+
@@ -743,7 +752,6 @@
-
@@ -756,7 +764,8 @@
-
+
+
diff --git a/main.why b/main.why
index 85502e7..bf9dcb6 100644
--- a/main.why
+++ b/main.why
@@ -1,4 +1,4 @@
-use std/linked_list.why;
+use std/;
fn main() -> int {
diff --git a/src/root/compiler/compile.rs b/src/root/compiler/compile.rs
index 0712322..6f143cb 100644
--- a/src/root/compiler/compile.rs
+++ b/src/root/compiler/compile.rs
@@ -1,7 +1,9 @@
-use std::collections::HashMap;
-
#[cfg(debug_assertions)]
use itertools::Itertools;
+use std::collections::HashMap;
+use std::io::{stdout, Write};
+use std::thread;
+use std::time::{Duration, Instant};
use crate::root::compiler::compile_function::compile_function;
use crate::root::compiler::global_tracker::GlobalTracker;
@@ -19,10 +21,14 @@ pub fn compile(
path_storage: &PathStorage,
) -> Result {
let mut unprocessed_functions = unprocessed_functions;
+ // TODO: Write assembly to disk asynchronously while compiling
let mut compiled_functions = new_hashmap();
let mut compiled_len = 0usize;
let mut open_set = new_hashset();
+ let mut compiled_count: usize = 0;
+ let mut last_shown = Instant::now();
+
open_set.insert(FunctionID(0)); // Start with main
let mut global_tracker = GlobalTracker::new(path_storage);
@@ -31,6 +37,8 @@ pub fn compile(
let current_function = *open_set.iter().next().unwrap();
open_set.remove(¤t_function);
+
+ compiled_count += 1;
let Some(current_function_token) = unprocessed_functions.remove(¤t_function) else {
continue; // Inline function
@@ -51,7 +59,22 @@ pub fn compile(
open_set.insert(*called);
}
}
+
+ if Instant::now() - last_shown > Duration::from_millis(1000) {
+ print!(
+ "\n - {}/{} Functions Compiled",
+ compiled_count,
+ open_set.len() + compiled_count
+ );
+ last_shown = Instant::now();
+ }
}
+ print!(
+ "\n - {}/{} Functions Compiled",
+ compiled_count,
+ open_set.len() + compiled_count
+ );
+ println!();
let mut s = String::with_capacity(compiled_len);
diff --git a/src/root/parser/mod.rs b/src/root/parser/mod.rs
index 79b242d..d3bb395 100644
--- a/src/root/parser/mod.rs
+++ b/src/root/parser/mod.rs
@@ -6,6 +6,7 @@ pub mod parse_blocks;
pub mod parse_comments;
pub mod parse_function;
pub mod parse_impl;
+mod parse_imports;
pub mod parse_name;
pub mod parse_name_old;
pub mod parse_parameters;
@@ -14,4 +15,3 @@ pub mod parse_toplevel;
pub mod parse_util;
pub mod path_storage;
pub mod soft_alt;
-mod use_parser;
diff --git a/src/root/parser/parse.rs b/src/root/parser/parse.rs
index e21791e..9a95fb1 100644
--- a/src/root/parser/parse.rs
+++ b/src/root/parser/parse.rs
@@ -9,10 +9,10 @@ use crate::root::errors::parser_errors::ParseError;
use crate::root::errors::WErr;
use crate::root::parser::handle_errors::handle_error;
use crate::root::parser::location::Location;
+use crate::root::parser::parse_imports::parse_imports;
use crate::root::parser::parse_toplevel;
use crate::root::parser::parse_toplevel::TopLevelTokens;
use crate::root::parser::path_storage::{FileID, PathStorage};
-use crate::root::parser::use_parser::parse_uses;
pub type Span<'a> = LocatedSpan<&'a str, FileID>;
@@ -35,7 +35,7 @@ pub fn parse(path_storage: &mut PathStorage) -> Result, WErr
let base = Span::new_extra(&text, file_id);
- let (after_use, new_files) = handle_error(parse_uses(base, path_storage), path_storage)?;
+ let (after_use, new_files) = handle_error(parse_imports(base, path_storage, file_id), path_storage)?;
path_queue.extend(new_files);
let res = parse_toplevel::parse_toplevel(after_use);
diff --git a/src/root/parser/use_parser.rs b/src/root/parser/parse_imports.rs
similarity index 78%
rename from src/root/parser/use_parser.rs
rename to src/root/parser/parse_imports.rs
index 6b6364c..26a3078 100644
--- a/src/root/parser/use_parser.rs
+++ b/src/root/parser/parse_imports.rs
@@ -7,15 +7,21 @@ use crate::root::parser::parse::{ErrorTree, ParseResult, Span};
use crate::root::parser::parse_util::discard_ignored;
use crate::root::parser::path_storage::{FileID, PathStorage};
-pub fn parse_uses<'a>(
+pub fn parse_imports<'a>(
s: Span<'a>,
path_storage: &mut PathStorage,
+ current_file: FileID,
) -> ParseResult<'a, Span<'a>, Vec<(FileID, Location)>> {
let mut s = s;
let mut found_paths = Vec::new();
loop {
let (ns, _) = discard_ignored(s)?;
- let Ok((ns, _)) = tag::<_, _, ErrorTree>("use")(ns) else {
+ let mut is_use = true;
+
+ let Ok((ns, _)) = tag::<_, _, ErrorTree>("use")(ns).or_else(|_| {
+ is_use = false;
+ tag::<_, _, ErrorTree>("import")(ns)
+ }) else {
return Ok((ns, found_paths));
};
@@ -37,9 +43,9 @@ pub fn parse_uses<'a>(
));
}
- let (_, (id, new)) = path_storage.get_file_path_id_checked(path)?;
-
- if new {
+ let (_, ids) = path_storage.get_id_and_add_to_file(current_file, is_use, path)?;
+
+ for id in ids {
found_paths.push((id, Location::from_span(&path)));
}
diff --git a/src/root/parser/path_storage.rs b/src/root/parser/path_storage.rs
index dfefaa7..0c69666 100644
--- a/src/root/parser/path_storage.rs
+++ b/src/root/parser/path_storage.rs
@@ -1,11 +1,11 @@
use std::collections::HashMap;
-
-use nom::character::complete::anychar;
-
+use std::fs;
use crate::root::errors::parser_errors::create_custom_error;
use crate::root::errors::WErr;
use crate::root::parser::parse::{ErrorTree, ParseResult, Span};
use crate::root::utils::identify_first_last::IdentifyLast;
+use nom::character::complete::anychar;
+use nom::InputTake;
#[derive(Hash, Copy, Clone, Debug, Eq, PartialEq)]
pub struct FileID(usize);
@@ -40,7 +40,8 @@ struct CodeFile {
parent: FolderID,
current: String,
use_files: Vec,
- use_folders: Vec,
+ imported_files: Vec,
+ imported_folders: Vec, // Use folder converts to import subfiles + folders
}
pub struct PathStorage {
@@ -51,6 +52,9 @@ pub struct PathStorage {
impl PathStorage {
pub fn new(main: &str) -> Result {
// TODO: Only allow certain characters in base
+ if !main.ends_with(".why") { todo!() }
+ let main = &main[..main.len() - ".why".len()];
+
let mut folders = vec![CodeFolder::root()];
let mut files = Vec::new();
@@ -61,7 +65,8 @@ impl PathStorage {
parent: current,
current: section.to_string(),
use_files: vec![],
- use_folders: vec![],
+ imported_files: vec![],
+ imported_folders: vec![],
});
} else {
folders.push(CodeFolder {
@@ -95,10 +100,10 @@ impl PathStorage {
}
pub fn reconstruct_file(&self, id: FileID) -> String {
- let mut sb = self.get_file(id).current.clone();
+ let mut sb = self.get_file(id).current.clone() + ".why";
let mut current = self.get_file(id).parent;
while current.0 != 0 {
- sb = self.get_folder(current).current.clone() + "/" + &sb;
+ sb = self.get_folder(current).current.clone() + std::path::MAIN_SEPARATOR_STR + &sb;
current = self.get_folder(current).parent;
}
sb
@@ -108,33 +113,62 @@ impl PathStorage {
let mut sb = self.get_folder(id).current.to_string();
let mut current = self.get_folder(id).parent;
while current.0 != 0 {
- sb = self.get_folder(current).current.clone() + "/" + &sb;
+ sb = self.get_folder(current).current.clone() + std::path::MAIN_SEPARATOR_STR + &sb;
current = self.get_folder(current).parent;
}
sb
}
- pub fn get_file_path_id_checked<'a>(
+ pub fn get_id_and_add_to_file<'a>(
&mut self,
+ current_file: FileID,
+ is_use: bool,
path: Span<'a>,
- ) -> ParseResult<(), (FileID, bool), ErrorTree<'a>> {
+ ) -> ParseResult<(), Vec, ErrorTree<'a>> {
let mut path_rem = path;
- let mut last_dot = false;
+
+ let Some(last) = path_rem.chars().last() else {
+ todo!()
+ };
+ // let wildcard = if last == '*' {
+ // let (_, p) = path_rem.take_split(path_rem.len() - 1);
+ // path_rem = p;
+ // true
+ // } else {
+ // false
+ // };
+
+ let is_folder = if let Some(last) = path_rem.chars().last() {
+ if last == '/' {
+ let (_, p) = path_rem.take_split(path_rem.len() - 1);
+ path_rem = p;
+ true
+ } else {
+ false
+ }
+ } else {
+ false
+ };
+
+ let is_absolute = if let Some(last) = path_rem.chars().next() {
+ if last == '/' {
+ let (p, _) = path_rem.take_split(1);
+ path_rem = p;
+ true
+ } else {
+ false
+ }
+ } else {
+ false
+ };
+
+ // if wildcard && !is_folder {
+ // todo!()
+ // }
+
while let Ok((rem, c)) = anychar::<_, ErrorTree>(path_rem) {
if c.is_alphanumeric() || c == '_' || c == '/' {
- last_dot = false;
- path_rem = rem;
- continue;
- }
- if c == '.' {
- if last_dot {
- return Err(create_custom_error(
- "Double '.'s not allowed in path".to_string(),
- path_rem,
- ));
- }
path_rem = rem;
- last_dot = true;
continue;
}
@@ -150,44 +184,101 @@ impl PathStorage {
));
}
- let mut current = FolderID(0);
+ let mut current: FolderID = if is_absolute {
+ FolderID(0)
+ } else {
+ self.get_file(current_file).parent
+ };
- for (is_last, section) in path.split('/').identify_last() {
+ for (is_last, section) in path.split_terminator('/').identify_last() {
if is_last {
- return if let Some(id) = self.get_folder(current).child_files.get(section) {
- Ok(((), (*id, false)))
+ if is_folder {
+ let folder = self.add_folder(section, current);
+ if !is_use {
+ self.get_file_mut(current_file).imported_folders.push(folder);
+ }
+ let folder_path = self.reconstruct_folder(folder);
+ let mut new_files = Vec::new();
+
+ let Ok(subpaths) = fs::read_dir(folder_path) else { todo!() };
+ for path in subpaths {
+ let Ok(path) = path else { todo!() };
+ let Ok(t) = path.file_type() else { todo!() };
+ if !t.is_file() { continue; }
+ let path = path.path();
+ if !path.extension().and_then(|e| e.to_str()).is_some_and(|e| e == "why") {
+ continue;
+ }
+ let Some(name) = path.file_stem().and_then(|f| f.to_str()) else { todo!() };
+
+ let (file, is_new) = self.add_file(name, folder);
+ if is_new { new_files.push(file); }
+ if is_use {
+ self.get_file_mut(current_file).imported_files.push(file);
+ }
+ }
+
+ return Ok(((), new_files));
} else {
- self.files.push(CodeFile {
- parent: current,
- current: section.to_string(),
- use_files: vec![],
- use_folders: vec![],
- });
- let id = FileID(self.files.len() - 1);
- self.get_folder_mut(current)
- .child_files
- .insert(section.to_string(), id);
- Ok(((), (id, true)))
- };
+ let (file, is_new) = self.add_file(section, current);
+ if file == current_file {
+ todo!();
+ }
+
+ if is_use {
+ self.get_file_mut(current_file).use_files.push(file);
+ } else {
+ self.get_file_mut(current_file).imported_files.push(file);
+ }
+
+ return if is_new {
+ Ok(((), vec![file]))
+ } else {
+ Ok(((), vec![]))
+ }
+ }
} else {
- current = if let Some(id) = self.get_folder(current).child_folders.get(section) {
- *id
- } else {
- self.folders.push(CodeFolder {
- parent: current,
- child_folders: Default::default(),
- child_files: Default::default(),
- current: section.to_string(),
- });
- let id = FolderID(self.folders.len() - 1);
- self.get_folder_mut(current)
- .child_folders
- .insert(section.to_string(), id);
- id
- };
+ current = self.add_folder(section, current);
}
}
panic!()
}
+
+ fn add_file(&mut self, name: &str, parent: FolderID) -> (FileID, bool) {
+ if let Some(id) = self.get_folder(parent).child_files.get(name) {
+ (*id, false)
+ } else {
+ self.files.push(CodeFile {
+ parent,
+ current: name.to_string(),
+ use_files: vec![],
+ imported_files: vec![],
+ imported_folders: vec![],
+ });
+ let id = FileID(self.files.len() - 1);
+ self.get_folder_mut(parent)
+ .child_files
+ .insert(name.to_string(), id);
+ (id, true)
+ }
+ }
+
+ fn add_folder(&mut self, name: &str, parent: FolderID) -> FolderID {
+ if let Some(id) = self.get_folder(parent).child_folders.get(name) {
+ *id
+ } else {
+ self.folders.push(CodeFolder {
+ parent,
+ child_folders: Default::default(),
+ child_files: Default::default(),
+ current: name.to_string(),
+ });
+ let id = FolderID(self.folders.len() - 1);
+ self.get_folder_mut(parent)
+ .child_folders
+ .insert(name.to_string(), id);
+ id
+ }
+ }
}