Compare commits

..

3 commits

Author SHA1 Message Date
79ee784a5b update readme 2024-09-08 12:52:23 +02:00
2024677225 update version 2024-09-08 12:52:23 +02:00
89e6eff198 replace function <{ args } with function<args> 2024-09-08 12:52:23 +02:00
7 changed files with 57 additions and 23 deletions

2
Cargo.lock generated
View file

@ -22,7 +22,7 @@ checksum = "b03f7fbd470aa8b3ad163c85cce8bccfc11cc9c44ef12da0a4eddd98bd307352"
[[package]]
name = "spl"
version = "0.3.0"
version = "0.3.1"
dependencies = [
"multicall",
"once_cell",

View file

@ -1,6 +1,6 @@
[package]
name = "spl"
version = "0.3.1"
version = "0.3.2"
edition = "2021"
description = "Stack Pogramming Language: A simple, concise scripting language."
license = "MIT"

View file

@ -10,7 +10,7 @@ func main { mega | with args ;
{ str | " " concat } swap:map
&print swap:foreach
"" println
println <{ "and with that, we're done" }
println<"and with that, we're done">
0
}
```
@ -177,19 +177,19 @@ func main { mega | with args ;
```
- SPL actually isn't fully concatenative. It supports postfix arguments as well:
```js
println <{ "and with that, we're done" }
println<"and with that, we're done">
```
This is actually not a special interpreter feature, more so is it a special
lexer feature. This is 100% equivalent with the non-postfix version, where the
string is right before the `println`.
The same can be done for object calls. Let's rewrite the previous code with
postfix:
prefix notation:
```js
Range:new <{ 0 5 }
Range:new<0 5>
:iter
:map <{ { | 5 * } }
:foreach <{ { | _str println } }
:map<{ | 5 * }>
:foreach<{ | _str println }>
```
I lied. This is now no longer 100% equivalent. Let's look at what happens
@ -261,4 +261,4 @@ As you can see, it's relatively straight-forward to do; but there are some major
The second one is easy to fix, but I intend to fix the first one first. Sadly, fixing it requires
compiling the code as a dynamic library and also getting it to work with the program its running in.
If anyone knows how to do this properly, I'd REALLY appreciate a PR or issue explaining it.
If anyone knows how to do this properly, I'd REALLY appreciate a PR or issue explaining it.

View file

@ -24,6 +24,15 @@ pub fn lex(compat: bool, input: String) -> Result<Words, LexerError> {
fn read_block(
str_words: &[String],
isfn: bool,
compat: bool,
) -> Result<(Option<u32>, Words, usize), LexerError> {
read_block_dyn(str_words, isfn, "}".to_owned(), compat)
}
fn read_block_dyn(
str_words: &[String],
isfn: bool,
endword: String,
mut compat: bool,
) -> Result<(Option<u32>, Words, usize), LexerError> {
if str_words.is_empty() {
@ -111,8 +120,8 @@ fn read_block(
x if x.len() >= 2 && &x[0..2] == "!{" => {
words.push(Word::Const(Value::Str(x[2..].to_owned())));
}
"<{" => {
let block = read_block(&str_words[i + 1..], false, compat)?;
"<" => {
let block = read_block_dyn(&str_words[i + 1..], false, ">".to_owned(), compat)?;
i += block.2 + 1;
let mut block = block.1.words;
match words.remove(words.len() - 1) {
@ -227,7 +236,7 @@ fn read_block(
}
words.push(Word::Key(Keyword::With(vars)));
}
"}" => {
x if x == endword => {
break;
}
x if x.starts_with('\"') => {
@ -286,7 +295,11 @@ fn read_block(
Ok((rem, Words { words }, i))
}
fn parse(input: String) -> Vec<String> {
pub fn parse(mut input: String) -> Vec<String> {
if input.starts_with("#!") {
input = input.split_off(input.find('\n').expect("cannot have #! without newline"));
}
let mut words = Vec::new();
let mut s = String::new();
@ -346,6 +359,17 @@ fn parse(input: String) -> Vec<String> {
if c == '(' || c == ')' {
continue;
}
if c == '<' || c == '>' {
if s.is_empty() {
words.push(c.to_string());
continue;
}
words.push(s);
s = String::new();
was_in_string = false;
words.push(c.to_string());
continue;
}
if c == ' ' || c == '\t' {
if s.is_empty() {
continue;

View file

@ -1,4 +1,6 @@
use spl::{lex, oxidizer::RustAppBuilder, start_file_in_runtime, Runtime, SetRuntime};
use spl::{
lex, oxidizer::RustAppBuilder, sasm::sasm_write, start_file_in_runtime, Runtime, SetRuntime,
};
use std::{env::args, fs};
@ -6,9 +8,14 @@ fn main() {
Runtime::new().set();
let mut args = args().skip(1);
let arg = &args.next().unwrap_or("#repl.spl".to_owned());
if arg == "--build" || arg == "--run" || arg == "--buildrun" {
if arg == "--build" || arg == "--run" || arg == "--buildrun" || arg == "--debug" {
let file = args.next().unwrap();
let data = fs::read_to_string(file.clone()).expect("unable to read specified file");
if arg == "--debug" {
println!("words: {}", spl::parse(data.clone()).join(" "));
println!("{}", sasm_write(lex(false, data).unwrap()));
return;
}
let build_only = arg == "--build";
if build_only {
println!("Building SPL with specified natives file...");

View file

@ -82,6 +82,9 @@ construct _str_ext {
starts-with { bool | with beginning this ;
beginning:to-bytes this:to-bytes:starts-with
}
_char { int | with this ;
0 (this _array):get
}
} include _str_ext in str
construct _mega-ext {
@ -398,9 +401,9 @@ func concat { str | with a b ;
func nconcat { str | with amt ;
_array
(amt 1 -):foreach <{ { | pop
(amt 1 -):foreach<{ | pop
swap _array swap aadd
} }
}>
_str
}

View file

@ -142,10 +142,10 @@ func main { int | with args ;
"testing messages" println
def bus messaging:Bus:new =bus
bus:subscribe <{ "testmsg1" { | with message ; message:name print " called1 1" println } }
bus:subscribe <{ "testmsg1" { | with message ; message:name print " called1 2" println } }
bus:subscribe <{ "testmsg2" { | with message ; message:name print " called2 1" println } }
bus:subscribe <{ "testmsg2" { | with message ; message:name print " called2 2" println } }
bus:subscribe<"testmsg1" { | with message ; message:name print " called1 1" println }>
bus:subscribe<"testmsg1" { | with message ; message:name print " called1 2" println }>
bus:subscribe<"testmsg2" { | with message ; message:name print " called2 1" println }>
bus:subscribe<"testmsg2" { | with message ; message:name print " called2 2" println }>
"testmsg1" bus:publish
"testmsg2" bus:publish
"testmsg1" bus:publish
@ -154,7 +154,7 @@ func main { int | with args ;
100
}
func cached-test { mega | 1 "cached-test" cache <{ { mega | with i ;
func cached-test { mega | 1 "cached-test" cache<{ mega | with i ;
i 2 *
"calculated " i _str concat println
} } }
}>}