-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
discuss: ASM as a subset of an existing language #802
Comments
Here's a sketch of what this could look like: use std::{iter, ops::Add};
use tuplez::{ops::Poppable, Tuple}; // 0.14.15
pub trait Load {
fn load(it: impl Iterator<Item = u8>) -> Self;
}
pub trait Store {
fn store(&self) -> impl Iterator<Item = u8> + '_;
}
impl Load for u8 {
fn load(mut it: impl Iterator<Item = u8>) -> Self {
it.next().unwrap()
}
}
impl Store for u8 {
fn store(&self) -> impl Iterator<Item = u8> + '_ {
iter::once(*self)
}
}
fn pop<T: Poppable>(t: T) -> (T::PopFrontOutput, T::PopFrontElement) {
tuplez::TupleLike::pop_front(t)
}
#[derive(Clone)]
pub struct Pointer(usize);
pub struct Memory(Vec<u8>);
pub fn mload_general<Stack0, Stack1, T>(memory: &Memory, stack0: Stack0) -> Tuple<T, Stack1>
where
Stack0: Poppable<PopFrontElement = Pointer, PopFrontOutput = Stack1>,
T: Load,
{
let (stack1, Pointer(ix)) = pop(stack0);
let t = T::load(memory.0[ix..].iter().copied());
push(stack1, t)
}
pub fn mstore_general<Stack0, Stack1, Stack2, T>(memory: &mut Memory, stack0: Stack0) -> Stack2
where
Stack0: Poppable<PopFrontElement = T, PopFrontOutput = Stack1>,
Stack1: Poppable<PopFrontElement = Pointer, PopFrontOutput = Stack2>,
T: Store,
{
let (stack1, t) = pop(stack0);
let (stack2, Pointer(ix)) = pop(stack1);
let storeme = t.store().collect::<Vec<_>>();
memory.0.splice(ix..(ix + storeme.len()), storeme);
stack2
}
pub fn add<Stack0, Stack1, Stack2, LeftT, RightT, ResultT>(stack0: Stack0) -> Tuple<ResultT, Stack2>
where
Stack0: Poppable<PopFrontElement = RightT, PopFrontOutput = Stack1>,
Stack1: Poppable<PopFrontElement = LeftT, PopFrontOutput = Stack2>,
LeftT: Add<RightT, Output = ResultT>,
{
let (stack1, right) = pop(stack0);
let (stack2, left) = pop(stack1);
let add = left + right;
push(stack2, add)
}
pub fn push<Stack0, T>(stack0: Stack0, t: T) -> Tuple<T, Stack0> {
Tuple(t, stack0)
}
pub fn increment_mem<Stack0>(memory: &mut Memory, address: Pointer, stack0: Stack0) -> Stack0
where
Stack0: Poppable, // this shouldn't be needed
{
let stack1 = push(stack0, address.clone()); // dest
let stack2 = push(stack1, address); // src
let stack3 = mload_general::<_, _, u8>(memory, stack2);
let stack4 = push(stack3, 1u8);
let stack5 = add(stack4);
mstore_general(memory, stack5)
}
#[test]
fn test() {
let stack = tuplez::Unit;
let mut memory = Memory(vec![42]);
let stack = push(stack, ()); // this shouldn't be needed
let stack = increment_mem(&mut memory, Pointer(0), stack);
let Tuple((), tuplez::Unit) = stack;
assert_eq!(memory.0, [43]);
} |
And the idea would be to compile the .asm files into something like the body of |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
between #801 and #299, have we considered using a subset of an existing language our ASM code in?
C(I think we need something with tuples in its type system)The text was updated successfully, but these errors were encountered: