Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions library/core/src/casting.fe
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
extern {
pub fn todo() -> !
}

pub trait IntUpcast<To> {
fn upcast(self) -> To
}

pub impl IntUpcast<u256> for u8 {
fn upcast(self) -> u256 {
todo()
}
}

pub impl IntUpcast<u256> for usize {
fn upcast(self) -> u256 {
todo()
}
}

pub trait IntDowncast<To> {
fn downcast_truncate(self) -> To
fn downcast_saturate(self) -> To
// fn downcast(self) -> Option<To> // Option is in core lib, which isn't visible in lsp (see grant's PR)
}

pub impl IntDowncast<u8> for u256 {
fn downcast_truncate(self) -> u8 {
todo()
}
fn downcast_saturate(self) -> u8 {
todo()
}
}

pub impl IntDowncast<usize> for u256 {
fn downcast_truncate(self) -> usize {
todo()
}
fn downcast_saturate(self) -> usize {
todo()
}
}
106 changes: 106 additions & 0 deletions library/core/src/codec.fe
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
pub struct BufferResult<T> {
pub value: T,
pub is_error: bool
}

pub trait Buffer {
fn write_word(mut self, offset: u256, w: u256) -> bool
fn read_word(mut self, offset: u256) -> BufferResult<u256>
fn len(self) -> u256
}

pub struct Cursor<B: Buffer> {
pub inner: B,
pub pos: u256
}

impl<B: Buffer> Write for Cursor<B> {
fn write_word(mut self, w: u256) -> bool {
if self.pos > self.inner.len() {
return false
}
self.inner.write_word(offset: self.pos, w)
self.pos += 32
true
}
}

impl<B: Buffer> Read for Cursor<B> {
fn read_word(mut self) -> BufferResult<u256> {
if self.pos > self.inner.len() {
return BufferResult { value: 0, is_error: true }
}
let word: u256 = self.inner.read_word(offset: self.pos).value
self.pos += 32
BufferResult { value: word, is_error: false }
}
}

pub trait Write {
fn write_word(mut self, w: u256) -> bool
}

pub trait Read {
fn read_word(mut self) -> BufferResult<u256>
}

pub trait Decode {
fn decode<R: Read>(mut r: R) -> BufferResult<Self>
fn decode_size() -> usize
}

pub trait Encode {
fn encode<W: Write>(self, mut _ w: W) -> bool
fn encode_size() -> usize
}

impl Decode for u256 {
fn decode<R: Read>(mut r: R) -> BufferResult<u256> {
r.read_word()
}
fn decode_size() -> usize {
32
}
}

impl Encode for u256 {
fn encode<W: Write>(self, mut _ w: W) -> bool {
w.write_word(w: self)
}

fn encode_size() -> usize {
32
}
}

impl Encode for (u256, u256) {
fn encode<W: Write>(self, mut _ w: W) -> bool {
let (a, b) = self
if !a.encode(w) {
return false
}
b.encode(w)
}

fn encode_size() -> usize {
64 // 2 * 32 bytes (size of two u256)
}
}

impl Decode for (u256, u256) {
fn decode<R: Read>(mut r: R) -> BufferResult<(u256, u256)> {
let a = u256::decode(r)
if a.is_error {
return BufferResult { value: (0, 0), is_error: true }
}
let b = u256::decode(r)
if b.is_error {
return BufferResult { value: (0, 0), is_error: true }
}
BufferResult { value: (a.value, b.value), is_error: false }
}

fn decode_size() -> usize {
64 // 2 * 32 bytes (size of two u256)
}
}
6 changes: 6 additions & 0 deletions library/core/src/default.fe
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ impl Default for usize {
0
}
}

impl Default for u256 {
fn default() -> Self {
0
}
}
97 changes: 97 additions & 0 deletions library/core/src/map.fe
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use ingot::codec::{Encode, Decode}
use ingot::operators::{Add, Sub, AddAssign, SubAssign}
use ingot::default::{Default}

pub trait Hasher {
fn hash<T: Encode>(mut self, key: T) -> u256
}

pub trait MapStorage<T, U> {
fn get(mut self, key: T) -> U
fn set(mut self, key: T, value: U) -> bool
fn entry(mut self, key: T) -> Entry<T, U, Self>
}

pub struct Map<T, U, S: MapStorage<T, U>> {
pub storage: S
}

impl<T, U, S: MapStorage<T, U>> Map<T, U, S>
where T: Encode, U: Encode, U: Decode
{
pub fn get(mut self, key: T) -> U {
self.storage.get(key)
}

pub fn set(mut self, key: T, value: U) -> bool {
self.storage.set(key, value)
}

pub fn entry(mut self, key: T) -> Entry<T, U, S> {
self.storage.entry(key)
}
}

pub enum Entry<T, U, S: MapStorage<T, U>> {
Occupied { pub key: T, pub value: U, pub index: u256, pub storage: S },
Vacant { pub key: T, pub storage: S }
}

impl<T, U, S: MapStorage<T, U>> Entry<T, U, S>
where U: Default
{
pub fn or_insert(mut self, value: U) -> U {
match self {
Entry::Occupied { value: v, .. } => v
Entry::Vacant { key, mut storage } => {
storage.set(key, value)
value
}
}
}

pub fn value(self) -> U {
match self {
Entry::Occupied { value, .. } => value
Entry::Vacant { .. } => U::default()
}
}
}

impl<K, V, S> AddAssign<V> for Entry<K, V, S>
where
S: MapStorage<K, V>,
V: Add
{
fn add_assign(mut self, rhs: V) {
match self {
Entry::Occupied { key, value, index, mut storage } => {
let new_value = value.add(rhs: rhs)
storage.set(key: key, value: new_value)
self = Entry::Occupied { key, value: new_value, index, storage }
}
Entry::Vacant { key, storage } => {
self = Entry::Vacant { key, storage }
}
}
}
}

impl<K, V, S> SubAssign<V> for Entry<K, V, S>
where
S: MapStorage<K, V>,
V: Sub
{
fn sub_assign(mut self, rhs: V) {
match self {
Entry::Occupied { key, value, index, mut storage } => {
let new_value = value.sub(rhs: rhs)
storage.set(key: key, value: new_value)
self = Entry::Occupied { key, value: new_value, index, storage }
}
Entry::Vacant { key, storage } => {
self = Entry::Vacant { key, storage }
}
}
}
}
27 changes: 27 additions & 0 deletions library/core/src/operators.fe
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
pub trait Add {
fn add(self, rhs: Self) -> Self
}

pub trait Sub {
fn sub(self, rhs: Self) -> Self
}

pub trait AddAssign<V> {
fn add_assign(mut self, rhs: V)
}

pub trait SubAssign<V> {
fn sub_assign(mut self, rhs: V)
}

impl Add for u256 {
fn add(self, rhs: u256) -> u256 {
self + rhs
}
}

impl Sub for u256 {
fn sub(self, rhs: u256) -> u256 {
self - rhs
}
}