Compare commits

..
55 Commits
Author SHA1 Message Date
raymon c8126f2891 CI_GH: use actions-rs 2022-01-07 16:58:51 +01:00
raymon 0784fc83d5 Add GitHub CI 2022-01-07 16:51:30 +01:00
raymon b456da8fe4 Cleanup main.rs by fixing warnings 2022-01-07 16:47:56 +01:00
raymon bb58370468 Complete crate info 2022-01-07 16:16:01 +01:00
raymon f4027a5a24 Create README.md with LICENCES 2022-01-07 16:15:25 +01:00
raymon 8a834c2003 Cleanup errors 2022-01-07 14:49:02 +01:00
raymon 1c5aaec6a3 Remove instruction prints 2022-01-07 14:10:04 +01:00
raymon e122222d08 Implement copy 2022-01-07 14:07:38 +01:00
raymon 4b75b591ee Implement addv and subv 2022-01-07 12:36:14 +01:00
raymon 29f45000af Extract pointing to mem_address to new instruction
- pointa, point now uses this instruction
2022-01-07 12:33:21 +01:00
raymon e2d076d3e1 Parse constants unsigned 2022-01-07 11:43:56 +01:00
raymon 4d3b7742cc Remove field value from MemCell
- plans for a directly interpreted mblf mode have been scrapped
-  it's MBLF, not MBNF
2022-01-06 21:58:24 +01:00
raymon 4cc28a5c2f Remove addb and subb
- add and sub will be optimized based on the operand
2022-01-06 21:40:32 +01:00
raymon bb896d7383 Extract non-expanding instructions to to_bf 2022-01-06 20:39:12 +01:00
raymon 5edcbbfd7c Remove match on Rule::instruction 2022-01-06 20:07:34 +01:00
raymon 21cc6cb920 Implement #include 2022-01-06 19:55:44 +01:00
raymon 53c5b66222 Implement loopBlock 2022-01-05 13:09:51 +01:00
raymon f944a28357 Implement print 2022-01-05 13:09:16 +01:00
raymon adc77acc42 Implement getchr 2022-01-05 13:08:55 +01:00
raymon 4fd1497e7b Implement setz 2022-01-05 13:07:36 +01:00
raymon cbeed38a5b Implement basic add and sub 2022-01-05 13:04:14 +01:00
raymon 756e21e7fd Remove field is_allocated from MemCell 2022-01-05 12:58:49 +01:00
raymon bb63782711 Implement pointm 2022-01-05 12:26:27 +01:00
raymon 0ac4731f8a Implement point 2022-01-05 12:26:17 +01:00
raymon 1673690956 Implement delvar 2022-01-04 23:25:10 +01:00
raymon 189a57f884 Panic on duplicate variable creation 2022-01-04 10:18:53 +01:00
raymon df38c66d83 Implement var 2022-01-04 10:02:47 +01:00
raymon 5e2497b2ad Fill-in struct fields 2022-01-04 10:02:47 +01:00
raymon e712f40738 Pass state to instruct
state will store:
- variable positions
2022-01-02 20:25:12 +01:00
raymon 2ac2306b95 Allow newlines between comments and statements 2022-01-01 18:40:15 +01:00
raymon 9cad628caf Cleanup grammar file
- Formatting
- Remove generic `operator` and `operand`
  - used for testing
2022-01-01 18:31:06 +01:00
raymon 0a03cfa416 Match macro #include 2022-01-01 18:29:00 +01:00
raymon c868b5f052 Explicitly allow spacing before loopBlockEnd
- Inherited prefixed `spacing*` only applied to loopBlockStart,
- as the rule from statement only allowed spacing before the entire loopBlock
2022-01-01 17:33:35 +01:00
raymon 53d712db4f Allow most common word separators for variables
- Also includes '?' suffix for bools
2021-12-31 09:24:14 +01:00
raymon d0805b55a7 Correct example.mblf with no-arg print 2021-12-30 23:29:00 +01:00
raymon 42c45c3835 Extend numeric operations to constant operations
- Besides decNums and hexNums, characters are also valid
2021-12-30 23:27:30 +01:00
raymon 5c450b2c6a Match all instructions without arguments 2021-12-30 22:47:16 +01:00
raymon c56770d604 Match all instructions with number argument 2021-12-30 22:46:04 +01:00
raymon 29ed49b554 Print other Rules to stdout
- Entire parsed file in readable form to stdout
2021-12-30 14:28:08 +01:00
raymon 974c6b8021 Match all instructions with variable argument 2021-12-30 14:28:08 +01:00
raymon e3883f2ae2 Use built-in NEWLINE Rule 2021-12-26 20:41:59 +01:00
raymon 02b392d96e Allow extra newlines between statements 2021-12-26 20:38:31 +01:00
raymon 629580e628 Allow comments on their own line 2021-12-26 20:22:07 +01:00
raymon a381e148f0 Allow indented statements 2021-12-26 20:22:07 +01:00
raymon 298513eb7f Allow either spaces or tabs as spacing 2021-12-26 19:47:40 +01:00
raymon 6eb61ad83d Extract newline grammar rule 2021-12-26 19:47:25 +01:00
raymon 91a4c8c0b8 Enforce newlines around body of loopBlock
- The start and end of the loopBlock should be on their own line
2021-12-26 19:42:53 +01:00
raymon bc99a9d96b Ensure operand is optional: only 0 or 1 2021-12-26 19:31:06 +01:00
raymon 9fbf521174 Allow nested loopBlocks
- loopBlocks now contain statements i.o. instructions
2021-12-26 19:23:37 +01:00
raymon 6804d2aac3 Extract IO out of instruct
- Attach fail case only once on main
2021-10-20 21:46:19 +02:00
raymon d0d82f1831 Formatting 2021-10-20 21:21:25 +02:00
raymon e20cfcbb4a Parse till operators 2021-10-20 21:21:02 +02:00
raymon 0a157cf02e Start with Pest Parser 2021-10-19 12:19:08 +02:00
raymon 389364a2dc Add CLI
- takes input-file, copies to output-file
2021-09-29 11:05:57 +02:00
raymon 805c7f5dd2 Init 2021-09-29 11:03:59 +02:00
5 changed files with 15 additions and 76 deletions
Generated
+2 -2
View File
@@ -1,6 +1,6 @@
# 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 = 4 version = 3
[[package]] [[package]]
name = "ansi_term" name = "ansi_term"
@@ -144,7 +144,7 @@ checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
[[package]] [[package]]
name = "mblf" name = "mblf"
version = "0.1.1" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"pest", "pest",
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "mblf" name = "mblf"
version = "0.1.1" version = "0.1.0"
edition = "2018" edition = "2018"
description = """ description = """
The MBLF-To-BF compiler written in Rust with Pest. The MBLF-To-BF compiler written in Rust with Pest.
@@ -9,7 +9,7 @@ MBLF is a programming language on top of the esoteric programming language Brain
authors = ["Raymon Zutekouw <contact@raymon.dev>"] authors = ["Raymon Zutekouw <contact@raymon.dev>"]
repository = "https://codeberg.org/MeltingSilicon/compiler-mblf" repository = "https://github.com/MBLF-Project/mblf"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
keywords = ["compiler", "mblf", "brainfuck", "pest"] keywords = ["compiler", "mblf", "brainfuck", "pest"]
+1 -1
View File
@@ -1,6 +1,6 @@
# MBLF # MBLF
<img src="logo.png" alt="MBLF-logo" width="100px" /> <img src="https://avatars.githubusercontent.com/u/77209611?s=200&v=4" alt="MBLF-logo" width="100px" />
MBLF is a programming language on top of the esoteric programming language Brainfuck. MBLF is a programming language on top of the esoteric programming language Brainfuck.
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

+10 -71
View File
@@ -24,14 +24,13 @@ struct MemCell {
} }
impl MemCell { impl MemCell {
pub fn allocate_to(address: u32) -> Self { pub fn allocate(address: u32) -> Self {
Self { address } Self { address }
} }
} }
struct State { struct State {
alloc_cnt: u32, alloc_cnt: u32,
free_list: Vec<u32>,
mem_pointer: u32, mem_pointer: u32,
variables: HashMap<String, MemCell>, variables: HashMap<String, MemCell>,
} }
@@ -72,35 +71,23 @@ fn to_bf(rule: Rule, operand: &str, state: &mut State, out: &mut Builder) {
match rule { match rule {
Rule::var => { Rule::var => {
let variable_name = operand; let variable_name = operand;
let mem_extension: u32;
let new_address: u32;
if !state.free_list.is_empty() {
new_address = state.free_list.pop().unwrap();
mem_extension = 0;
} else {
new_address = state.alloc_cnt;
mem_extension = 1;
}
if let Some(_v) = state.variables.insert( if let Some(_v) = state.variables.insert(
String::from(variable_name), String::from(variable_name),
MemCell::allocate_to(new_address), MemCell::allocate(state.alloc_cnt),
) { ) {
panic!("Variable '{}' already exists", variable_name); panic!("Variable '{}' already exists", variable_name);
} }
state.alloc_cnt += mem_extension; state.alloc_cnt += 1;
} }
Rule::delvar => { Rule::delvar => {
let variable_name = operand; let variable_name = operand;
let memcell = state if state
.variables .variables
.get(variable_name) .remove(&String::from(variable_name))
.ok_or_else(|| format!("Variable '{variable_name}' did not exists")) .is_none()
.unwrap(); {
state.free_list.push(memcell.address); panic!("Variable '{}' did not exists", variable_name);
state.variables.remove(&String::from(variable_name)); }
} }
Rule::point => { Rule::point => {
let variable_name = operand; let variable_name = operand;
@@ -215,7 +202,7 @@ fn instruct(statement: Pair<Rule>, state: &mut State, out: &mut Builder) {
Rule::include => { Rule::include => {
let file_path_raw = extract_operand(statement); let file_path_raw = extract_operand(statement);
let file_path = &file_path_raw[1..file_path_raw.len() - 1]; let file_path = &file_path_raw[1..file_path_raw.len() - 1];
let content = std::fs::read_to_string(file_path).unwrap(); let content = std::fs::read_to_string(&file_path).unwrap();
let parsed_file = MblfParser::parse(Rule::file, &content) let parsed_file = MblfParser::parse(Rule::file, &content)
.expect("Parse Error") .expect("Parse Error")
.next() .next()
@@ -247,7 +234,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut state = State { let mut state = State {
alloc_cnt: 0, alloc_cnt: 0,
free_list: Vec::new(),
mem_pointer: 0, mem_pointer: 0,
variables: HashMap::new(), variables: HashMap::new(),
}; };
@@ -263,50 +249,3 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
Ok(()) Ok(())
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_constant() {
assert_eq!(parse_constant("42"), Ok(42));
assert_eq!(parse_constant("0x2A"), Ok(42));
assert_eq!(parse_constant("\"*\""), Ok(42));
assert!(
matches!(parse_constant("\'*\'"), Err(std::num::ParseIntError { .. })),
"Char literals are declared with \"_\", not \'_\'"
);
}
#[test]
fn test_reuse_of_free_memcells() {
let mut builder = Builder::default();
let mut state = State {
alloc_cnt: 0,
free_list: Vec::new(),
mem_pointer: 0,
variables: HashMap::new(),
};
to_bf(Rule::var, "abc", &mut state, &mut builder);
assert_eq!(state.alloc_cnt, 1);
to_bf(Rule::delvar, "abc", &mut state, &mut builder);
assert_eq!(
state.alloc_cnt, 1,
"allocation should not be shrunken, that is too costly"
);
to_bf(Rule::var, "def", &mut state, &mut builder);
assert_ne!(
state.alloc_cnt, 2,
"the just de-allocated memorycell should be re-used"
);
assert_eq!(
state.alloc_cnt, 1,
"alloc, dealloc, alloc has a max usage of one memorycell"
);
}
}