diff --git a/spl/json.spl b/spl/json.spl new file mode 100644 index 0000000..b49f5c7 --- /dev/null +++ b/spl/json.spl @@ -0,0 +1,30 @@ + +construct json namespace { + _StringyJSON + ; + props-to-sjson { s | with spaces props this ; + props:last:get<1> dup null eq not if { + "\"" swap _str :replace<"\\" "\\\\">:replace<"\"" "\\\""> concat "\"" concat 2 stop + } pop + "{" + props + :iter + :filter<{ b | :to-stack pop with key ; key ":" eq not key ";" eq not and }> + :map<{ s | + :to-stack with key value ; + "\"" + key :replace<"\\" "\\\\">:replace<"\"" "\\\""> concat + "\":" concat spaces if { " " concat } + spaces value properties this:props-to-json concat + }> + :join<", "> concat + "}" concat + } +} + +construct json:_StringyJSON { + ; + sjson { s | with spaces this ; + spaces this properties json:props-to-sjson + } +} diff --git a/spl/std.spl b/spl/std.spl index 90b8931..26d0ff8 100644 --- a/spl/std.spl +++ b/spl/std.spl @@ -717,8 +717,8 @@ func _'match-else-error { | } func _'match-else-push { | - if { - pop + dup if { + swap pop } } diff --git a/src/lexer.rs b/src/lexer.rs index d11c747..d9fed26 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -260,19 +260,17 @@ fn read_block_dyn( "=" => { if str_words[i + 1] == ">" { i += 1; - let pushing = if str_words[i + 1] == "?" { + let cword = &str_words[i + 1]; + if cword.contains(|c| c == '?' || c == '!') { i += 1; + } + let pushing = if cword.contains('?') { words.push(Word::Call("dup".to_owned(), false, 0)); true } else { false }; - let throwing = if str_words[i + 1] == "!" { - i += 1; - true - } else { - false - }; + let throwing = cword.contains('!'); if str_words[i + 1] == "[" { i += 1; let mut block = diff --git a/src/stdlib.rs b/src/stdlib.rs index 58f6389..a1d0cad 100644 --- a/src/stdlib.rs +++ b/src/stdlib.rs @@ -17,6 +17,7 @@ pub const SERVER: &str = include_str!("../spl/server.spl"); pub const HTTP_SERVER: &str = include_str!("../spl/httpserver/base.spl"); pub const HTTP_SERVER_STATIC: &str = include_str!("../spl/httpserver/static.spl"); pub const LINKEDLIST: &str = include_str!("../spl/linkedlist.spl"); +pub const JSON: &str = include_str!("../spl/json.spl"); pub const NOP: &str = ""; pub fn register(runtime: &mut Runtime) { @@ -38,6 +39,7 @@ pub fn register(runtime: &mut Runtime) { insert("httpserver/base.spl", HTTP_SERVER); insert("httpserver/static.spl", HTTP_SERVER_STATIC); insert("linkedlist.spl", LINKEDLIST); + insert("json.spl", JSON); insert("nop.spl", NOP); } } diff --git a/test.spl b/test.spl index 4f27358..6a0d2b8 100644 --- a/test.spl +++ b/test.spl @@ -327,6 +327,8 @@ func main { int | with args ; } } + ^ok =>? ^error not if { println } +