rue-compiler 0.1.0

The Rue compiler.
Documentation
export enum Condition {
    Remark = 1 {
        value?: Any,
    },
    AggSigParent = 43 {
        public_key: PublicKey,
        message: Bytes,
    },
    AggSigPuzzle = 44 {
        public_key: PublicKey,
        message: Bytes,
    },
    AggSigAmount = 45 {
        public_key: PublicKey,
        message: Bytes,
    },
    AggSigPuzzleAmount = 46 {
        public_key: PublicKey,
        message: Bytes,
    },
    AggSigParentAmount = 47 {
        public_key: PublicKey,
        message: Bytes,
    },
    AggSigParentPuzzle = 48 {
        public_key: PublicKey,
        message: Bytes,
    },
    AggSigUnsafe = 49 {
        public_key: PublicKey,
        message: Bytes,
    },
    AggSigMe = 50 {
        public_key: PublicKey,
        message: Bytes,
    },
    CreateCoin = 51 {
        puzzle_hash: Bytes32,
        amount: Int,
        memos?: Bytes[],
    },
    ReserveFee = 52 {
        amount: Int,
    },
    CreateCoinAnnouncement = 60 {
        message: Bytes,
    },
    AssertCoinAnnouncement = 61 {
        announcement_id: Bytes32,
    },
    CreatePuzzleAnnouncement = 62 {
        message: Bytes,
    },
    AssertPuzzleAnnouncement = 63 {
        announcement_id: Bytes32,
    },
    AssertConcurrentSpend = 64 {
        coin_id: Bytes32,
    },
    AssertConcurrentPuzzle = 65 {
        puzzle_hash: Bytes32,
    },
    AssertMyCoinId = 70 {
        coin_id: Bytes32,
    },
    AssertMyParentId = 71 {
        parent_coin_id: Bytes32,
    },
    AssertMyPuzzleHash = 72 {
        puzzle_hash: Bytes32,
    },
    AssertMyAmount = 73 {
        amount: Int,
    },
    AssertMyBirthSeconds = 74 {
        seconds: Int,
    },
    AssertMyBirthHeight = 75 {
        height: Int,
    },
    AssertEphemeral = 76,
    AssertSecondsRelative = 80 {
        seconds: Int,
    },
    AssertSecondsAbsolute = 81 {
        seconds: Int,
    },
    AssertHeightRelative = 82 {
        height: Int,
    },
    AssertHeightAbsolute = 83 {
        height: Int,
    },
    AssertBeforeSecondsRelative = 84 {
        seconds: Int,
    },
    AssertBeforeSecondsAbsolute = 85 {
        seconds: Int,
    },
    AssertBeforeHeightRelative = 86 {
        height: Int,
    },
    AssertBeforeHeightAbsolute = 87 {
        height: Int,
    },
    Softfork = 90 {
        cost: Int,
        value?: Any,
    },
}

export fun concat<T>(a: T[], b: T[]) -> T[] {
    if a is (T, T[]) {
        return [a.first, ...concat(a.rest, b)];
    }
    if b is (T, T[]) {
        return [b.first, ...concat(a, b.rest)];
    }
    nil
}

inline const ATOM_PREFIX: Bytes = 1 as Bytes;
inline const PAIR_PREFIX: Bytes = 2 as Bytes;

export fun tree_hash(value: Any) -> Bytes32 {
    if value is Bytes {
        tree_hash_atom(value)
    } else {
        tree_hash_pair(tree_hash(value.first), tree_hash(value.rest))
    }
}

export inline fun tree_hash_atom(value: Bytes) -> Bytes32 {
    sha256(ATOM_PREFIX + value)
}

export inline fun tree_hash_pair(first: Bytes32, rest: Bytes32) -> Bytes32 {
    sha256(PAIR_PREFIX + first + rest)
}

inline const OP_Q: Bytes = 1 as Bytes;
inline const OP_A: Bytes = 2 as Bytes;
inline const OP_C: Bytes = 4 as Bytes;

inline const OP_Q_TREE_HASH: Bytes32 = tree_hash_atom(OP_Q);
inline const OP_A_TREE_HASH: Bytes32 = tree_hash_atom(OP_A);
inline const OP_C_TREE_HASH: Bytes32 = tree_hash_atom(OP_C);
inline const ONE_TREE_HASH: Bytes32 = tree_hash_atom(1 as Bytes);

const NIL_TREE_HASH: Bytes32 = tree_hash_atom(nil);
const APPLY_PREIMAGE_PREFIX: Bytes = PAIR_PREFIX + OP_A_TREE_HASH;
const CONS_PREIMAGE_PREFIX: Bytes = PAIR_PREFIX + OP_C_TREE_HASH;

inline fun quote_hash(value: Bytes32) -> Bytes32 {
    tree_hash_pair(OP_Q_TREE_HASH, value)
}

inline fun two_item_list_hash(first: Bytes32, rest: Bytes32) -> Bytes32 {
    tree_hash_pair(first, tree_hash_pair(rest, NIL_TREE_HASH))
}

inline fun apply_hash(mod_hash: Bytes32, environment_hash: Bytes32) -> Bytes32 {
    sha256(APPLY_PREIMAGE_PREFIX + two_item_list_hash(quote_hash(mod_hash), environment_hash))
}

inline fun update_hash_with_parameter(
    parameter_hash: Bytes32,
    environment_hash: Bytes32
) -> Bytes32 {
    sha256(CONS_PREIMAGE_PREFIX + two_item_list_hash(quote_hash(parameter_hash), environment_hash))
}

fun curried_params_hash(parameters: Bytes32[]) -> Bytes32 {
    if parameters is Nil {
        return ONE_TREE_HASH;
    }
    update_hash_with_parameter(parameters.first, curried_params_hash(parameters.rest))
}

export inline fun curry_tree_hash(
    mod_hash: Bytes32,
    ...parameters: Bytes32[]
) -> Bytes32 {
    apply_hash(mod_hash, curried_params_hash(parameters))
}

export fun calculate_coin_id(
    parent_coin_id: Bytes,
    puzzle_hash: Bytes,
    amount: Int,
) -> Bytes32 {
    assert parent_coin_id is Bytes32;
    assert puzzle_hash is Bytes32;
    sha256(parent_coin_id + puzzle_hash + amount as Bytes)
}

export fun map<T, U>(list: T[], fn: fun(item: T) -> U) -> U[] {
    if list is Nil {
        return nil;
    }
    [fn(list.first), ...map(list.rest, fn)]
}

export fun filter<T>(list: T[], fn: fun(item: T) -> Bool) -> T[] {
    if list is Nil {
        return nil;
    }
    if fn(list.first) {
        return [list.first, ...filter(list.rest, fn)];
    }
    filter(list.rest, fn)
}

export fun fold<T, U>(list: T[], initial: U, fn: fun(acc: U, item: T) -> U) -> U {
    if list is Nil {
        return initial;
    }
    fold(list.rest, fn(initial, list.first), fn)
}