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]] [[package]]
name = "spl" name = "spl"
version = "0.3.0" version = "0.3.1"
dependencies = [ dependencies = [
"multicall", "multicall",
"once_cell", "once_cell",

View file

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

View file

@ -10,7 +10,7 @@ func main { mega | with args ;
{ str | " " concat } swap:map { str | " " concat } swap:map
&print swap:foreach &print swap:foreach
"" println "" println
println <{ "and with that, we're done" } println<"and with that, we're done">
0 0
} }
``` ```
@ -177,19 +177,19 @@ func main { mega | with args ;
``` ```
- SPL actually isn't fully concatenative. It supports postfix arguments as well: - SPL actually isn't fully concatenative. It supports postfix arguments as well:
```js ```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 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 lexer feature. This is 100% equivalent with the non-postfix version, where the
string is right before the `println`. string is right before the `println`.
The same can be done for object calls. Let's rewrite the previous code with The same can be done for object calls. Let's rewrite the previous code with
postfix: prefix notation:
```js ```js
Range:new <{ 0 5 } Range:new<0 5>
:iter :iter
:map <{ { | 5 * } } :map<{ | 5 * }>
:foreach <{ { | _str println } } :foreach<{ | _str println }>
``` ```
I lied. This is now no longer 100% equivalent. Let's look at what happens I lied. This is now no longer 100% equivalent. Let's look at what happens

View file

@ -24,6 +24,15 @@ pub fn lex(compat: bool, input: String) -> Result<Words, LexerError> {
fn read_block( fn read_block(
str_words: &[String], str_words: &[String],
isfn: bool, 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, mut compat: bool,
) -> Result<(Option<u32>, Words, usize), LexerError> { ) -> Result<(Option<u32>, Words, usize), LexerError> {
if str_words.is_empty() { if str_words.is_empty() {
@ -111,8 +120,8 @@ fn read_block(
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())));
} }
"<{" => { "<" => {
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; i += block.2 + 1;
let mut block = block.1.words; let mut block = block.1.words;
match words.remove(words.len() - 1) { match words.remove(words.len() - 1) {
@ -227,7 +236,7 @@ fn read_block(
} }
words.push(Word::Key(Keyword::With(vars))); words.push(Word::Key(Keyword::With(vars)));
} }
"}" => { x if x == endword => {
break; break;
} }
x if x.starts_with('\"') => { x if x.starts_with('\"') => {
@ -286,7 +295,11 @@ fn read_block(
Ok((rem, Words { words }, i)) 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 words = Vec::new();
let mut s = String::new(); let mut s = String::new();
@ -346,6 +359,17 @@ fn parse(input: String) -> Vec<String> {
if c == '(' || c == ')' { if c == '(' || c == ')' {
continue; 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 c == ' ' || c == '\t' {
if s.is_empty() { if s.is_empty() {
continue; 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}; use std::{env::args, fs};
@ -6,9 +8,14 @@ fn main() {
Runtime::new().set(); Runtime::new().set();
let mut args = args().skip(1); let mut args = args().skip(1);
let arg = &args.next().unwrap_or("#repl.spl".to_owned()); 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 file = args.next().unwrap();
let data = fs::read_to_string(file.clone()).expect("unable to read specified file"); 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"; let build_only = arg == "--build";
if build_only { if build_only {
println!("Building SPL with specified natives file..."); println!("Building SPL with specified natives file...");

View file

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

View file

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