From bd4253d6d396fb27d6e5f13a9c94831d0e9ae465 Mon Sep 17 00:00:00 2001 From: jiyinyiyong Date: Sun, 19 Sep 2021 03:58:40 +0800 Subject: [PATCH] try stupid nested expression; bump 0.1.1 --- .github/workflows/publish.yaml | 7 +++-- .github/workflows/test.yaml | 7 +++-- Cargo.toml | 2 +- README.md | 38 ++++++++++++++++++++++++ examples/nested.cirru | 14 +++++++++ src/parser.rs | 54 +++++++++++++++++++++++++++++++--- 6 files changed, 111 insertions(+), 11 deletions(-) create mode 100644 examples/nested.cirru diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 1c03110..ca98626 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -14,9 +14,10 @@ jobs: with: toolchain: stable - - run: cargo run examples/hello.cirru - - run: cargo run examples/sum.cirru - - run: cargo run examples/assert.cirru + - run: cargo run -- -S examples/hello.cirru + - run: cargo run -- -S examples/sum.cirru + - run: cargo run -- -S examples/assert.cirru + - run: cargo run -- -S examples/nested.cirru # - run: cargo test diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 23e60a6..97a2c05 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -16,6 +16,7 @@ jobs: with: toolchain: stable - - run: cargo run examples/hello.cirru - - run: cargo run examples/sum.cirru - - run: cargo run examples/assert.cirru + - run: cargo run -- -S examples/hello.cirru + - run: cargo run -- -S examples/sum.cirru + - run: cargo run -- -S examples/assert.cirru + - run: cargo run -- -S examples/nested.cirru diff --git a/Cargo.toml b/Cargo.toml index 1f071fa..5e0a9da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "calx_vm" -version = "0.1.0" +version = "0.1.1" authors = ["jiyinyiyong "] edition = "2018" license = "MIT" diff --git a/README.md b/README.md index 5ae8c42..fe3a4a6 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,44 @@ calx -S hello.cirru calx -D hello.cirru ``` +### Syntax Sugar + +Code of: + +```cirru +fn main () + i.add + const 1 + i.mul + const 2 + const 3 + + echo + dup + + assert "|expected 7" + i.eq + const 7 +``` + +is desugared to: + +```cirru +fn main () + const 2 + const 3 + i.mul + const 1 + i.add + + dup + echo + + const 7 + i.eq + assert "|expected 7" +``` + ### Instructions Highly inspired by: diff --git a/examples/nested.cirru b/examples/nested.cirru new file mode 100644 index 0000000..8440d18 --- /dev/null +++ b/examples/nested.cirru @@ -0,0 +1,14 @@ + +fn main () + i.add + const 1 + i.mul + const 2 + const 3 + + echo + dup + + assert "|expected 7" + i.eq + const 7 diff --git a/src/parser.rs b/src/parser.rs index ef4fa84..eaf2d37 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -43,11 +43,14 @@ pub fn parse_function(nodes: &[Cirru]) -> Result { let mut ptr_base: usize = 0; for (idx, line) in nodes.iter().enumerate() { if idx >= 3 { - let instrs = parse_instr(ptr_base, line)?; + for expanded in extract_nested(line)? { + // println!("expanded {}", expanded); + let instrs = parse_instr(ptr_base, &expanded)?; - for instr in instrs { - ptr_base += 1; - body.push(instr); + for instr in instrs { + ptr_base += 1; + body.push(instr); + } } } } @@ -423,3 +426,46 @@ pub fn parse_types(xs: &Cirru) -> Result<(Vec, Vec), String> } } } + +/// rather stupid function to extract nested calls before current call +/// TODO better have some tests +pub fn extract_nested(xs: &Cirru) -> Result, String> { + match xs { + Cirru::Leaf(x) => Err(format!("not extracting leaf: {}", x)), + Cirru::List(ys) => match ys.get(0) { + None => Err(String::from("unexpected empty expression")), + Some(Cirru::List(zs)) => Err(format!("unexpected nested instruction name: {:?}", zs)), + Some(Cirru::Leaf(zs)) => match zs.as_str() { + "block" | "loop" => { + let mut chunk: Vec = vec![Cirru::Leaf(zs.to_string())]; + for (idx, y) in ys.iter().enumerate() { + if idx > 0 { + for e in extract_nested(y)? { + chunk.push(e); + } + } + } + Ok(vec![Cirru::List(chunk)]) + } + _ => { + let mut pre: Vec = vec![]; + let mut chunk: Vec = vec![Cirru::Leaf(zs.to_string())]; + for (idx, y) in ys.iter().enumerate() { + if idx > 0 { + match y { + Cirru::Leaf(_) => chunk.push(y.to_owned()), + Cirru::List(_) => { + for e in extract_nested(y)? { + pre.push(e); + } + } + } + } + } + pre.push(Cirru::List(chunk)); + Ok(pre) + } + }, + }, + } +}