Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
linsyking committed Apr 5, 2023
1 parent 9404fbe commit 367483b
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 10 deletions.
43 changes: 43 additions & 0 deletions docs/Multiple Replacement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Multiple Replacement

It is easy to replace one string with another in meow. However, when you want to replace multiple strings with multiple strings, it is not that easy. This is because the replacement is done in a single pass.

For example,

```catlet
> let "a" "b" let "c" "a" "ac"
bb
```

We want to replace `a` with `b` and `c` with `a`. However, the replacement is done in a single pass, so the first replacement is done, and then the second replacement is done. So, the result is `bb`.

What if we want to do the replacement simultaneously? It's not easy to see.

This feature doesn't need i expression and it is originally designed to be supported in catlet.

First, we have to make sure that the multiple strings are all **independent**. Otherwise the result is not expected.

Implementation code for 2 strings:

```meow
enraw(s) {
"_^" = "";
"_$" = "";
encode(s)
}
enrep(s,x,y) {
enraw(x) = y;
s
}
rep2(s,x,xr,y,yr) {
var repx = enrep(encode(s),x,"x$");
var repy = enrep(repx,y,"y$");
decode({
"x$" = enraw(xr);
"y$" = enraw(yr);
repy
})
}
```
2 changes: 1 addition & 1 deletion docs/Syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ x=dd, y=dd

You can use `var` to declare a variable. The syntax is like `var x = "abc";`. The variable is only visible in the block where it is declared. The right hand side can be any expressions. Note that the right hand side is evaluated in **raw** mode.

When compiling to cat, the compiler will **remove all `var` declarations**. So `var` is simply a **syntax sugar**.
When compiling to catlet, the compiler will **remove all `var` declarations**. So `var` is simply a **syntax sugar**.

For example,

Expand Down
2 changes: 1 addition & 1 deletion docs/i-expr.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# i Expressions

i expressions allow you to evaluate cat expression inside cat expression. This gives us the power to do recursion.
i expressions allow you to evaluate catlet expressions inside catlet expressions. This gives us the power to do recursion.

The fibonacci function can be defined as:

Expand Down
25 changes: 25 additions & 0 deletions examples/syn.meow
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,31 @@ decode(s) {
rep
}

encat(x,y) {
{"_$"=""; x} + {"_^"=""; y}
}

enraw(s) {
"_^" = "";
"_$" = "";
encode(s)
}

enrep(s,x,y) {
enraw(x) = y;
s
}

rep2(s,x,xr,y,yr) {
var repx = enrep(encode(s),x,"x$");
var repy = enrep(repx,y,"y$");
decode({
"x$" = enraw(xr);
"y$" = enraw(yr);
repy
})
}

eq(x,y) {
encode(x) = "F";
encode(y) = "T";
Expand Down
2 changes: 2 additions & 0 deletions examples/token.cat
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
eat x w = x
head x = ! cat cat `eat "` let " " `" eat "` x `" ""`
9 changes: 9 additions & 0 deletions examples/token.meow
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
eat(x,w) {
x
}

head(x) {
var xx = {" " = `" eat "`; x};
!(`eat "` + xx + `" ""`)
}

22 changes: 14 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@ fn main() {
if fp == "repl" {
repl(&mut Box::new(prog::Context::new()));
} else {
let fc = std::fs::read_to_string(fp).expect("failed to open the file");
let res = parse::ProgramParser::new()
.parse(fc.as_str())
.expect("unexpected token!");
let res = read_file(&fp);
let context = &mut Box::new(prog::Context::new());
prog::eval_prog(&res, context);
let trans = prog::translate(&res, context);
Expand All @@ -34,7 +31,19 @@ fn main() {
}
}

fn read_file(path: &str) -> Box<ast::Prog> {
let fc = std::fs::read_to_string(path).expect("failed to open the file");
let res = parse::ProgramParser::new()
.parse(fc.as_str())
.expect("unexpected token!");
res
}

fn repl(context: &mut Box<prog::Context>) {
// Load default module
prog::eval_prog(&read_file("./examples/syn.meow"), context);
println!("default script loaded");

let mut rl = rustyline::DefaultEditor::new().unwrap();
loop {
let line: String;
Expand Down Expand Up @@ -65,10 +74,7 @@ fn repl(context: &mut Box<prog::Context>) {
context.clean();
} else if cmd == &"load" {
let path = cmds.get(1).unwrap();
let fc = std::fs::read_to_string(path).expect("failed to open the file");
let res = parse::ProgramParser::new()
.parse(fc.as_str())
.expect("unexpected token!");
let res = read_file(path);
prog::eval_prog(&res, context);
println!("loaded {}", path);
} else {
Expand Down

0 comments on commit 367483b

Please sign in to comment.