add postfix argument notation
This commit is contained in:
parent
fa488c4b08
commit
0689bdbea0
3 changed files with 58 additions and 7 deletions
24
src/lexer.rs
24
src/lexer.rs
|
@ -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('&') {
|
||||
|
|
|
@ -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:?}");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in a new issue