Skip to content

Commit

Permalink
Merge branch 'main' of https://gitlab.com/mech-lang/mech
Browse files Browse the repository at this point in the history
  • Loading branch information
cmontella committed Jul 22, 2024
2 parents 198cde4 + dc4bffd commit a9008e7
Show file tree
Hide file tree
Showing 31 changed files with 5,572 additions and 9,480 deletions.
14 changes: 7 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mech"
version = "0.2.2"
version = "0.2.3"
authors = ["Corey Montella <[email protected]>"]
description = "Toolchain for the Mech programming language."
documentation = "https://mech-lang.org/docs"
Expand All @@ -18,20 +18,20 @@ gitlab = { repository = "mech-lang/mech", branch = "main" }
maintenance = { status = "actively-developed" }

[dependencies]
mech-core = "0.2.2"
mech-syntax = {version = "0.2.2", features = ["lang-server"]}
mech-core = "0.2.3"
mech-syntax = "0.2.3"
#mech-program = "0.2.2"
mech-utilities = "0.2.2"
#mech-utilities = "0.2.2"

clap = {version = "4.5.8", features = ["cargo"]}
colored = "2.1.0"
#nom = "7.1.3"
#hashbrown = "0.14.5"
#reqwest = {version = "0.12.4", features = ["blocking"]}
bincode = "1.3.3"
#serde = "1.0.203"
#serde_derive = "1.0.203"
#serde_json = "1.0.117"
serde = "1.0.204"
serde_derive = "1.0.204"
serde_json = "1.0.120"
crossbeam-channel = "0.5.13"
#seahash = "4.1.0"
crossterm = "0.27.0"
Expand Down
30 changes: 21 additions & 9 deletions src/bin/mech.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#![feature(hash_extract_if)]
#![allow(warnings)]
use mech::format_parse_tree;
use mech_core::*;
use mech_syntax::parser2;
use mech_syntax::parser;
//use mech_syntax::analyzer::*;
use mech_syntax::interpreter::*;
use std::time::Instant;
Expand All @@ -20,9 +21,11 @@ use tabled::{
settings::{object::Rows,Panel, Span, Alignment, Modify, Style},
Tabled,
};
use serde_json;


fn main() -> Result<(), MechError> {
let version = "0.2.2";
let version = "0.2.3";
let text_logo = r#"
┌─────────┐ ┌──────┐ ┌─┐ ┌──┐ ┌─┐ ┌─┐
└───┐ ┌───┘ └──────┘ │ │ └┐ │ │ │ │ │
Expand Down Expand Up @@ -56,13 +59,15 @@ fn main() -> Result<(), MechError> {
let mut intrp = Interpreter::new();
if let Some(mech_paths) = matches.get_one::<String>("mech_paths") {
let s = fs::read_to_string(&mech_paths).unwrap();
match parser2::parse(&s) {
match parser::parse(&s) {
Ok(tree) => {
let result = intrp.interpret(&tree);
let pretty_json = format_parse_tree(&tree);

let debug_flag = matches.get_flag("debug");
if debug_flag {
let tree_hash = hash_str(&format!("{:#?}", tree));
let syntax_tree_str = format!("Tree Hash: {:?}\n{:#?}", tree_hash, tree);
let syntax_tree_str = format!("Tree Hash: {:?}\n{}", tree_hash, pretty_json);

let mut interpreter_str = format!("Symbols: {:#?}\n", intrp.symbols);
interpreter_str = format!("{}Plan:\n", interpreter_str);
Expand All @@ -76,7 +81,10 @@ fn main() -> Result<(), MechError> {
for fxn in intrp.plan.borrow().iter() {
fxn.solve();
}
let result_str = format!("{:#?}", result);
let result_str = match result {
Ok(r) => format!("{}", r.pretty_print()),
Err(err) => format!("{:?}", err),
};

let data = vec!["🌳 Syntax Tree", &syntax_tree_str,
"💻 Interpreter", &interpreter_str,
Expand All @@ -88,12 +96,16 @@ fn main() -> Result<(), MechError> {

println!("{table}");
} else {
println!("{:#?}", result);
let result_str = match result {
Ok(r) => format!("{}", r.pretty_print()),
Err(err) => format!("{:?}", err),
};
println!("{}", result_str);
}
},
Err(err) => {
if let MechErrorKind::ParserError(report, _) = err.kind {
parser2::print_err_report(&s, &report);
parser::print_err_report(&s, &report);
} else {
panic!("Unexpected error type");
}
Expand Down Expand Up @@ -125,7 +137,7 @@ fn main() -> Result<(), MechError> {
io::stdout().flush().unwrap();
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
match parser2::parse(&input) {
match parser::parse(&input) {
Ok(tree) => {
let result = intrp.interpret(&tree);
match result {
Expand All @@ -135,7 +147,7 @@ fn main() -> Result<(), MechError> {
}
Err(err) => {
if let MechErrorKind::ParserError(report, _) = err.kind {
parser2::print_err_report(&input, &report);
parser::print_err_report(&input, &report);
} else {
panic!("Unexpected error type");
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mech-core"
version = "0.2.2"
version = "0.2.3"
authors = ["Corey Montella <[email protected]>"]
description = "The Mech language runtime."
documentation = "http://docs.mech-lang.org"
Expand Down
1 change: 1 addition & 0 deletions src/core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub enum MechErrorKind {
PendingExpression, // id of pending variable
PendingTable(u64), // TableId of pending table
DimensionMismatch(Vec<(Rows,Cols)>), // Argument dimensions are mismatched ((row,col),(row,col))
UnhandledIndexKind,
//MissingColumn((TableId,TableIndex)), // The identified table is missing a needed column
//ColumnKindMismatch(Vec<ValueKind>), // Excepted kind versus given kind
//SubscriptOutOfBounds(((Rows,Cols),(Rows,Cols))), // (target) vs (actual) index
Expand Down
6 changes: 4 additions & 2 deletions src/core/src/nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,8 @@ impl Term {
pub enum Factor {
Term(Box<Term>),
Expression(Box<Expression>),
Negated(Box<Factor>),
Negate(Box<Factor>),
Not(Box<Factor>),
Transpose(Box<Factor>),
}

Expand All @@ -900,7 +901,8 @@ impl Factor {
match self {
Factor::Term(x) => x.tokens(),
Factor::Expression(x) => x.tokens(),
Factor::Negated(x) => x.tokens(),
Factor::Negate(x) => x.tokens(),
Factor::Not(x) => x.tokens(),
Factor::Transpose(x) => x.tokens(),
}
}
Expand Down
163 changes: 161 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
pub extern crate mech_core as core;
pub extern crate mech_syntax as syntax;
//pub extern crate mech_program as program;
pub extern crate mech_utilities as utilities;
//pub extern crate mech_utilities as utilities;

//mod repl;

pub use mech_core::*;
use mech_core::nodes::Program;
//pub use mech_syntax::compiler::*;
//pub use mech_program::*;
pub use mech_utilities::*;
//pub use mech_utilities::*;
//pub use self::repl::*;

extern crate colored;
Expand All @@ -40,6 +41,164 @@ lazy_static! {
static ref CORE_MAP: Mutex<HashMap<SocketAddr, (String, SystemTime)>> = Mutex::new(HashMap::new());
}

pub fn format_parse_tree(program: &Program) -> String {
let json_string = serde_json::to_string_pretty(&program).unwrap();

let depth = |line: &str|->usize{line.chars().take_while(|&c| c == ' ').count()};
let mut result = String::new();
let lines: Vec<&str> = json_string.lines().collect();
result.push_str("Program\n");
for (index, line) in lines.iter().enumerate() {
let trm = line.trim();
if trm == "}" ||
trm == "},"||
trm == "{" ||
trm == "[" ||
trm == "],"||
trm == "]" {
continue;
}

// Count leading spaces to determine depth
let d = depth(line);
// Construct the tree-like prefix
let mut prefix = String::new();
for _ in 0..d {
prefix.push_str(" ");
}
if index == lines.len() {
prefix.push_str("└ ");
} else {
if depth(lines[index + 1]) != d {
prefix.push_str("└ ");
} else {
prefix.push_str("├ ");
}
}
let trm = line.trim();
let trm = trm.trim_end_matches('{')
.trim_start_matches('"')
.trim_end_matches(':')
.trim_end_matches('"')
.trim_end_matches('[');
prefix.push_str(trm);

// Append formatted line to result
result.push_str(&prefix);
result.push('\n');
result = result.replace("\":", "");
}
let mut indexed_str = IndexedString::new(&result);
'rows: for i in 0..indexed_str.rows {
let rowz = &indexed_str.index_map[i];
for j in 0..rowz.len() {
let c = match indexed_str.get(i,j) {
Some(c) => c,
None => continue,
};
if c == '└' {
for k in i+1..indexed_str.rows {
match indexed_str.get(k,j) {
Some(c2) => {
if c2 == '└' {
indexed_str.set(i,j,'├');
for l in i+1..k {
match indexed_str.get(l,j) {
Some(' ') => {indexed_str.set(l,j,'│');},
Some('└') => {indexed_str.set(l,j,'├');},
_ => (),
}
}
} else if c2 == ' ' {
continue;
} else {
continue 'rows;
}
},
None => continue,
}

}
} else if c == ' ' || c == '│' {
continue;
} else {
continue 'rows;
}
}
}
indexed_str.to_string()
}

#[derive(Clone, Debug, PartialEq, Eq)]
struct IndexedString {
pub data: Vec<char>,
pub index_map: Vec<Vec<usize>>,
pub rows: usize,
pub cols: usize,
}

impl IndexedString {
fn new(input: &str) -> Self {
let mut data = Vec::new();
let mut index_map = Vec::new();
let mut current_row = 0;
let mut current_col = 0;
index_map.push(Vec::new());
for c in input.chars() {
data.push(c);
if c == '\n' {
index_map.push(Vec::new());
current_row += 1;
current_col = 0;
} else {
index_map[current_row].push(data.len() - 1);
current_col += 1;
}
}
let rows = index_map.len();
let cols = if rows > 0 { index_map[0].len() } else { 0 };
IndexedString {
data,
index_map,
rows,
cols,
}
}
fn to_string(&self) -> String {
self.data.iter().collect()
}
fn get(&self, row: usize, col: usize) -> Option<char> {
if row < self.rows {
let rowz = &self.index_map[row];
if col < rowz.len() {
let index = self.index_map[row][col];
Some(self.data[index])
} else {
None
}
} else {
None
}
}

fn set(&mut self, row: usize, col: usize, new_char: char) -> Result<(), String> {
if row < self.rows {
let row_indices = &mut self.index_map[row];
if col < row_indices.len() {
let index = row_indices[col];
self.data[index] = new_char;
Ok(())
} else {
Err("Column index out of bounds".to_string())
}
} else {
Err("Row index out of bounds".to_string())
}
}


}

//extern crate nom;

/*
Expand Down
8 changes: 2 additions & 6 deletions src/syntax/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mech-syntax"
version = "0.2.2"
version = "0.2.3"
authors = ["Corey Montella <[email protected]>"]
description = "A toolchain for compiling textual syntax into Mech blocks."
documentation = "http://docs.mech-lang.org"
Expand All @@ -19,10 +19,9 @@ maintenance = { status = "actively-developed" }
[features]
default = []
no-std = ["mech-core/no-std", "rlibc"]
lang-server = ["tower-lsp", "tokio"]

[dependencies]
mech-core = "0.2.2"
mech-core = "0.2.3"

hashbrown = "0.14.5"
lazy_static = "1.4.0"
Expand All @@ -40,9 +39,6 @@ libm = "0.2.8"
simba = "0.9.0"
paste = "1.0.15"

tower-lsp = {version = "0.20.0", optional = true}
tokio = { version = "1.37.0", features = ["full"], optional = true }

[dependencies.num-traits]
version = "0.2.19"
default-features = false
Expand Down
Loading

0 comments on commit a9008e7

Please sign in to comment.