add postfix argument notation

This commit is contained in:
Daniella / Tove 2023-04-07 22:03:36 +02:00
parent fa488c4b08
commit 0689bdbea0
Signed by: TudbuT
GPG key ID: 7D63D5634B7C417F
3 changed files with 58 additions and 7 deletions

View file

@ -10,6 +10,7 @@ pub enum LexerError {
InvalidInclude,
InvalidConstructBlock,
InvalidNumber(String),
ArgsWithoutCall,
}
pub fn lex(input: String) -> Result<Words, LexerError> {
@ -65,6 +66,24 @@ fn read_block(str_words: &[String], isfn: bool) -> Result<(Option<u32>, Words, u
name: "dyn".to_owned(),
}))))
}
"<{" => {
let block = read_block(&str_words[i + 1..], false)?;
i += block.2 + 1;
let mut block = block.1.words;
match words.remove(words.len() - 1) {
Word::Call(a, b, c) => {
words.append(&mut block);
words.push(Word::Call(a, b, c));
}
Word::ObjCall(a, b, c) => {
words.push(Word::Key(Keyword::ObjPush));
words.append(&mut block);
words.push(Word::Key(Keyword::ObjPop));
words.push(Word::ObjCall(a, b, c));
}
_ => return Err(LexerError::ArgsWithoutCall),
}
}
"construct" => {
let name = str_words[i + 1].to_owned();
let is_namespace = if str_words[i + 2] == "namespace" {
@ -190,10 +209,7 @@ fn read_block(str_words: &[String], isfn: bool) -> Result<(Option<u32>, Words, u
)));
}
x => {
let mut word = x
.split(':')
.next()
.unwrap(); // SAFETY: One item always exists after a split.
let mut word = x.split(':').next().unwrap(); // SAFETY: One item always exists after a split.
if !word.is_empty() {
let mut ra = 0;
while word.starts_with('&') {

View file

@ -1,9 +1,13 @@
use spl::{start_file, find_in_splpath};
use spl::{find_in_splpath, start_file};
use std::env::args;
fn main() {
if let Err(x) = start_file(&args().nth(1).unwrap_or_else(|| find_in_splpath("repl.spl").expect("no file to be run"))) {
if let Err(x) = start_file(
&args()
.nth(1)
.unwrap_or_else(|| find_in_splpath("repl.spl").expect("no file to be run")),
) {
println!("{x:?}");
}
}

View file

@ -358,6 +358,7 @@ impl Frame {
pub struct Stack {
frames: Vec<Arc<Frame>>,
object_stack: Vec<AMObject>,
objcall_stack: Vec<AMObject>,
files: Vec<String>,
pub return_accumultor: u32,
}
@ -393,6 +394,7 @@ impl Stack {
let mut r = Stack {
frames: vec![o.clone()],
object_stack: Vec::new(),
objcall_stack: Vec::new(),
files: Vec::new(),
return_accumultor: 0,
};
@ -409,6 +411,7 @@ impl Stack {
let mut r = Stack {
frames: vec![o.clone()],
object_stack: Vec::new(),
objcall_stack: Vec::new(),
files: Vec::new(),
return_accumultor: 0,
};
@ -663,6 +666,20 @@ pub enum Keyword {
/// encountered and the error is of <type> (or, if no type is specified, any error).
/// equivalent to \[ ["<type>" <...>] \] { | <code> } { | <wordsOnCatch> } dyn-catch
Catch(Vec<String>, Words, Words),
/// <none>
///
/// Used by `object:method <{ arg1 arg2 }` syntax. Generates as:
/// - CALL object
/// - OBJPUSH
/// - CALL arg1
/// - CALL arg2
/// - OBJPOP
/// - OBJCALL method
ObjPush,
/// <none>
///
/// see [Keyword::ObjPush]
ObjPop,
}
/// Any SPL value that is not a construct.
@ -840,7 +857,10 @@ impl Type {
q.append(&mut VecDeque::from(t.lock_ro().parents.clone()));
}
for property in to_apply.into_iter().rev() {
object.property_map.entry(property).or_insert_with(|| Value::Null.spl());
object
.property_map
.entry(property)
.or_insert_with(|| Value::Null.spl());
}
}
@ -1199,6 +1219,17 @@ impl Words {
stack.set_var(var, obj)?;
}
}
Keyword::ObjPush => {
let o = stack.pop();
stack.objcall_stack.push(o);
}
Keyword::ObjPop => {
let o = stack
.objcall_stack
.pop()
.expect("invalid word generation. objpop without objpush!");
stack.push(o);
}
},
Word::Const(x) => {
if option_env!("SPLDEBUG").is_some() {