Crates.io | pushr |
lib.rs | pushr |
version | 0.4.1 |
source | src |
created_at | 2021-08-19 19:39:05.88684 |
updated_at | 2022-12-30 11:59:03.308158 |
description | Pushr is a Rust based interpreter for Push programs. |
homepage | |
repository | https://github.com/johker/pushr/ |
max_upload_size | |
id | 439740 |
size | 439,183 |
Pushr is a Rust based interpreter for Push programs.
Push is a stack-based, Turing-complete programming language that enables autoconstructive evolution in its programs. More information can be found here.
This implementation supports all Push3 instructions for the types desribed in the Push 3.0 Programming Language Description:
Additional stack types:
FIFO queues are used to communicate with other modules. The type is BOOLVECTOR.
INPUT
OUTPUT
The default instructions for vector types are 'dup', 'equal', 'flush', 'get', 'set', 'shove', 'stackdepth', 'rand', 'swap', 'yank' and 'yankdup'. Additionally, the instruction set contains 'add', 'subtract', 'multiply' and 'divide' for float and integer vectors, as well as 'and', 'or' and 'not' for boolean vectors. To initialize vectors the instructions 'ones' and 'zeros' can be used.
For vector instructions the following rules apply:
The 'rand' instruction is interpreted differently for boolean, float and integer vectors:
Vector lengths do not have to match. Arithmetic operations are executed element-wise on the overlapping parts. An offset parameter shifts the top vector on the stack to create the desired overlap.
In a Push program the vectors are defined as BOOL[..], FLOAT[..] and INT[..]. For example, BOOL[1,0] defines a BOOLVECTOR with two elements.
The following example shows how to intepret Push program with Prush.
// Define Push program
let input = "( CODE.QUOTE ( CODE.DUP INTEGER.DUP 1 INTEGER.- CODE.DO INTEGER.* )
CODE.QUOTE ( INTEGER.POP 1 )
INTEGER.DUP 2 INTEGER.< CODE.IF )";
// Define State and Instruction Set
let mut push_state = PushState::new();
let mut instruction_set = InstructionSet::new();
// Load default instructions
instruction_set.load();
// Add program to execution stack
PushParser::parse_program(&mut push_state, &instruction_set, &input);
// Put initial values
push_state.int_stack.push(4);
// Run the program
PushInterpreter::run(&mut push_state, &mut instruction_set);
For existing types the instruction set can be extended by calling the add
function.
pub fn my_instruction(_push_state: &mut PushState, _instruction_set: &InstructionCache) {
// Does nothing
}
...
let mut instruction_set = InstructionSet::new();
instruction_set.add(String::from("MyInstruction"), Instruction::new(my_instruction));