Merge pull request 'Implement new features' (#6) from bedohswe/labast:master into master
Reviewed-on: #6 Reviewed-by: n3tael <n3tael@noreply.localhost>
This commit is contained in:
		
						commit
						6a35058d54
					
				
							
								
								
									
										83
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										83
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							@ -2,6 +2,12 @@
 | 
			
		||||
# It is not intended for manual editing.
 | 
			
		||||
version = 3
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "cfg-if"
 | 
			
		||||
version = "1.0.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "fastrand"
 | 
			
		||||
version = "2.0.1"
 | 
			
		||||
@ -13,11 +19,88 @@ name = "labast"
 | 
			
		||||
version = "1.0.6"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "fastrand",
 | 
			
		||||
 "libloading",
 | 
			
		||||
 "pico-args",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "libloading"
 | 
			
		||||
version = "0.8.1"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "cfg-if",
 | 
			
		||||
 "windows-sys",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "pico-args"
 | 
			
		||||
version = "0.5.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows-sys"
 | 
			
		||||
version = "0.48.0"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "windows-targets",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows-targets"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
 | 
			
		||||
dependencies = [
 | 
			
		||||
 "windows_aarch64_gnullvm",
 | 
			
		||||
 "windows_aarch64_msvc",
 | 
			
		||||
 "windows_i686_gnu",
 | 
			
		||||
 "windows_i686_msvc",
 | 
			
		||||
 "windows_x86_64_gnu",
 | 
			
		||||
 "windows_x86_64_gnullvm",
 | 
			
		||||
 "windows_x86_64_msvc",
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_aarch64_gnullvm"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_aarch64_msvc"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_i686_gnu"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_i686_msvc"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_x86_64_gnu"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_x86_64_gnullvm"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
 | 
			
		||||
 | 
			
		||||
[[package]]
 | 
			
		||||
name = "windows_x86_64_msvc"
 | 
			
		||||
version = "0.48.5"
 | 
			
		||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
			
		||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
 | 
			
		||||
 | 
			
		||||
@ -18,4 +18,5 @@ panic = "abort"
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
fastrand = "2.0.1"
 | 
			
		||||
libloading = "0.8.1"
 | 
			
		||||
pico-args = "0.5.0"
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
use crate::{
 | 
			
		||||
    instructions,
 | 
			
		||||
    stack::{Instruction, Stack, StackVec},
 | 
			
		||||
    stack::{Instruction, Stack},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
fn find_labels(stack: &mut Stack) {
 | 
			
		||||
@ -28,18 +28,17 @@ fn find_labels(stack: &mut Stack) {
 | 
			
		||||
    stack.program_counter = stack.labels[0].unwrap_or(0) as u16;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn find_prefix_operators(instruction: &mut Instruction, memory: &mut StackVec) {
 | 
			
		||||
fn find_prefix_operators(instruction: &mut Instruction) {
 | 
			
		||||
    match instruction.name.chars().nth(0) {
 | 
			
		||||
        Some('|') => {
 | 
			
		||||
            instruction.name = instruction.name.chars().skip(1).collect();
 | 
			
		||||
 | 
			
		||||
            instruction.data = memory.pop();
 | 
			
		||||
            instruction.ispiped = true;
 | 
			
		||||
        }
 | 
			
		||||
        Some('/') => {
 | 
			
		||||
            instruction.name = instruction.name.chars().skip(1).collect();
 | 
			
		||||
 | 
			
		||||
            memory.push(instruction.data);
 | 
			
		||||
            instruction.data = 0;
 | 
			
		||||
            instruction.isdrained = true;
 | 
			
		||||
        }
 | 
			
		||||
        _ => {}
 | 
			
		||||
    }
 | 
			
		||||
@ -51,7 +50,16 @@ pub fn execute(stack: &mut Stack, mut origin_stack: Option<&mut Stack>, mod_name
 | 
			
		||||
    while let Some(mut instruction) = stack.program.get_mut(stack.program_counter as usize) {
 | 
			
		||||
        stack.program_counter += 1;
 | 
			
		||||
 | 
			
		||||
        find_prefix_operators(&mut instruction, &mut stack.memory);
 | 
			
		||||
        find_prefix_operators(&mut instruction);
 | 
			
		||||
 | 
			
		||||
        if instruction.ispiped {
 | 
			
		||||
            instruction.data = stack.memory.pop();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if instruction.isdrained {
 | 
			
		||||
            stack.memory.push(instruction.data);
 | 
			
		||||
            instruction.data = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if instruction.name.chars().nth(0) == Some('#')
 | 
			
		||||
            || instruction.name.chars().nth(0) == Some('$')
 | 
			
		||||
@ -70,6 +78,7 @@ pub fn execute(stack: &mut Stack, mut origin_stack: Option<&mut Stack>, mod_name
 | 
			
		||||
            "dup" => instructions::stack_manage::dup(&mut stack.memory),
 | 
			
		||||
            "swap" => instructions::stack_manage::swap(&mut stack.memory),
 | 
			
		||||
            "pick" => instructions::stack_manage::pick(&mut stack.memory, instruction.data),
 | 
			
		||||
            "string" => instructions::stack_manage::string(&mut stack.memory, instruction.arg.clone()),
 | 
			
		||||
 | 
			
		||||
            // Math operations
 | 
			
		||||
            "add" => instructions::math::add(&mut stack.memory),
 | 
			
		||||
@ -143,7 +152,15 @@ pub fn execute(stack: &mut Stack, mut origin_stack: Option<&mut Stack>, mod_name
 | 
			
		||||
            "exec" => {
 | 
			
		||||
                let arg = instruction.arg.clone();
 | 
			
		||||
                instructions::modules::exec(stack, arg, mod_name.clone())
 | 
			
		||||
            }
 | 
			
		||||
            },
 | 
			
		||||
            "call" => {
 | 
			
		||||
                let arg = instruction.arg.clone();
 | 
			
		||||
                instructions::modules::call(stack, arg)
 | 
			
		||||
            },
 | 
			
		||||
            "native" => {
 | 
			
		||||
                let arg = instruction.arg.clone();
 | 
			
		||||
                unsafe {instructions::native::native(stack, arg)}
 | 
			
		||||
            },
 | 
			
		||||
 | 
			
		||||
            // Self-modifying
 | 
			
		||||
            "insert" => {
 | 
			
		||||
 | 
			
		||||
@ -9,3 +9,4 @@ pub mod self_modify;
 | 
			
		||||
pub mod special;
 | 
			
		||||
pub mod specific;
 | 
			
		||||
pub mod stack_manage;
 | 
			
		||||
pub mod native;
 | 
			
		||||
 | 
			
		||||
@ -34,3 +34,13 @@ pub fn exec(mut stack: &mut Stack, arg: String, mod_name: String) {
 | 
			
		||||
        stack.memory.push(*item);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn call(stack: &mut Stack, mod_name: String) {
 | 
			
		||||
    let len: u16 = stack.memory.pop();
 | 
			
		||||
    let mut rev: String = String::new();
 | 
			
		||||
    for _i in 0..len {
 | 
			
		||||
        rev.push(stack.memory.pop() as u8 as char);
 | 
			
		||||
    }
 | 
			
		||||
    let tocall: String = rev.chars().rev().collect::<String>();
 | 
			
		||||
    exec(stack, tocall, mod_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								src/instructions/native.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/instructions/native.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,37 @@
 | 
			
		||||
use crate::Stack;
 | 
			
		||||
use libloading::{Library, Symbol};
 | 
			
		||||
 | 
			
		||||
static mut STACKPTR: *mut Stack = 0 as *mut Stack;
 | 
			
		||||
 | 
			
		||||
#[no_mangle]
 | 
			
		||||
unsafe extern fn stack_pop_callback() -> u16  { 
 | 
			
		||||
    (*STACKPTR).memory.pop()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[no_mangle]
 | 
			
		||||
unsafe extern fn stack_push_callback(data: u16) { 
 | 
			
		||||
    (*STACKPTR).memory.push(data) 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[no_mangle]
 | 
			
		||||
unsafe extern fn stack_len_callback() -> usize { 
 | 
			
		||||
    (*STACKPTR).memory.len()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub unsafe fn native(stack: &mut Stack, arg: String) {
 | 
			
		||||
    STACKPTR = stack as *mut Stack;
 | 
			
		||||
    #[cfg(not(target_family = "windows"))]
 | 
			
		||||
    let libsuf: String = ".so".to_owned();
 | 
			
		||||
 | 
			
		||||
    #[cfg(target_family = "windows")]
 | 
			
		||||
    let libsuf: String = ".dll".to_owned();
 | 
			
		||||
 | 
			
		||||
    let module = Library::new(format!("./{}{}", arg, libsuf)).unwrap();
 | 
			
		||||
    // C libraries should use 
 | 
			
		||||
    // void (*labashka)(unsigned short (*pop)(void), void (*push)(unsigned short), size_t (*len)(void), size_t max_size);
 | 
			
		||||
    let func: Symbol<unsafe extern "C" fn(unsafe extern fn() -> u16, unsafe extern fn(u16), unsafe extern fn() -> usize, usize)> = module.get(b"labashka").unwrap();
 | 
			
		||||
    func(stack_pop_callback,stack_push_callback,stack_len_callback, stack.memory.size());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -22,5 +22,7 @@ pub fn insert(program: &mut Vec<Instruction>, arg: String, data: u16) {
 | 
			
		||||
        name: arg.to_string(),
 | 
			
		||||
        arg: "\n".to_string(),
 | 
			
		||||
        data,
 | 
			
		||||
        ispiped: false,
 | 
			
		||||
        isdrained: false
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -34,3 +34,11 @@ pub fn pick(memory: &mut StackVec, data: u16) {
 | 
			
		||||
            .expect(&format!("{}", RunError::PickOutOfBounds)),
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn string(memory: &mut StackVec, arg: String) {
 | 
			
		||||
    for i in arg.chars() {
 | 
			
		||||
        memory.push(i as u16);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    memory.push(arg.len() as u16);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -47,7 +47,9 @@ pub fn parse(stack: &mut Stack, file_content: &str) {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let inst = Instruction { name, arg, data };
 | 
			
		||||
        if name.is_empty() {
 | 
			
		||||
            let inst = Instruction { name, arg, data, ispiped: false, isdrained: false };
 | 
			
		||||
            stack.program.push(inst);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,8 @@ pub struct Instruction {
 | 
			
		||||
    pub name: String,
 | 
			
		||||
    pub arg: String,
 | 
			
		||||
    pub data: u16,
 | 
			
		||||
    pub ispiped: bool,
 | 
			
		||||
    pub isdrained: bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct Stack {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								test/native_test.lb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								test/native_test.lb
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
@ 0
 | 
			
		||||
 push -1
 | 
			
		||||
 #native native_test
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								test/native_test.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								test/native_test.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
// Build with
 | 
			
		||||
// rustc --crate-type cdylib native_test.rs -o native_test.so
 | 
			
		||||
// or
 | 
			
		||||
// rustc --crate-type cdylib native_test.rs -o native_test.dll
 | 
			
		||||
 | 
			
		||||
#[no_mangle]
 | 
			
		||||
unsafe extern "C" fn labashka(pop: extern fn() -> u16, push: extern fn(u16), len: extern fn () -> usize, max: usize) {
 | 
			
		||||
    println!("At {}, there's {}.", len(), pop());
 | 
			
		||||
    push(12);
 | 
			
		||||
    println!("Maximum size is {}.", max);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user