add escape fn to string, add some ways to write callables
This commit is contained in:
parent
35639cb2c8
commit
2bbeaebd7c
4 changed files with 43 additions and 5 deletions
|
@ -7,7 +7,7 @@ func main { mega | with args ;
|
||||||
while { 1 } {
|
while { 1 } {
|
||||||
catch {
|
catch {
|
||||||
def line "" =line
|
def line "" =line
|
||||||
while { line is-complete not } {
|
while { line repl-is-complete not } {
|
||||||
def s
|
def s
|
||||||
line " > " print readln =s
|
line " > " print readln =s
|
||||||
s "\n" concat concat =line
|
s "\n" concat concat =line
|
||||||
|
@ -44,7 +44,7 @@ func main { mega | with args ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func is-complete { bool | with line ;
|
func repl-is-complete { bool | with line ;
|
||||||
"!!-end" line:contains
|
"!!-end" line:contains
|
||||||
0 line _array :foreach<{ | with char ;
|
0 line _array :foreach<{ | with char ;
|
||||||
char "{" :_char eq
|
char "{" :_char eq
|
||||||
|
|
|
@ -42,7 +42,7 @@ construct _str_ext {
|
||||||
replacee:to-bytes replacement:to-bytes this:to-bytes:replace:to-str
|
replacee:to-bytes replacement:to-bytes this:to-bytes:replace:to-str
|
||||||
}
|
}
|
||||||
find { idx | with search this ;
|
find { idx | with search this ;
|
||||||
search _array this _array :find
|
search _barray this _barray :find
|
||||||
}
|
}
|
||||||
contains { bool | with search this ;
|
contains { bool | with search this ;
|
||||||
search this:find null eq not
|
search this:find null eq not
|
||||||
|
@ -53,6 +53,9 @@ construct _str_ext {
|
||||||
ends-with { bool | with ending this ;
|
ends-with { bool | with ending this ;
|
||||||
ending:to-bytes this:to-bytes:ends-with
|
ending:to-bytes this:to-bytes:ends-with
|
||||||
}
|
}
|
||||||
|
escape { formatted | with this ;
|
||||||
|
"\"" this:replace<"\\" "\\\\">:replace<"\"" "\\\"">:replace<"\n" "\\n">:replace<"\r" "\\r"> concat "\"" concat
|
||||||
|
}
|
||||||
_char { int | with this ;
|
_char { int | with this ;
|
||||||
0 (this _array):get
|
0 (this _array):get
|
||||||
}
|
}
|
||||||
|
|
28
src/lexer.rs
28
src/lexer.rs
|
@ -121,6 +121,31 @@ fn read_block_dyn(
|
||||||
run_as_base: false,
|
run_as_base: false,
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
|
// ., lambda
|
||||||
|
"|" => {
|
||||||
|
let block = read_block_dyn(&str_words[i + 1..], false, ">".to_owned(), compat)?;
|
||||||
|
i += block.2;
|
||||||
|
words.push(Word::Const(Value::Func(AFunc::new(Func {
|
||||||
|
ret_count: 0,
|
||||||
|
to_call: FuncImpl::SPL(block.1),
|
||||||
|
origin: Arc::new(Frame::dummy()),
|
||||||
|
fname: None,
|
||||||
|
name: "dyn-arg".to_owned(),
|
||||||
|
run_as_base: false,
|
||||||
|
}))))
|
||||||
|
}
|
||||||
|
"/" => {
|
||||||
|
let block = read_block_dyn(&str_words[i + 1..], false, "\\".to_owned(), compat)?;
|
||||||
|
i += block.2 + 1;
|
||||||
|
words.push(Word::Const(Value::Func(AFunc::new(Func {
|
||||||
|
ret_count: 0,
|
||||||
|
to_call: FuncImpl::SPL(block.1),
|
||||||
|
origin: Arc::new(Frame::dummy()),
|
||||||
|
fname: None,
|
||||||
|
name: "dyn-direct".to_owned(),
|
||||||
|
run_as_base: false,
|
||||||
|
}))))
|
||||||
|
}
|
||||||
x if x.len() >= 2 && &x[0..2] == "!{" => {
|
x if x.len() >= 2 && &x[0..2] == "!{" => {
|
||||||
words.push(Word::Const(Value::Str(x[2..].to_owned())));
|
words.push(Word::Const(Value::Str(x[2..].to_owned())));
|
||||||
}
|
}
|
||||||
|
@ -255,6 +280,9 @@ fn read_block_dyn(
|
||||||
x if x.starts_with('\"') => {
|
x if x.starts_with('\"') => {
|
||||||
words.push(Word::Const(Value::Str(x[1..].to_owned())));
|
words.push(Word::Const(Value::Str(x[1..].to_owned())));
|
||||||
}
|
}
|
||||||
|
x if x.starts_with('^') => {
|
||||||
|
words.push(Word::Const(Value::Str(x[1..].to_owned())));
|
||||||
|
}
|
||||||
x if x.chars().all(|c| c.is_numeric() || c == '_' || c == '-')
|
x if x.chars().all(|c| c.is_numeric() || c == '_' || c == '-')
|
||||||
&& !x.starts_with('_')
|
&& !x.starts_with('_')
|
||||||
&& x.contains(char::is_numeric) =>
|
&& x.contains(char::is_numeric) =>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, VecDeque},
|
collections::{HashMap, VecDeque},
|
||||||
env::{args, vars},
|
env::{self, args, vars},
|
||||||
fs,
|
fs,
|
||||||
io::{stdin, stdout, Write},
|
io::{stdin, stdout, Write},
|
||||||
ops::{Add, Div, Mul, Rem, Sub},
|
ops::{Add, Div, Mul, Rem, Sub},
|
||||||
|
@ -1128,9 +1128,15 @@ pub fn delete_dir(stack: &mut Stack) -> OError {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn chdir(stack: &mut Stack) -> OError {
|
||||||
|
require_on_stack!(dir, Str, stack, "chdir");
|
||||||
|
env::set_current_dir(dir).map_err(|e| stack.error(ErrorKind::IO(e.to_string())))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn register(r: &mut Stack, o: Arc<Frame>) {
|
pub fn register(r: &mut Stack, o: Arc<Frame>) {
|
||||||
type Fn = fn(&mut Stack) -> OError;
|
type Fn = fn(&mut Stack) -> OError;
|
||||||
let fns: [(&str, Fn, u32); 68] = [
|
let fns: [(&str, Fn, u32); 69] = [
|
||||||
("pop", pop, 0),
|
("pop", pop, 0),
|
||||||
("dup", dup, 2),
|
("dup", dup, 2),
|
||||||
("dup2", dup2, 3),
|
("dup2", dup2, 3),
|
||||||
|
@ -1199,6 +1205,7 @@ pub fn register(r: &mut Stack, o: Arc<Frame>) {
|
||||||
("list-files", list_files, 1),
|
("list-files", list_files, 1),
|
||||||
("delete-file", delete_file, 1),
|
("delete-file", delete_file, 1),
|
||||||
("delete-dir", delete_dir, 1),
|
("delete-dir", delete_dir, 1),
|
||||||
|
("chdir", chdir, 0),
|
||||||
];
|
];
|
||||||
for f in fns {
|
for f in fns {
|
||||||
r.define_func(
|
r.define_func(
|
||||||
|
|
Loading…
Add table
Reference in a new issue