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 Sep 17, 2024
2 parents d7ffa62 + f26a724 commit 73404e8
Show file tree
Hide file tree
Showing 15 changed files with 129 additions and 58 deletions.
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mech"
version = "0.2.10"
version = "0.2.11"
authors = ["Corey Montella <[email protected]>"]
description = "Mech is a reactive programming language for building robots, games, and animations."
documentation = "https://mech-lang.org/docs"
Expand All @@ -18,8 +18,8 @@ gitlab = { repository = "mech-lang/mech", branch = "main" }
maintenance = { status = "actively-developed" }

[dependencies]
mech-core = "0.2.10"
mech-syntax = "0.2.10"
mech-core = "0.2.11"
mech-syntax = "0.2.11"
#mech-program = "0.2.2"
#mech-utilities = "0.2.2"

Expand Down Expand Up @@ -69,7 +69,7 @@ mech-utilities = { path = 'src/utilities'}
mech-wasm = { path = 'src/wasm'}

[patch.'https://gitlab.com/mech-lang/core']
mech-core = { path = 'src/core', version = '0.2.10' }
mech-core = { path = 'src/core', version = '0.2.11' }

[patch.'https://gitlab.com/mech-lang/syntax']
mech-syntax = { path = 'src/syntax', version = '0.2.10' }
mech-syntax = { path = 'src/syntax', version = '0.2.11' }
36 changes: 16 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,39 @@
<p align="center">
<img width="500px" src="https://mech-lang.org/img/logo.png">
<img width="500px" src="https://mech-lang.org/img/logo.png" alt="Mech Logo">
</p>

Mech is a language for developing **data-driven**, **reactive** systems like animations, games, and robots. It makes **composing**, **transforming**, and **distributing** data easy, allowing you to focus on the essential complexity of your project.
**Mech** is a language designed for building **data-driven** and **reactive** systems like robots, games, user interfaces, and more. It simplifies **composing**, **transforming**, and **distributing** data, so you can focus on the core complexities of your project.

[Try](https://mech-lang.org/try/) Mech online in your browser, or follow our progress on our [blog](https://mech-lang.org/blog/).
[Try Mech](https://mech-lang.org/try/) online in your browser or stay updated through our [blog](https://mech-lang.org/blog/).

## Documentation
## 📚 Documentation

If this is your first time with Mech, read [Learn Mech in Fifteen Minutes](https://gitlab.com/mech-lang/docs/-/raw/v0.2-beta/III.guides/MechFifteen.mec).
New to Mech? Start with [Learn Mech in Fifteen Minutes](https://gitlab.com/mech-lang/docs/-/raw/v0.2-beta/III.guides/MechFifteen.mec).

Documentation is hosted online at [mech-lang.org](https://mech-lang.org/docs), and is open sourced on [GitHub](http://github.com/mech-lang/docs).
Comprehensive documentation is available at [mech-lang.org](https://mech-lang.org/docs) and open-sourced on [GitHub](http://github.com/mech-lang/docs).

## Installation
## 📂 Download and Install

### Binary
### 💾 From Binary

You can download the latest release for your platform [here](https://github.com/mech-lang/mech/releases).
Download the latest release for your platform [here](https://github.com/mech-lang/mech/releases).

### Source
### 🔨 From Source

You will need to install [Rust](https://www.rust-lang.org/learn/get-started) on a recent nightly release. Follow these instructions to build the Mech language toolchain, which is packaged in a single executable called "mech":
To build Mech from source, you’ll need to install [Rust](https://www.rust-lang.org/learn/get-started) (nightly version). Follow the instructions below to compile the Mech toolchain, bundled in a single executable called `mech`:

```bash
git clone https://gitlab.com/mech-lang/mech
cd mech
cargo build --bin mech --release
```

## Project Roadmap
## 🚧 Project Roadmap

Mech is undergoing a redesign to incorporate state machines into the language.
Mech is being redesigned to integrate state machines into the language, with development happening in the v0.2-beta branch.

This work is happening in the v0.2-beta branch of the repository.
The v0.2 release is planned for October 2024. For more details, check out the [ROADMAP.mec](ROADMAP.mec).

The current target for the release of v0.2 is October 2024.
## ⚖️ License

See [ROADMAP.mec](ROADMAP.mec) for more.

## License

Apache 2.0
Licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0).
2 changes: 1 addition & 1 deletion ROADMAP.mec
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ reshaping it for use in program logic.
- Statement
- [x] VarDefine
- [ ] VarAssign
- [ ] Kind Define
- [x] Kind Define
- [ ] Enum Define
- Matrix
- [x] Multiply
Expand Down
2 changes: 1 addition & 1 deletion src/bin/mech.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use serde_json;


fn main() -> Result<(), MechError> {
let version = "0.2.10";
let version = "0.2.11";
let text_logo = r#"
┌─────────┐ ┌──────┐ ┌─┐ ┌──┐ ┌─┐ ┌─┐
└───┐ ┌───┘ └──────┘ │ │ └┐ │ │ │ │ │
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.10"
version = "0.2.11"
authors = ["Corey Montella <[email protected]>"]
description = "The Mech language runtime."
documentation = "http://docs.mech-lang.org"
Expand Down
25 changes: 11 additions & 14 deletions src/core/README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
<p align="center">
<img width="400px" src="https://mech-lang.org/img/logo.png">
<img width="500px" src="https://mech-lang.org/img/logo.png">
</p>

Mech is a language for developing **data-driven**, **reactive** systems like robots, games, and animations. It makes **composing**, **transforming**, and **distributing** data easy, allowing you to focus on the essential complexity of your project.
Mech is a language for developing **data-driven**, **reactive** systems like animations, games, and robots. It makes **composing**, **transforming**, and **distributing** data easy, allowing you to focus on the essential complexity of your project.

You can try Mech online at [https://mech-lang.org/try](https://mech-lang.org/try).

Usage and installation instructions can be found in the [documentation](https://mech-lang.org/#/docs/index.mec) or the [main Mech repository](https://github.com/mech-lang/mech).

Be sure to follow our [blog](https://mech-lang.org/blog/)([RSS](https://mech-lang.org/feed.xml))!
[Try](https://mech-lang.org/try/) Mech online in your browser, or follow our progress on our [blog](https://mech-lang.org/blog/).

# Core

The language runtime. It's a small dataflow engine that accepts transactions of changes, and applies them to a compute network.

## Contents

- **block** - defines a `Block`, which is the ubiquitous unit of code in Mech. A block is comprised of transformations on input tables. These transformations can either modify existing tables or create new tables.
- **table** - defines a `Table`, the core data structure of Mech. A table is a 2D array of values.
- **column** - defines a `Column`, which is a vector of values.
- **value** - defines a `Value`, a unified datatype for Mech. A value can be empty, a boolean, a string, a reference to another table, a number literal.
- **database** - defines a `Database` of tables. Databases accept `Transactions`, which are sets of `Changes` to the database.
- **function** - defines the standard library for Mech, including basic indexing, mathematical, comparison, and logic functions.
- **error** - defines an `MechError`, which holds the information necessary to track and render error messages.
- **interpreter** - The Mech interpreter, which executes Mech bytecode.
- **value** - Defines `Value`, a unified datatype
- **kind** - Defines `Kind`, which is used to annotate the kind of each varible
- **error** - Define `MechError`, an error type that is used throughout the Mech system.
- **functions** - User defined functions
- **matrix** - Mech `Matrix` wraps NDArray for fast matrix computations
- **nodes** - Defines various nodes which comprise the Mech AST.
- **types** - Defines various types used by the Rust implementation of the Mech compiler.

## Project Status

Expand Down
9 changes: 8 additions & 1 deletion src/core/src/interpreter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,20 @@ fn statement(stmt: &Statement, plan: Plan, symbols: SymbolTableRef, functions: F
Statement::VariableDefine(var_def) => variable_define(&var_def, plan.clone(), symbols.clone(), functions.clone()),
Statement::VariableAssign(_) => todo!(),
Statement::KindDefine(knd_def) => kind_define(&knd_def, plan.clone(), symbols.clone(), functions.clone()),
Statement::EnumDefine(_) => todo!(),
Statement::EnumDefine(enm_def) => enum_define(&enm_def, plan.clone(), symbols.clone(), functions.clone()),
Statement::FsmDeclare(_) => todo!(),
Statement::SplitTable => todo!(),
Statement::FlattenTable => todo!(),
}
}

fn enum_define(enm_def: &EnumDefine, plan: Plan, symbols: SymbolTableRef, functions: FunctionsRef) -> MResult<Value> {
let id = enm_def.name.hash();


Ok(Value::Empty)
}

fn kind_define(knd_def: &KindDefine, plan: Plan, symbols: SymbolTableRef, functions: FunctionsRef) -> MResult<Value> {
let id = knd_def.name.hash();
let kind = kind_annotation(&knd_def.kind.kind, functions.clone())?;
Expand Down
6 changes: 3 additions & 3 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.10"
version = "0.2.11"
authors = ["Corey Montella <[email protected]>"]
description = "A toolchain for compiling textual syntax into Mech blocks."
documentation = "http://docs.mech-lang.org"
Expand All @@ -21,13 +21,13 @@ default = []
no-std = ["mech-core/no-std", "rlibc"]

[dependencies]
mech-core = "0.2.10"
mech-core = "0.2.11"

hashbrown = "0.14.5"
lazy_static = "1.5.0"
nom = "7.1.3"
nom-unicode = "0.3.0"
unicode-segmentation = "1.11.0"
unicode-segmentation = "1.12.0"
rlibc = { version = "=1.0", optional = true }
serde = "1.0.210"
serde_derive = "1.0.210"
Expand Down
15 changes: 15 additions & 0 deletions src/syntax/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ leaf!{box_t_top, "┬", TokenKind::BoxDrawing}
leaf!{box_t_bottom, "┴", TokenKind::BoxDrawing}
leaf!{box_vert, "│", TokenKind::BoxDrawing}

// emoji_grapheme := emoji_grapheme_literal ;
pub fn emoji_grapheme(mut input: ParseString) -> ParseResult<String> {
if let Some(matched) = input.consume_emoji() {
Ok((input, matched))
Expand All @@ -86,6 +87,7 @@ pub fn emoji_grapheme(mut input: ParseString) -> ParseResult<String> {
}
}

// alpha := alpha_literal ;
pub fn alpha(mut input: ParseString) -> ParseResult<String> {
if let Some(matched) = input.consume_alpha() {
Ok((input, matched))
Expand All @@ -94,6 +96,7 @@ pub fn alpha(mut input: ParseString) -> ParseResult<String> {
}
}

// digit := digit_literal ;
pub fn digit(mut input: ParseString) -> ParseResult<String> {
if let Some(matched) = input.consume_digit() {
Ok((input, matched))
Expand All @@ -102,6 +105,7 @@ pub fn digit(mut input: ParseString) -> ParseResult<String> {
}
}

// any := any_character ;
pub fn any(mut input: ParseString) -> ParseResult<String> {
if let Some(matched) = input.consume_one() {
Ok((input, matched))
Expand All @@ -110,6 +114,7 @@ pub fn any(mut input: ParseString) -> ParseResult<String> {
}
}

// forbidden_emoji := box_drawing | other_forbidden_shapes ;
pub fn forbidden_emoji(input: ParseString) -> ParseResult<Token> {
alt((box_t_left,box_tl_round,box_br_round, box_tr_round, box_bl_round, box_vert, box_cross, box_horz, box_t_right, box_t_top, box_t_bottom))(input)
}
Expand All @@ -125,11 +130,13 @@ pub fn emoji(input: ParseString) -> ParseResult<Token> {
Ok((input, Token{kind: TokenKind::Emoji, chars: g.chars().collect::<Vec<char>>(), src_range}))
}

// alpha_token := alpha_literal_token ;
pub fn alpha_token(input: ParseString) -> ParseResult<Token> {
let (input, (g, src_range)) = range(alpha)(input)?;
Ok((input, Token{kind: TokenKind::Alpha, chars: g.chars().collect::<Vec<char>>(), src_range}))
}

// digit_token := digit_literal_token ;
pub fn digit_token(input: ParseString) -> ParseResult<Token> {
let (input, (g, src_range)) = range(digit)(input)?;
Ok((input, Token{kind: TokenKind::Digit, chars: g.chars().collect::<Vec<char>>(), src_range}))
Expand Down Expand Up @@ -228,21 +235,25 @@ pub fn whitespace0(input: ParseString) -> ParseResult<()> {
Ok((input, ()))
}

// whitespace1 := one_or_more_whitespaces ;
pub fn whitespace1(input: ParseString) -> ParseResult<()> {
let (input, _) = many1(whitespace)(input)?;
Ok((input, ()))
}

// space_tab := space | tab ;
pub fn space_tab(input: ParseString) -> ParseResult<Token> {
let (input, space) = alt((space,tab))(input)?;
Ok((input, space))
}

// list_separator := optional_whitespace "," optional_whitespace ;
pub fn list_separator(input: ParseString) -> ParseResult<()> {
let (input,_) = nom_tuple((whitespace0,tag(","),whitespace0))(input)?;
Ok((input, ()))
}

// enum_separator := optional_whitespace "|" optional_whitespace ;
pub fn enum_separator(input: ParseString) -> ParseResult<()> {
let (input,_) = nom_tuple((whitespace0,tag("|"),whitespace0))(input)?;
Ok((input, ()))
Expand Down Expand Up @@ -275,6 +286,7 @@ pub fn number(input: ParseString) -> ParseResult<Number> {
Ok((input, Number::Real(real_num)))
}

// real_number := optional_dash (hexadecimal_literal | decimal_literal | octal_literal | binary_literal | scientific_literal | rational_literal | float_literal | integer_literal) ;
pub fn real_number(input: ParseString) -> ParseResult<RealNumber> {
let (input, neg) = opt(dash)(input)?;
let (input, result) = alt((hexadecimal_literal, decimal_literal, octal_literal, binary_literal, scientific_literal, rational_literal, float_literal, integer_literal))(input)?;
Expand All @@ -285,13 +297,15 @@ pub fn real_number(input: ParseString) -> ParseResult<RealNumber> {
Ok((input, result))
}

// rational_literal := integer_literal "/" integer_literal ;
pub fn rational_literal(input: ParseString) -> ParseResult<RealNumber> {
let (input, RealNumber::Integer(numerator)) = integer_literal(input)? else { unreachable!() };
let (input, _) = slash(input)?;
let (input, RealNumber::Integer(denominator)) = integer_literal(input)? else { unreachable!() };
Ok((input, RealNumber::Rational((numerator,denominator))))
}

// scientific_literal := (float_literal | integer_literal) ("e" | "E") (optional_plus | ε) (optional_dash | ε) (float_literal | integer_literal) ;
pub fn scientific_literal(input: ParseString) -> ParseResult<RealNumber> {
let (input, base) = match float_literal(input.clone()) {
Ok((input, RealNumber::Float(base))) => {
Expand Down Expand Up @@ -454,6 +468,7 @@ pub fn kind_map(input: ParseString) -> ParseResult<Kind> {
Ok((input, Kind::Map(Box::new(key_kind),Box::new(value_kind))))
}

// kind_fxn := "(" kind (list_separator kind)* ")" "=" "(" kind (list_separator kind)* ")" ;
pub fn kind_fxn(input: ParseString) -> ParseResult<Kind> {
let (input, _) = left_parenthesis(input)?;
let (input, input_kinds) = separated_list0(list_separator,kind)(input)?;
Expand Down
5 changes: 5 additions & 0 deletions src/syntax/src/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ pub fn parenthetical_term(input: ParseString) -> ParseResult<Factor> {
Ok((input, frmla))
}

// negate_factor := "-" factor ;
pub fn negate_factor(input: ParseString) -> ParseResult<Factor> {
let (input, _) = dash(input)?;
let (input, expr) = factor(input)?;
Ok((input, Factor::Negate(Box::new(expr))))
}

// not_factor := "not" factor ;
pub fn not_factor(input: ParseString) -> ParseResult<Factor> {
let (input, _) = not(input)?;
let (input, expr) = factor(input)?;
Expand Down Expand Up @@ -261,6 +263,7 @@ pub fn statement_separator(input: ParseString) -> ParseResult<()> {
Ok((input, ()))
}

// function_define := identifier "(" (function_arg (list_separator function_arg)*)? ")" whitespace0 "=" whitespace0 (function_out_args | function_out_arg) define_operator (statement (whitespace1 | statement_separator)*) period ;
pub fn function_define(input: ParseString) -> ParseResult<FunctionDefine> {
let ((input, name)) = identifier(input)?;
let ((input, _)) = left_parenthesis(input)?;
Expand All @@ -276,13 +279,15 @@ pub fn function_define(input: ParseString) -> ParseResult<FunctionDefine> {
Ok((input,FunctionDefine{name,input: input_args,output,statements}))
}

// function_out_args := "(" function_arg (list_separator function_arg)* ")" ;
pub fn function_out_args(input: ParseString) -> ParseResult<Vec<FunctionArgument>> {
let ((input, _)) = left_parenthesis(input)?;
let ((input, args)) = separated_list1(list_separator,function_arg)(input)?;
let ((input, _)) = right_parenthesis(input)?;
Ok((input, args))
}

// function_out_arg := function_arg ;
pub fn function_out_arg(input: ParseString) -> ParseResult<Vec<FunctionArgument>> {
let ((input, arg)) = function_arg(input)?;
Ok((input, vec![arg]))
Expand Down
9 changes: 7 additions & 2 deletions src/syntax/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,16 @@ pub fn mech_code_alt(input: ParseString) -> ParseResult<MechCode> {
}
}

// mech_code := mech_code_alt, "\n" | ";" ;
pub fn comment_token(input: ParseString) -> ParseResult<Token> {
let (input, c) = comment(input)?;
Ok((input, c.text))
}

// mech_code := mech_code_alt, ("\n" | ";" | comment) ;
pub fn mech_code(input: ParseString) -> ParseResult<MechCode> {
let (input, code) = mech_code_alt(input.clone())?;
let (input, _) = many0(space_tab)(input)?;
let (input, _) = alt((new_line, semicolon))(input)?;
let (input, _) = alt((new_line, semicolon, comment_token))(input)?;
Ok((input, code))
}

Expand Down
Loading

0 comments on commit 73404e8

Please sign in to comment.