diff --git a/install.spl b/install.spl index aa19deb..09899c5 100644 --- a/install.spl +++ b/install.spl @@ -4,6 +4,7 @@ func main { mega | [ "sudo" "mkdir" "/usr/lib/spl" ] command-wait; [ "sh" "-c" "sudo cp *.spl /usr/lib/spl" ] command-wait; [ "cargo" "build" "--release" ] command-wait; + [ "sudo" "rm" "/bin/spl" ] command-wait; [ "sudo" "cp" "target/release/spl" "/bin" ] command-wait; "make sure its executable"; diff --git a/repl.spl b/repl.spl new file mode 100644 index 0000000..c900e28 --- /dev/null +++ b/repl.spl @@ -0,0 +1,26 @@ + +func main { mega | with args ; + "REPL" =program-name + while { 1 } { + catch { + " > " print readln dyn-read exec2 "\n" print + } + with { with err ; + err:message dup null eq if { + pop + "Uncaught error." + } err:trace + + with msg trace ; + program-name dup if { + program-name print " panicked at:" println + } not if { + "Program panicked at:" println + } + &println trace:foreach + "\nPanic message:" println + " " print msg println + "\nRecovering." println + } + } +} diff --git a/src/dyn_fns.rs b/src/dyn_fns.rs index 300008f..35d0c43 100644 --- a/src/dyn_fns.rs +++ b/src/dyn_fns.rs @@ -1,7 +1,7 @@ use std::sync::Arc; -use crate::{lexer, runtime::*}; use crate::*; +use crate::{lexer, runtime::*}; pub fn dyn_dump(stack: &mut Stack) -> OError { Words { diff --git a/src/lexer.rs b/src/lexer.rs index 52d7206..6f6af3e 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -21,6 +21,9 @@ pub fn lex(input: String) -> Result { } fn read_block(str_words: &[String], isfn: bool) -> Result<(Option, Words, usize), LexerError> { + if str_words.len() == 0 { + return Ok((None, Words::new(Vec::new()), 0)); + } let mut rem = None; let mut words = Vec::new(); let mut i = 0; diff --git a/src/std_fns.rs b/src/std_fns.rs index 41e604f..6f682bf 100644 --- a/src/std_fns.rs +++ b/src/std_fns.rs @@ -20,7 +20,12 @@ macro_rules! type_err { macro_rules! array { ($stack:expr, $i:expr) => { - || $stack.error(ErrorKind::PropertyNotFound("array".to_owned(), $i.to_string())) + || { + $stack.error(ErrorKind::PropertyNotFound( + "array".to_owned(), + $i.to_string(), + )) + } }; } @@ -511,28 +516,40 @@ pub fn exec(stack: &mut Stack) -> OError { }; unsafe { let f = stack.pop_frame(0); - let f1 = stack.pop_frame(0); - a.to_call.call(stack)?; - stack.push_frame(f1); + let r = a.to_call.call(stack); stack.push_frame(f); + r } - Ok(()) } pub fn exec2(stack: &mut Stack) -> OError { let Value::Func(a) = stack.pop().lock_ro().native.clone() else { return stack.err(ErrorKind::InvalidCall("exec2".to_owned())) }; + unsafe { + let f = stack.pop_frame(0); + let f1 = stack.pop_frame(0); + let r = a.to_call.call(stack); + stack.push_frame(f1); + stack.push_frame(f); + r + } +} + +pub fn exec3(stack: &mut Stack) -> OError { + let Value::Func(a) = stack.pop().lock_ro().native.clone() else { + return stack.err(ErrorKind::InvalidCall("exec3".to_owned())) + }; unsafe { let f = stack.pop_frame(0); let f1 = stack.pop_frame(0); let f2 = stack.pop_frame(0); - a.to_call.call(stack)?; + let r = a.to_call.call(stack); stack.push_frame(f2); stack.push_frame(f1); stack.push_frame(f); + r } - Ok(()) } pub fn stop(stack: &mut Stack) -> OError { @@ -768,13 +785,23 @@ pub fn acopy(stack: &mut Stack) -> OError { } pub fn throw(stack: &mut Stack) -> OError { - let kind = ErrorKind::CustomObject(stack.pop()); - stack.err(kind) + let obj = stack.pop(); + if let Value::Str(ref s) = obj.lock_ro().native { + if obj.lock_ro().kind.lock_ro().get_id() + == get_type("str") + .expect("str type must exist") + .lock_ro() + .get_id() + { + stack.err(ErrorKind::Custom(s.to_owned()))?; + } + } + stack.err(ErrorKind::CustomObject(obj)) } pub fn register(r: &mut Stack, o: Arc) { type Fn = fn(&mut Stack) -> OError; - let fns: [(&str, Fn, u32); 50] = [ + let fns: [(&str, Fn, u32); 51] = [ ("pop", pop, 0), ("dup", dup, 2), ("clone", clone, 1), @@ -812,6 +839,7 @@ pub fn register(r: &mut Stack, o: Arc) { ("exit", exit, 0), ("exec", exec, 0), ("exec2", exec2, 0), + ("exec3", exec3, 0), ("stop", stop, 0), ("argv", argv, 1), ("get-env", get_env, 1), diff --git a/std.spl b/std.spl index 7527e22..c58bf04 100644 --- a/std.spl +++ b/std.spl @@ -310,15 +310,13 @@ func concat { str | with a b ; a _array b _array aadd _str } -func panic { | with msg ; +func handle-panic { | with msg trace ; program-name dup if { program-name print " panicked at:" println } not if { "Program panicked at:" println } - { | with it ; - it println - } trace:foreach + &println trace:foreach "\nPanic message:" println " " print msg println def map env =map @@ -342,6 +340,8 @@ func panic { | with msg ; 1 exit } +func panic { | trace handle-panic } + { | with msg this ; this not if { "Assertion failed!" panic @@ -384,9 +384,17 @@ func -- { mega | func _ { | } func call-main-on-file { | with file ; - "@" file concat import - update-types - argv main exit + catch { + "@" file concat import + update-types + argv main exit + } + with { with err ; + err:message dup null eq if { + pop + "Uncaught error." + } err:trace handle-panic + } } func update-types { | diff --git a/test.spl b/test.spl index 9f225d5..440deec 100644 --- a/test.spl +++ b/test.spl @@ -115,7 +115,7 @@ func main { int | with args ; catch { use net:http:Request "testing http" println - def req "tudbut.de" 81 "GET" "/" Request:new =req + def req "tudbut.de" 81 "GET" "/spltest" Request:new =req req:send:body _str println } with { with e ;