Add several builtins for strings and bytestring
Co-authored-by: rvcas <x@rvcas.dev>
This commit is contained in:
parent
0e5d25b019
commit
11ee99c199
|
@ -642,6 +642,7 @@ checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99"
|
||||||
name = "uplc"
|
name = "uplc"
|
||||||
version = "0.0.7"
|
version = "0.0.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cryptoxide",
|
||||||
"flat-rs",
|
"flat-rs",
|
||||||
"hex",
|
"hex",
|
||||||
"minicbor 0.18.0",
|
"minicbor 0.18.0",
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
(program
|
(program
|
||||||
1.0.0
|
1.0.0
|
||||||
(con (list (list integer)) [[7], [5]])
|
[ (builtin decodeUtf8) [ (builtin encodeUtf8) (con string "hello world") ] ]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ exclude = ["test_data/*"]
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
cryptoxide = "0.4.2"
|
||||||
flat-rs = { path = "../flat", version = "0.0.7" }
|
flat-rs = { path = "../flat", version = "0.0.7" }
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
minicbor = { version = "0.18.0", features = ["std"] }
|
minicbor = { version = "0.18.0", features = ["std"] }
|
||||||
|
|
|
@ -334,7 +334,7 @@ impl Machine {
|
||||||
|
|
||||||
self.spend_budget(cost)?;
|
self.spend_budget(cost)?;
|
||||||
|
|
||||||
runtime.call()
|
runtime.call(&mut self.logs)
|
||||||
} else {
|
} else {
|
||||||
Ok(Value::Builtin { fun, term, runtime })
|
Ok(Value::Builtin { fun, term, runtime })
|
||||||
}
|
}
|
||||||
|
@ -430,7 +430,7 @@ impl Value {
|
||||||
((i.abs() as f64).log2().floor() as i64 / 64) + 1
|
((i.abs() as f64).log2().floor() as i64 / 64) + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Constant::ByteString(b) => (((b.len() - 1) / 8) + 1) as i64,
|
Constant::ByteString(b) => (((b.len() as i64 - 1) / 8) + 1),
|
||||||
Constant::String(s) => s.chars().count() as i64,
|
Constant::String(s) => s.chars().count() as i64,
|
||||||
Constant::Unit => 1,
|
Constant::Unit => 1,
|
||||||
Constant::Bool(_) => 1,
|
Constant::Bool(_) => 1,
|
||||||
|
|
|
@ -552,13 +552,40 @@ impl BuiltinCosts {
|
||||||
.cpu
|
.cpu
|
||||||
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
},
|
},
|
||||||
DefaultFunction::MultiplyInteger => todo!(),
|
DefaultFunction::MultiplyInteger => ExBudget {
|
||||||
|
mem: self
|
||||||
|
.multiply_integer
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.multiply_integer
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::DivideInteger => todo!(),
|
DefaultFunction::DivideInteger => todo!(),
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => todo!(),
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => todo!(),
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => todo!(),
|
||||||
DefaultFunction::EqualsInteger => todo!(),
|
DefaultFunction::EqualsInteger => ExBudget {
|
||||||
DefaultFunction::LessThanInteger => todo!(),
|
mem: self
|
||||||
|
.equals_integer
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.equals_integer
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::LessThanInteger => ExBudget {
|
||||||
|
mem: self
|
||||||
|
.less_than_integer
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.less_than_integer
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::LessThanEqualsInteger => ExBudget {
|
DefaultFunction::LessThanEqualsInteger => ExBudget {
|
||||||
mem: self
|
mem: self
|
||||||
.less_than_equals_integer
|
.less_than_equals_integer
|
||||||
|
@ -569,24 +596,75 @@ impl BuiltinCosts {
|
||||||
.cpu
|
.cpu
|
||||||
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
},
|
},
|
||||||
DefaultFunction::AppendByteString => todo!(),
|
DefaultFunction::AppendByteString => ExBudget {
|
||||||
|
mem: self
|
||||||
|
.append_byte_string
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.append_byte_string
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::ConsByteString => todo!(),
|
DefaultFunction::ConsByteString => todo!(),
|
||||||
DefaultFunction::SliceByteString => todo!(),
|
DefaultFunction::SliceByteString => todo!(),
|
||||||
DefaultFunction::LengthOfByteString => todo!(),
|
DefaultFunction::LengthOfByteString => todo!(),
|
||||||
DefaultFunction::IndexByteString => todo!(),
|
DefaultFunction::IndexByteString => todo!(),
|
||||||
DefaultFunction::EqualsByteString => todo!(),
|
DefaultFunction::EqualsByteString => ExBudget {
|
||||||
|
mem: self
|
||||||
|
.equals_byte_string
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.equals_byte_string
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::LessThanByteString => todo!(),
|
DefaultFunction::LessThanByteString => todo!(),
|
||||||
DefaultFunction::LessThanEqualsByteString => todo!(),
|
DefaultFunction::LessThanEqualsByteString => todo!(),
|
||||||
DefaultFunction::Sha2_256 => todo!(),
|
DefaultFunction::Sha2_256 => ExBudget {
|
||||||
DefaultFunction::Sha3_256 => todo!(),
|
mem: self.sha2_256.mem.cost(args[0].to_ex_mem()),
|
||||||
DefaultFunction::Blake2b_256 => todo!(),
|
cpu: self.sha2_256.cpu.cost(args[0].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::Sha3_256 => ExBudget {
|
||||||
|
mem: self.sha3_256.mem.cost(args[0].to_ex_mem()),
|
||||||
|
cpu: self.sha3_256.cpu.cost(args[0].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::Blake2b_256 => ExBudget {
|
||||||
|
mem: self.blake2b_256.mem.cost(args[0].to_ex_mem()),
|
||||||
|
cpu: self.blake2b_256.cpu.cost(args[0].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::VerifySignature => todo!(),
|
DefaultFunction::VerifySignature => todo!(),
|
||||||
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::AppendString => todo!(),
|
DefaultFunction::AppendString => ExBudget {
|
||||||
DefaultFunction::EqualsString => todo!(),
|
mem: self
|
||||||
DefaultFunction::EncodeUtf8 => todo!(),
|
.append_string
|
||||||
DefaultFunction::DecodeUtf8 => todo!(),
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.append_string
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::EqualsString => ExBudget {
|
||||||
|
mem: self
|
||||||
|
.equals_string
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.equals_string
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::EncodeUtf8 => ExBudget {
|
||||||
|
mem: self.encode_utf8.mem.cost(args[0].to_ex_mem()),
|
||||||
|
cpu: self.encode_utf8.cpu.cost(args[0].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::DecodeUtf8 => ExBudget {
|
||||||
|
mem: self.decode_utf8.mem.cost(args[0].to_ex_mem()),
|
||||||
|
cpu: self.decode_utf8.cpu.cost(args[0].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::IfThenElse => ExBudget {
|
DefaultFunction::IfThenElse => ExBudget {
|
||||||
mem: self.if_then_else.mem.cost(
|
mem: self.if_then_else.mem.cost(
|
||||||
args[0].to_ex_mem(),
|
args[0].to_ex_mem(),
|
||||||
|
@ -599,8 +677,26 @@ impl BuiltinCosts {
|
||||||
args[2].to_ex_mem(),
|
args[2].to_ex_mem(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
DefaultFunction::ChooseUnit => todo!(),
|
DefaultFunction::ChooseUnit => ExBudget {
|
||||||
DefaultFunction::Trace => todo!(),
|
mem: self
|
||||||
|
.choose_unit
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.choose_unit
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::Trace => ExBudget {
|
||||||
|
mem: self
|
||||||
|
.trace
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.trace
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
DefaultFunction::SndPair => todo!(),
|
DefaultFunction::SndPair => todo!(),
|
||||||
DefaultFunction::ChooseList => todo!(),
|
DefaultFunction::ChooseList => todo!(),
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::string::FromUtf8Error;
|
||||||
|
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::ast::{NamedDeBruijn, Term, Type};
|
use crate::ast::{NamedDeBruijn, Term, Type};
|
||||||
|
@ -28,4 +30,6 @@ pub enum Error {
|
||||||
NotAConstant(Value),
|
NotAConstant(Value),
|
||||||
#[error("The evaluation never reached a final state")]
|
#[error("The evaluation never reached a final state")]
|
||||||
MachineNeverReachedDone,
|
MachineNeverReachedDone,
|
||||||
|
#[error("Decoding utf8")]
|
||||||
|
Utf8(#[from] FromUtf8Error),
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,8 @@ impl BuiltinRuntime {
|
||||||
self.forces += 1;
|
self.forces += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call(&self) -> Result<Value, Error> {
|
pub fn call(&self, logs: &mut Vec<String>) -> Result<Value, Error> {
|
||||||
self.fun.call(&self.args)
|
self.fun.call(&self.args, logs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, arg: Value) -> Result<(), Error> {
|
pub fn push(&mut self, arg: Value) -> Result<(), Error> {
|
||||||
|
@ -74,35 +74,35 @@ impl DefaultFunction {
|
||||||
match self {
|
match self {
|
||||||
DefaultFunction::AddInteger => 2,
|
DefaultFunction::AddInteger => 2,
|
||||||
DefaultFunction::SubtractInteger => 2,
|
DefaultFunction::SubtractInteger => 2,
|
||||||
DefaultFunction::MultiplyInteger => todo!(),
|
DefaultFunction::MultiplyInteger => 2,
|
||||||
DefaultFunction::DivideInteger => todo!(),
|
DefaultFunction::DivideInteger => todo!(),
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => todo!(),
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => todo!(),
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => todo!(),
|
||||||
DefaultFunction::EqualsInteger => todo!(),
|
DefaultFunction::EqualsInteger => 2,
|
||||||
DefaultFunction::LessThanInteger => todo!(),
|
DefaultFunction::LessThanInteger => 2,
|
||||||
DefaultFunction::LessThanEqualsInteger => 2,
|
DefaultFunction::LessThanEqualsInteger => 2,
|
||||||
DefaultFunction::AppendByteString => todo!(),
|
DefaultFunction::AppendByteString => 2,
|
||||||
DefaultFunction::ConsByteString => todo!(),
|
DefaultFunction::ConsByteString => todo!(),
|
||||||
DefaultFunction::SliceByteString => todo!(),
|
DefaultFunction::SliceByteString => todo!(),
|
||||||
DefaultFunction::LengthOfByteString => todo!(),
|
DefaultFunction::LengthOfByteString => todo!(),
|
||||||
DefaultFunction::IndexByteString => todo!(),
|
DefaultFunction::IndexByteString => todo!(),
|
||||||
DefaultFunction::EqualsByteString => todo!(),
|
DefaultFunction::EqualsByteString => 2,
|
||||||
DefaultFunction::LessThanByteString => todo!(),
|
DefaultFunction::LessThanByteString => todo!(),
|
||||||
DefaultFunction::LessThanEqualsByteString => todo!(),
|
DefaultFunction::LessThanEqualsByteString => todo!(),
|
||||||
DefaultFunction::Sha2_256 => todo!(),
|
DefaultFunction::Sha2_256 => 1,
|
||||||
DefaultFunction::Sha3_256 => todo!(),
|
DefaultFunction::Sha3_256 => 1,
|
||||||
DefaultFunction::Blake2b_256 => todo!(),
|
DefaultFunction::Blake2b_256 => 1,
|
||||||
DefaultFunction::VerifySignature => todo!(),
|
DefaultFunction::VerifySignature => todo!(),
|
||||||
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::AppendString => todo!(),
|
DefaultFunction::AppendString => 2,
|
||||||
DefaultFunction::EqualsString => todo!(),
|
DefaultFunction::EqualsString => 2,
|
||||||
DefaultFunction::EncodeUtf8 => todo!(),
|
DefaultFunction::EncodeUtf8 => 1,
|
||||||
DefaultFunction::DecodeUtf8 => todo!(),
|
DefaultFunction::DecodeUtf8 => 1,
|
||||||
DefaultFunction::IfThenElse => 3,
|
DefaultFunction::IfThenElse => 3,
|
||||||
DefaultFunction::ChooseUnit => todo!(),
|
DefaultFunction::ChooseUnit => 2,
|
||||||
DefaultFunction::Trace => todo!(),
|
DefaultFunction::Trace => 2,
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
DefaultFunction::SndPair => todo!(),
|
DefaultFunction::SndPair => todo!(),
|
||||||
DefaultFunction::ChooseList => todo!(),
|
DefaultFunction::ChooseList => todo!(),
|
||||||
|
@ -133,35 +133,35 @@ impl DefaultFunction {
|
||||||
match self {
|
match self {
|
||||||
DefaultFunction::AddInteger => 0,
|
DefaultFunction::AddInteger => 0,
|
||||||
DefaultFunction::SubtractInteger => 0,
|
DefaultFunction::SubtractInteger => 0,
|
||||||
DefaultFunction::MultiplyInteger => todo!(),
|
DefaultFunction::MultiplyInteger => 0,
|
||||||
DefaultFunction::DivideInteger => todo!(),
|
DefaultFunction::DivideInteger => todo!(),
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => todo!(),
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => todo!(),
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => todo!(),
|
||||||
DefaultFunction::EqualsInteger => todo!(),
|
DefaultFunction::EqualsInteger => 0,
|
||||||
DefaultFunction::LessThanInteger => todo!(),
|
DefaultFunction::LessThanInteger => 0,
|
||||||
DefaultFunction::LessThanEqualsInteger => 0,
|
DefaultFunction::LessThanEqualsInteger => 0,
|
||||||
DefaultFunction::AppendByteString => todo!(),
|
DefaultFunction::AppendByteString => 0,
|
||||||
DefaultFunction::ConsByteString => todo!(),
|
DefaultFunction::ConsByteString => todo!(),
|
||||||
DefaultFunction::SliceByteString => todo!(),
|
DefaultFunction::SliceByteString => todo!(),
|
||||||
DefaultFunction::LengthOfByteString => todo!(),
|
DefaultFunction::LengthOfByteString => todo!(),
|
||||||
DefaultFunction::IndexByteString => todo!(),
|
DefaultFunction::IndexByteString => todo!(),
|
||||||
DefaultFunction::EqualsByteString => todo!(),
|
DefaultFunction::EqualsByteString => 0,
|
||||||
DefaultFunction::LessThanByteString => todo!(),
|
DefaultFunction::LessThanByteString => todo!(),
|
||||||
DefaultFunction::LessThanEqualsByteString => todo!(),
|
DefaultFunction::LessThanEqualsByteString => todo!(),
|
||||||
DefaultFunction::Sha2_256 => todo!(),
|
DefaultFunction::Sha2_256 => 0,
|
||||||
DefaultFunction::Sha3_256 => todo!(),
|
DefaultFunction::Sha3_256 => 0,
|
||||||
DefaultFunction::Blake2b_256 => todo!(),
|
DefaultFunction::Blake2b_256 => 0,
|
||||||
DefaultFunction::VerifySignature => todo!(),
|
DefaultFunction::VerifySignature => todo!(),
|
||||||
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::AppendString => todo!(),
|
DefaultFunction::AppendString => 0,
|
||||||
DefaultFunction::EqualsString => todo!(),
|
DefaultFunction::EqualsString => 0,
|
||||||
DefaultFunction::EncodeUtf8 => todo!(),
|
DefaultFunction::EncodeUtf8 => 0,
|
||||||
DefaultFunction::DecodeUtf8 => todo!(),
|
DefaultFunction::DecodeUtf8 => 0,
|
||||||
DefaultFunction::IfThenElse => 1,
|
DefaultFunction::IfThenElse => 1,
|
||||||
DefaultFunction::ChooseUnit => 1,
|
DefaultFunction::ChooseUnit => 1,
|
||||||
DefaultFunction::Trace => todo!(),
|
DefaultFunction::Trace => 1,
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
DefaultFunction::SndPair => todo!(),
|
DefaultFunction::SndPair => todo!(),
|
||||||
DefaultFunction::ChooseList => todo!(),
|
DefaultFunction::ChooseList => todo!(),
|
||||||
|
@ -192,41 +192,53 @@ impl DefaultFunction {
|
||||||
match self {
|
match self {
|
||||||
DefaultFunction::AddInteger => arg.expect_type(Type::Integer),
|
DefaultFunction::AddInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::SubtractInteger => arg.expect_type(Type::Integer),
|
DefaultFunction::SubtractInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::MultiplyInteger => todo!(),
|
DefaultFunction::MultiplyInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::DivideInteger => todo!(),
|
DefaultFunction::DivideInteger => todo!(),
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => todo!(),
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => todo!(),
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => todo!(),
|
||||||
DefaultFunction::EqualsInteger => todo!(),
|
DefaultFunction::EqualsInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::LessThanInteger => todo!(),
|
DefaultFunction::LessThanInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::LessThanEqualsInteger => arg.expect_type(Type::Integer),
|
DefaultFunction::LessThanEqualsInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::AppendByteString => todo!(),
|
DefaultFunction::AppendByteString => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::ConsByteString => todo!(),
|
DefaultFunction::ConsByteString => todo!(),
|
||||||
DefaultFunction::SliceByteString => todo!(),
|
DefaultFunction::SliceByteString => todo!(),
|
||||||
DefaultFunction::LengthOfByteString => todo!(),
|
DefaultFunction::LengthOfByteString => todo!(),
|
||||||
DefaultFunction::IndexByteString => todo!(),
|
DefaultFunction::IndexByteString => todo!(),
|
||||||
DefaultFunction::EqualsByteString => todo!(),
|
DefaultFunction::EqualsByteString => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::LessThanByteString => todo!(),
|
DefaultFunction::LessThanByteString => todo!(),
|
||||||
DefaultFunction::LessThanEqualsByteString => todo!(),
|
DefaultFunction::LessThanEqualsByteString => todo!(),
|
||||||
DefaultFunction::Sha2_256 => todo!(),
|
DefaultFunction::Sha2_256 => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::Sha3_256 => todo!(),
|
DefaultFunction::Sha3_256 => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::Blake2b_256 => todo!(),
|
DefaultFunction::Blake2b_256 => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::VerifySignature => todo!(),
|
DefaultFunction::VerifySignature => todo!(),
|
||||||
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::AppendString => todo!(),
|
DefaultFunction::AppendString => arg.expect_type(Type::String),
|
||||||
DefaultFunction::EqualsString => todo!(),
|
DefaultFunction::EqualsString => arg.expect_type(Type::String),
|
||||||
DefaultFunction::EncodeUtf8 => todo!(),
|
DefaultFunction::EncodeUtf8 => arg.expect_type(Type::String),
|
||||||
DefaultFunction::DecodeUtf8 => todo!(),
|
DefaultFunction::DecodeUtf8 => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::IfThenElse => {
|
DefaultFunction::IfThenElse => {
|
||||||
if args.is_empty() && !arg.is_bool() {
|
if args.is_empty() {
|
||||||
arg.expect_type(Type::Bool)
|
arg.expect_type(Type::Bool)
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefaultFunction::ChooseUnit => todo!(),
|
DefaultFunction::ChooseUnit => {
|
||||||
DefaultFunction::Trace => todo!(),
|
if args.is_empty() {
|
||||||
|
arg.expect_type(Type::Unit)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultFunction::Trace => {
|
||||||
|
if args.is_empty() {
|
||||||
|
arg.expect_type(Type::String)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
DefaultFunction::SndPair => todo!(),
|
DefaultFunction::SndPair => todo!(),
|
||||||
DefaultFunction::ChooseList => todo!(),
|
DefaultFunction::ChooseList => todo!(),
|
||||||
|
@ -256,7 +268,7 @@ impl DefaultFunction {
|
||||||
// This should be safe because we've already checked
|
// This should be safe because we've already checked
|
||||||
// the types of the args as they were pushed. Although
|
// the types of the args as they were pushed. Although
|
||||||
// the unreachables look ugly, it's the reality of the situation.
|
// the unreachables look ugly, it's the reality of the situation.
|
||||||
pub fn call(&self, args: &[Value]) -> Result<Value, Error> {
|
pub fn call(&self, args: &[Value], logs: &mut Vec<String>) -> Result<Value, Error> {
|
||||||
match self {
|
match self {
|
||||||
DefaultFunction::AddInteger => {
|
DefaultFunction::AddInteger => {
|
||||||
let args = (&args[0], &args[1]);
|
let args = (&args[0], &args[1]);
|
||||||
|
@ -278,13 +290,40 @@ impl DefaultFunction {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefaultFunction::MultiplyInteger => todo!(),
|
DefaultFunction::MultiplyInteger => {
|
||||||
|
let args = (&args[0], &args[1]);
|
||||||
|
|
||||||
|
match args {
|
||||||
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
|
Ok(Value::Con(Constant::Integer(arg1 * arg2)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
DefaultFunction::DivideInteger => todo!(),
|
DefaultFunction::DivideInteger => todo!(),
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => todo!(),
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => todo!(),
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => todo!(),
|
||||||
DefaultFunction::EqualsInteger => todo!(),
|
DefaultFunction::EqualsInteger => {
|
||||||
DefaultFunction::LessThanInteger => todo!(),
|
let args = (&args[0], &args[1]);
|
||||||
|
|
||||||
|
match args {
|
||||||
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
|
Ok(Value::Con(Constant::Bool(arg1 == arg2)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultFunction::LessThanInteger => {
|
||||||
|
let args = (&args[0], &args[1]);
|
||||||
|
|
||||||
|
match args {
|
||||||
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
|
Ok(Value::Con(Constant::Bool(arg1 < arg2)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
DefaultFunction::LessThanEqualsInteger => {
|
DefaultFunction::LessThanEqualsInteger => {
|
||||||
let args = (&args[0], &args[1]);
|
let args = (&args[0], &args[1]);
|
||||||
|
|
||||||
|
@ -295,24 +334,121 @@ impl DefaultFunction {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefaultFunction::AppendByteString => todo!(),
|
DefaultFunction::AppendByteString => {
|
||||||
|
let args = (&args[0], &args[1]);
|
||||||
|
|
||||||
|
match args {
|
||||||
|
(
|
||||||
|
Value::Con(Constant::ByteString(arg1)),
|
||||||
|
Value::Con(Constant::ByteString(arg2)),
|
||||||
|
) => Ok(Value::Con(Constant::ByteString(
|
||||||
|
arg1.iter().copied().chain(arg2.iter().copied()).collect(),
|
||||||
|
))),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
DefaultFunction::ConsByteString => todo!(),
|
DefaultFunction::ConsByteString => todo!(),
|
||||||
DefaultFunction::SliceByteString => todo!(),
|
DefaultFunction::SliceByteString => todo!(),
|
||||||
DefaultFunction::LengthOfByteString => todo!(),
|
DefaultFunction::LengthOfByteString => todo!(),
|
||||||
DefaultFunction::IndexByteString => todo!(),
|
DefaultFunction::IndexByteString => todo!(),
|
||||||
DefaultFunction::EqualsByteString => todo!(),
|
DefaultFunction::EqualsByteString => {
|
||||||
|
let args = (&args[0], &args[1]);
|
||||||
|
|
||||||
|
match args {
|
||||||
|
(
|
||||||
|
Value::Con(Constant::ByteString(arg1)),
|
||||||
|
Value::Con(Constant::ByteString(arg2)),
|
||||||
|
) => Ok(Value::Con(Constant::Bool(arg1 == arg2))),
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
DefaultFunction::LessThanByteString => todo!(),
|
DefaultFunction::LessThanByteString => todo!(),
|
||||||
DefaultFunction::LessThanEqualsByteString => todo!(),
|
DefaultFunction::LessThanEqualsByteString => todo!(),
|
||||||
DefaultFunction::Sha2_256 => todo!(),
|
DefaultFunction::Sha2_256 => match &args[0] {
|
||||||
DefaultFunction::Sha3_256 => todo!(),
|
Value::Con(Constant::ByteString(arg1)) => {
|
||||||
DefaultFunction::Blake2b_256 => todo!(),
|
use cryptoxide::{digest::Digest, sha2::Sha256};
|
||||||
|
|
||||||
|
let mut hasher = Sha256::new();
|
||||||
|
|
||||||
|
hasher.input(arg1);
|
||||||
|
|
||||||
|
let mut bytes = vec![0; hasher.output_bytes()];
|
||||||
|
|
||||||
|
hasher.result(&mut bytes);
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::ByteString(bytes)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::Sha3_256 => match &args[0] {
|
||||||
|
Value::Con(Constant::ByteString(arg1)) => {
|
||||||
|
use cryptoxide::{digest::Digest, sha3::Sha3_256};
|
||||||
|
|
||||||
|
let mut hasher = Sha3_256::new();
|
||||||
|
|
||||||
|
hasher.input(arg1);
|
||||||
|
|
||||||
|
let mut bytes = vec![0; hasher.output_bytes()];
|
||||||
|
|
||||||
|
hasher.result(&mut bytes);
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::ByteString(bytes)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::Blake2b_256 => match &args[0] {
|
||||||
|
Value::Con(Constant::ByteString(arg1)) => {
|
||||||
|
use cryptoxide::{blake2b::Blake2b, digest::Digest};
|
||||||
|
|
||||||
|
let mut digest = [0u8; 32];
|
||||||
|
let mut context = Blake2b::new(32);
|
||||||
|
|
||||||
|
context.input(arg1);
|
||||||
|
context.result(&mut digest);
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::ByteString(digest.to_vec())))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
DefaultFunction::VerifySignature => todo!(),
|
DefaultFunction::VerifySignature => todo!(),
|
||||||
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::AppendString => todo!(),
|
DefaultFunction::AppendString => {
|
||||||
DefaultFunction::EqualsString => todo!(),
|
let args = (&args[0], &args[1]);
|
||||||
DefaultFunction::EncodeUtf8 => todo!(),
|
|
||||||
DefaultFunction::DecodeUtf8 => todo!(),
|
match args {
|
||||||
|
(Value::Con(Constant::String(arg1)), Value::Con(Constant::String(arg2))) => {
|
||||||
|
Ok(Value::Con(Constant::String(format!("{}{}", arg1, arg2))))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultFunction::EqualsString => {
|
||||||
|
let args = (&args[0], &args[1]);
|
||||||
|
|
||||||
|
match args {
|
||||||
|
(Value::Con(Constant::String(arg1)), Value::Con(Constant::String(arg2))) => {
|
||||||
|
Ok(Value::Con(Constant::Bool(arg1 == arg2)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultFunction::EncodeUtf8 => match &args[0] {
|
||||||
|
Value::Con(Constant::String(arg1)) => {
|
||||||
|
let bytes = arg1.as_bytes().to_vec();
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::ByteString(bytes)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::DecodeUtf8 => match &args[0] {
|
||||||
|
Value::Con(Constant::ByteString(arg1)) => {
|
||||||
|
let string = String::from_utf8(arg1.clone())?;
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::String(string)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
DefaultFunction::IfThenElse => match args[0] {
|
DefaultFunction::IfThenElse => match args[0] {
|
||||||
Value::Con(Constant::Bool(condition)) => {
|
Value::Con(Constant::Bool(condition)) => {
|
||||||
if condition {
|
if condition {
|
||||||
|
@ -323,8 +459,18 @@ impl DefaultFunction {
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
DefaultFunction::ChooseUnit => todo!(),
|
DefaultFunction::ChooseUnit => match &args[0] {
|
||||||
DefaultFunction::Trace => todo!(),
|
Value::Con(Constant::Unit) => Ok(args[1].clone()),
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::Trace => match &args[0] {
|
||||||
|
Value::Con(Constant::String(arg1)) => {
|
||||||
|
logs.push(arg1.clone());
|
||||||
|
|
||||||
|
Ok(args[1].clone())
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
DefaultFunction::FstPair => todo!(),
|
DefaultFunction::FstPair => todo!(),
|
||||||
DefaultFunction::SndPair => todo!(),
|
DefaultFunction::SndPair => todo!(),
|
||||||
DefaultFunction::ChooseList => todo!(),
|
DefaultFunction::ChooseList => todo!(),
|
||||||
|
|
Loading…
Reference in New Issue