Implement more builtins for bytestring and integer
Co-authored-by: rvcas <x@rvcas.dev>
This commit is contained in:
parent
7f1ffd8e2f
commit
f3ace55355
|
@ -1,5 +1,5 @@
|
||||||
(program
|
(program
|
||||||
1.0.0
|
1.0.0
|
||||||
[ (builtin decodeUtf8) [ (builtin encodeUtf8) (con string "hello world") ] ]
|
[ (builtin divideInteger) (con integer 5) (con integer 2) ]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ use std::{fmt::Write as _, fs};
|
||||||
|
|
||||||
use uplc::{
|
use uplc::{
|
||||||
ast::{DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Program, Term},
|
ast::{DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Program, Term},
|
||||||
|
machine::cost_model::ExBudget,
|
||||||
parser,
|
parser,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,14 +103,24 @@ fn main() -> anyhow::Result<()> {
|
||||||
Ok(term) => {
|
Ok(term) => {
|
||||||
let term: Term<Name> = term.try_into()?;
|
let term: Term<Name> = term.try_into()?;
|
||||||
|
|
||||||
println!("{}", term.to_pretty());
|
println!("\nResult\n------\n\n{}\n", term.to_pretty());
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("{}", err);
|
eprintln!("\nError\n-----\n\n{}\n", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("\nCosts - memory: {} & cpu: {}", cost.mem, cost.cpu);
|
let budget = ExBudget::default();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"\nCosts\n-----\ncpu: {}\nmemory: {}",
|
||||||
|
budget.cpu - cost.cpu,
|
||||||
|
budget.mem - cost.mem
|
||||||
|
);
|
||||||
|
println!(
|
||||||
|
"\nBudget\n------\ncpu: {}\nmemory: {}\n",
|
||||||
|
cost.cpu, cost.mem
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -562,7 +562,16 @@ 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::DivideInteger => todo!(),
|
DefaultFunction::DivideInteger => ExBudget {
|
||||||
|
mem: self
|
||||||
|
.divide_integer
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.divide_integer
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => todo!(),
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => todo!(),
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => todo!(),
|
||||||
|
@ -606,10 +615,42 @@ 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::ConsByteString => todo!(),
|
DefaultFunction::ConsByteString => ExBudget {
|
||||||
DefaultFunction::SliceByteString => todo!(),
|
mem: self
|
||||||
DefaultFunction::LengthOfByteString => todo!(),
|
.cons_byte_string
|
||||||
DefaultFunction::IndexByteString => todo!(),
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.cons_byte_string
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::SliceByteString => ExBudget {
|
||||||
|
mem: self.slice_byte_string.mem.cost(
|
||||||
|
args[0].to_ex_mem(),
|
||||||
|
args[1].to_ex_mem(),
|
||||||
|
args[2].to_ex_mem(),
|
||||||
|
),
|
||||||
|
cpu: self.slice_byte_string.cpu.cost(
|
||||||
|
args[0].to_ex_mem(),
|
||||||
|
args[1].to_ex_mem(),
|
||||||
|
args[2].to_ex_mem(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
DefaultFunction::LengthOfByteString => ExBudget {
|
||||||
|
mem: self.length_of_byte_string.mem.cost(args[0].to_ex_mem()),
|
||||||
|
cpu: self.length_of_byte_string.cpu.cost(args[0].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::IndexByteString => ExBudget {
|
||||||
|
mem: self
|
||||||
|
.index_byte_string
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.index_byte_string
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::EqualsByteString => ExBudget {
|
DefaultFunction::EqualsByteString => ExBudget {
|
||||||
mem: self
|
mem: self
|
||||||
.equals_byte_string
|
.equals_byte_string
|
||||||
|
@ -620,8 +661,26 @@ 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::LessThanByteString => todo!(),
|
DefaultFunction::LessThanByteString => ExBudget {
|
||||||
DefaultFunction::LessThanEqualsByteString => todo!(),
|
mem: self
|
||||||
|
.less_than_byte_string
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.less_than_byte_string
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
|
DefaultFunction::LessThanEqualsByteString => ExBudget {
|
||||||
|
mem: self
|
||||||
|
.less_than_equals_byte_string
|
||||||
|
.mem
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
cpu: self
|
||||||
|
.less_than_equals_byte_string
|
||||||
|
.cpu
|
||||||
|
.cost(args[0].to_ex_mem(), args[1].to_ex_mem()),
|
||||||
|
},
|
||||||
DefaultFunction::Sha2_256 => ExBudget {
|
DefaultFunction::Sha2_256 => ExBudget {
|
||||||
mem: self.sha2_256.mem.cost(args[0].to_ex_mem()),
|
mem: self.sha2_256.mem.cost(args[0].to_ex_mem()),
|
||||||
cpu: self.sha2_256.cpu.cost(args[0].to_ex_mem()),
|
cpu: self.sha2_256.cpu.cost(args[0].to_ex_mem()),
|
||||||
|
@ -763,7 +822,7 @@ impl TwoArguments {
|
||||||
TwoArguments::LinearInX(l) => l.slope * x + l.intercept,
|
TwoArguments::LinearInX(l) => l.slope * x + l.intercept,
|
||||||
TwoArguments::LinearInY(l) => l.slope * y + l.intercept,
|
TwoArguments::LinearInY(l) => l.slope * y + l.intercept,
|
||||||
TwoArguments::AddedSizes(s) => s.slope * (x + y) + s.intercept,
|
TwoArguments::AddedSizes(s) => s.slope * (x + y) + s.intercept,
|
||||||
TwoArguments::SubtractedSizes(s) => s.slope * s.minimum.min(x - y) + s.intercept,
|
TwoArguments::SubtractedSizes(s) => s.slope * s.minimum.max(x - y) + s.intercept,
|
||||||
TwoArguments::MultipliedSizes(s) => s.slope * (x * y) + s.intercept,
|
TwoArguments::MultipliedSizes(s) => s.slope * (x * y) + s.intercept,
|
||||||
TwoArguments::MinSize(s) => s.slope * x.min(y) + s.intercept,
|
TwoArguments::MinSize(s) => s.slope * x.min(y) + s.intercept,
|
||||||
TwoArguments::MaxSize(s) => s.slope * x.max(y) + s.intercept,
|
TwoArguments::MaxSize(s) => s.slope * x.max(y) + s.intercept,
|
||||||
|
|
|
@ -32,4 +32,8 @@ pub enum Error {
|
||||||
MachineNeverReachedDone,
|
MachineNeverReachedDone,
|
||||||
#[error("Decoding utf8")]
|
#[error("Decoding utf8")]
|
||||||
Utf8(#[from] FromUtf8Error),
|
Utf8(#[from] FromUtf8Error),
|
||||||
|
#[error("Out of Bounds\n\nindex: {}\nbytestring: {}\npossible: 0 - {}", .0, hex::encode(.1), .1.len() - 1)]
|
||||||
|
ByteStringOutOfBounds(isize, Vec<u8>),
|
||||||
|
#[error("Divide By Zero\n\n{0} / {1}")]
|
||||||
|
DivideByZero(isize, isize),
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ impl DefaultFunction {
|
||||||
DefaultFunction::AddInteger => 2,
|
DefaultFunction::AddInteger => 2,
|
||||||
DefaultFunction::SubtractInteger => 2,
|
DefaultFunction::SubtractInteger => 2,
|
||||||
DefaultFunction::MultiplyInteger => 2,
|
DefaultFunction::MultiplyInteger => 2,
|
||||||
DefaultFunction::DivideInteger => todo!(),
|
DefaultFunction::DivideInteger => 2,
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => todo!(),
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => todo!(),
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => todo!(),
|
||||||
|
@ -83,13 +83,13 @@ impl DefaultFunction {
|
||||||
DefaultFunction::LessThanInteger => 2,
|
DefaultFunction::LessThanInteger => 2,
|
||||||
DefaultFunction::LessThanEqualsInteger => 2,
|
DefaultFunction::LessThanEqualsInteger => 2,
|
||||||
DefaultFunction::AppendByteString => 2,
|
DefaultFunction::AppendByteString => 2,
|
||||||
DefaultFunction::ConsByteString => todo!(),
|
DefaultFunction::ConsByteString => 2,
|
||||||
DefaultFunction::SliceByteString => todo!(),
|
DefaultFunction::SliceByteString => 3,
|
||||||
DefaultFunction::LengthOfByteString => todo!(),
|
DefaultFunction::LengthOfByteString => 1,
|
||||||
DefaultFunction::IndexByteString => todo!(),
|
DefaultFunction::IndexByteString => 2,
|
||||||
DefaultFunction::EqualsByteString => 2,
|
DefaultFunction::EqualsByteString => 2,
|
||||||
DefaultFunction::LessThanByteString => todo!(),
|
DefaultFunction::LessThanByteString => 2,
|
||||||
DefaultFunction::LessThanEqualsByteString => todo!(),
|
DefaultFunction::LessThanEqualsByteString => 2,
|
||||||
DefaultFunction::Sha2_256 => 1,
|
DefaultFunction::Sha2_256 => 1,
|
||||||
DefaultFunction::Sha3_256 => 1,
|
DefaultFunction::Sha3_256 => 1,
|
||||||
DefaultFunction::Blake2b_256 => 1,
|
DefaultFunction::Blake2b_256 => 1,
|
||||||
|
@ -134,7 +134,7 @@ impl DefaultFunction {
|
||||||
DefaultFunction::AddInteger => 0,
|
DefaultFunction::AddInteger => 0,
|
||||||
DefaultFunction::SubtractInteger => 0,
|
DefaultFunction::SubtractInteger => 0,
|
||||||
DefaultFunction::MultiplyInteger => 0,
|
DefaultFunction::MultiplyInteger => 0,
|
||||||
DefaultFunction::DivideInteger => todo!(),
|
DefaultFunction::DivideInteger => 0,
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => todo!(),
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => todo!(),
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => todo!(),
|
||||||
|
@ -142,13 +142,13 @@ impl DefaultFunction {
|
||||||
DefaultFunction::LessThanInteger => 0,
|
DefaultFunction::LessThanInteger => 0,
|
||||||
DefaultFunction::LessThanEqualsInteger => 0,
|
DefaultFunction::LessThanEqualsInteger => 0,
|
||||||
DefaultFunction::AppendByteString => 0,
|
DefaultFunction::AppendByteString => 0,
|
||||||
DefaultFunction::ConsByteString => todo!(),
|
DefaultFunction::ConsByteString => 0,
|
||||||
DefaultFunction::SliceByteString => todo!(),
|
DefaultFunction::SliceByteString => 0,
|
||||||
DefaultFunction::LengthOfByteString => todo!(),
|
DefaultFunction::LengthOfByteString => 0,
|
||||||
DefaultFunction::IndexByteString => todo!(),
|
DefaultFunction::IndexByteString => 0,
|
||||||
DefaultFunction::EqualsByteString => 0,
|
DefaultFunction::EqualsByteString => 0,
|
||||||
DefaultFunction::LessThanByteString => todo!(),
|
DefaultFunction::LessThanByteString => 0,
|
||||||
DefaultFunction::LessThanEqualsByteString => todo!(),
|
DefaultFunction::LessThanEqualsByteString => 0,
|
||||||
DefaultFunction::Sha2_256 => 0,
|
DefaultFunction::Sha2_256 => 0,
|
||||||
DefaultFunction::Sha3_256 => 0,
|
DefaultFunction::Sha3_256 => 0,
|
||||||
DefaultFunction::Blake2b_256 => 0,
|
DefaultFunction::Blake2b_256 => 0,
|
||||||
|
@ -193,7 +193,7 @@ impl DefaultFunction {
|
||||||
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 => arg.expect_type(Type::Integer),
|
DefaultFunction::MultiplyInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::DivideInteger => todo!(),
|
DefaultFunction::DivideInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => todo!(),
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => todo!(),
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => todo!(),
|
||||||
|
@ -201,13 +201,31 @@ impl DefaultFunction {
|
||||||
DefaultFunction::LessThanInteger => arg.expect_type(Type::Integer),
|
DefaultFunction::LessThanInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::LessThanEqualsInteger => arg.expect_type(Type::Integer),
|
DefaultFunction::LessThanEqualsInteger => arg.expect_type(Type::Integer),
|
||||||
DefaultFunction::AppendByteString => arg.expect_type(Type::ByteString),
|
DefaultFunction::AppendByteString => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::ConsByteString => todo!(),
|
DefaultFunction::ConsByteString => {
|
||||||
DefaultFunction::SliceByteString => todo!(),
|
if args.is_empty() {
|
||||||
DefaultFunction::LengthOfByteString => todo!(),
|
arg.expect_type(Type::Integer)
|
||||||
DefaultFunction::IndexByteString => todo!(),
|
} else {
|
||||||
|
arg.expect_type(Type::ByteString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultFunction::SliceByteString => {
|
||||||
|
if args.len() < 2 {
|
||||||
|
arg.expect_type(Type::Integer)
|
||||||
|
} else {
|
||||||
|
arg.expect_type(Type::ByteString)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefaultFunction::LengthOfByteString => arg.expect_type(Type::ByteString),
|
||||||
|
DefaultFunction::IndexByteString => {
|
||||||
|
if args.is_empty() {
|
||||||
|
arg.expect_type(Type::ByteString)
|
||||||
|
} else {
|
||||||
|
arg.expect_type(Type::Integer)
|
||||||
|
}
|
||||||
|
}
|
||||||
DefaultFunction::EqualsByteString => arg.expect_type(Type::ByteString),
|
DefaultFunction::EqualsByteString => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::LessThanByteString => todo!(),
|
DefaultFunction::LessThanByteString => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::LessThanEqualsByteString => todo!(),
|
DefaultFunction::LessThanEqualsByteString => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::Sha2_256 => arg.expect_type(Type::ByteString),
|
DefaultFunction::Sha2_256 => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::Sha3_256 => arg.expect_type(Type::ByteString),
|
DefaultFunction::Sha3_256 => arg.expect_type(Type::ByteString),
|
||||||
DefaultFunction::Blake2b_256 => arg.expect_type(Type::ByteString),
|
DefaultFunction::Blake2b_256 => arg.expect_type(Type::ByteString),
|
||||||
|
@ -270,74 +288,58 @@ impl DefaultFunction {
|
||||||
// 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], logs: &mut Vec<String>) -> Result<Value, Error> {
|
pub fn call(&self, args: &[Value], logs: &mut Vec<String>) -> Result<Value, Error> {
|
||||||
match self {
|
match self {
|
||||||
DefaultFunction::AddInteger => {
|
DefaultFunction::AddInteger => match (&args[0], &args[1]) {
|
||||||
let args = (&args[0], &args[1]);
|
|
||||||
|
|
||||||
match args {
|
|
||||||
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
Ok(Value::Con(Constant::Integer(arg1 + arg2)))
|
Ok(Value::Con(Constant::Integer(arg1 + arg2)))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
},
|
||||||
}
|
DefaultFunction::SubtractInteger => match (&args[0], &args[1]) {
|
||||||
DefaultFunction::SubtractInteger => {
|
|
||||||
let args = (&args[0], &args[1]);
|
|
||||||
|
|
||||||
match args {
|
|
||||||
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
Ok(Value::Con(Constant::Integer(arg1 - arg2)))
|
Ok(Value::Con(Constant::Integer(arg1 - arg2)))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
},
|
||||||
}
|
DefaultFunction::MultiplyInteger => match (&args[0], &args[1]) {
|
||||||
DefaultFunction::MultiplyInteger => {
|
|
||||||
let args = (&args[0], &args[1]);
|
|
||||||
|
|
||||||
match args {
|
|
||||||
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
Ok(Value::Con(Constant::Integer(arg1 * arg2)))
|
Ok(Value::Con(Constant::Integer(arg1 * arg2)))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::DivideInteger => match (&args[0], &args[1]) {
|
||||||
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
|
if *arg2 != 0 {
|
||||||
|
let ret = (*arg1 as f64) / (*arg2 as f64);
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::Integer(ret.floor() as isize)))
|
||||||
|
} else {
|
||||||
|
Err(Error::DivideByZero(*arg1, *arg2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefaultFunction::DivideInteger => todo!(),
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
DefaultFunction::QuotientInteger => todo!(),
|
DefaultFunction::QuotientInteger => todo!(),
|
||||||
DefaultFunction::RemainderInteger => todo!(),
|
DefaultFunction::RemainderInteger => todo!(),
|
||||||
DefaultFunction::ModInteger => todo!(),
|
DefaultFunction::ModInteger => todo!(),
|
||||||
DefaultFunction::EqualsInteger => {
|
DefaultFunction::EqualsInteger => match (&args[0], &args[1]) {
|
||||||
let args = (&args[0], &args[1]);
|
|
||||||
|
|
||||||
match args {
|
|
||||||
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
Ok(Value::Con(Constant::Bool(arg1 == arg2)))
|
Ok(Value::Con(Constant::Bool(arg1 == arg2)))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
},
|
||||||
}
|
DefaultFunction::LessThanInteger => match (&args[0], &args[1]) {
|
||||||
DefaultFunction::LessThanInteger => {
|
|
||||||
let args = (&args[0], &args[1]);
|
|
||||||
|
|
||||||
match args {
|
|
||||||
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
Ok(Value::Con(Constant::Bool(arg1 < arg2)))
|
Ok(Value::Con(Constant::Bool(arg1 < arg2)))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
},
|
||||||
}
|
DefaultFunction::LessThanEqualsInteger => match (&args[0], &args[1]) {
|
||||||
DefaultFunction::LessThanEqualsInteger => {
|
|
||||||
let args = (&args[0], &args[1]);
|
|
||||||
|
|
||||||
match args {
|
|
||||||
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
Ok(Value::Con(Constant::Bool(arg1 <= arg2)))
|
Ok(Value::Con(Constant::Bool(arg1 <= arg2)))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
},
|
||||||
}
|
DefaultFunction::AppendByteString => match (&args[0], &args[1]) {
|
||||||
DefaultFunction::AppendByteString => {
|
|
||||||
let args = (&args[0], &args[1]);
|
|
||||||
|
|
||||||
match args {
|
|
||||||
(
|
(
|
||||||
Value::Con(Constant::ByteString(arg1)),
|
Value::Con(Constant::ByteString(arg1)),
|
||||||
Value::Con(Constant::ByteString(arg2)),
|
Value::Con(Constant::ByteString(arg2)),
|
||||||
|
@ -345,25 +347,72 @@ impl DefaultFunction {
|
||||||
arg1.iter().copied().chain(arg2.iter().copied()).collect(),
|
arg1.iter().copied().chain(arg2.iter().copied()).collect(),
|
||||||
))),
|
))),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
},
|
||||||
}
|
DefaultFunction::ConsByteString => match (&args[0], &args[1]) {
|
||||||
DefaultFunction::ConsByteString => todo!(),
|
(Value::Con(Constant::Integer(arg1)), Value::Con(Constant::ByteString(arg2))) => {
|
||||||
DefaultFunction::SliceByteString => todo!(),
|
let mut ret = vec![(arg1 % 256) as u8];
|
||||||
DefaultFunction::LengthOfByteString => todo!(),
|
ret.extend(arg2.clone());
|
||||||
DefaultFunction::IndexByteString => todo!(),
|
|
||||||
DefaultFunction::EqualsByteString => {
|
|
||||||
let args = (&args[0], &args[1]);
|
|
||||||
|
|
||||||
match args {
|
Ok(Value::Con(Constant::ByteString(ret)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::SliceByteString => match (&args[0], &args[1], &args[2]) {
|
||||||
|
(
|
||||||
|
Value::Con(Constant::Integer(arg1)),
|
||||||
|
Value::Con(Constant::Integer(arg2)),
|
||||||
|
Value::Con(Constant::ByteString(arg3)),
|
||||||
|
) => {
|
||||||
|
let skip = if 0 > *arg1 { 0 } else { *arg1 as usize };
|
||||||
|
let take = if 0 > *arg2 { 0 } else { *arg2 as usize };
|
||||||
|
|
||||||
|
let ret: Vec<u8> = arg3.iter().skip(skip).take(take).cloned().collect();
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::ByteString(ret)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::LengthOfByteString => match &args[0] {
|
||||||
|
Value::Con(Constant::ByteString(arg1)) => {
|
||||||
|
Ok(Value::Con(Constant::Integer(arg1.len() as isize)))
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::IndexByteString => match (&args[0], &args[1]) {
|
||||||
|
(Value::Con(Constant::ByteString(arg1)), Value::Con(Constant::Integer(arg2))) => {
|
||||||
|
let index = *arg2 as usize;
|
||||||
|
|
||||||
|
if 0 <= *arg2 && index < arg1.len() {
|
||||||
|
let ret = arg1[index] as isize;
|
||||||
|
|
||||||
|
Ok(Value::Con(Constant::Integer(ret)))
|
||||||
|
} else {
|
||||||
|
Err(Error::ByteStringOutOfBounds(*arg2, arg1.to_vec()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::EqualsByteString => match (&args[0], &args[1]) {
|
||||||
(
|
(
|
||||||
Value::Con(Constant::ByteString(arg1)),
|
Value::Con(Constant::ByteString(arg1)),
|
||||||
Value::Con(Constant::ByteString(arg2)),
|
Value::Con(Constant::ByteString(arg2)),
|
||||||
) => Ok(Value::Con(Constant::Bool(arg1 == arg2))),
|
) => Ok(Value::Con(Constant::Bool(arg1 == arg2))),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
},
|
||||||
}
|
DefaultFunction::LessThanByteString => match (&args[0], &args[1]) {
|
||||||
DefaultFunction::LessThanByteString => todo!(),
|
(
|
||||||
DefaultFunction::LessThanEqualsByteString => todo!(),
|
Value::Con(Constant::ByteString(arg1)),
|
||||||
|
Value::Con(Constant::ByteString(arg2)),
|
||||||
|
) => Ok(Value::Con(Constant::Bool(arg1 < arg2))),
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
|
DefaultFunction::LessThanEqualsByteString => match (&args[0], &args[1]) {
|
||||||
|
(
|
||||||
|
Value::Con(Constant::ByteString(arg1)),
|
||||||
|
Value::Con(Constant::ByteString(arg2)),
|
||||||
|
) => Ok(Value::Con(Constant::Bool(arg1 <= arg2))),
|
||||||
|
_ => unreachable!(),
|
||||||
|
},
|
||||||
DefaultFunction::Sha2_256 => match &args[0] {
|
DefaultFunction::Sha2_256 => match &args[0] {
|
||||||
Value::Con(Constant::ByteString(arg1)) => {
|
Value::Con(Constant::ByteString(arg1)) => {
|
||||||
use cryptoxide::{digest::Digest, sha2::Sha256};
|
use cryptoxide::{digest::Digest, sha2::Sha256};
|
||||||
|
@ -413,26 +462,18 @@ impl DefaultFunction {
|
||||||
DefaultFunction::VerifySignature => todo!(),
|
DefaultFunction::VerifySignature => todo!(),
|
||||||
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
DefaultFunction::VerifyEcdsaSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
DefaultFunction::VerifySchnorrSecp256k1Signature => todo!(),
|
||||||
DefaultFunction::AppendString => {
|
DefaultFunction::AppendString => match (&args[0], &args[1]) {
|
||||||
let args = (&args[0], &args[1]);
|
|
||||||
|
|
||||||
match args {
|
|
||||||
(Value::Con(Constant::String(arg1)), Value::Con(Constant::String(arg2))) => {
|
(Value::Con(Constant::String(arg1)), Value::Con(Constant::String(arg2))) => {
|
||||||
Ok(Value::Con(Constant::String(format!("{}{}", arg1, arg2))))
|
Ok(Value::Con(Constant::String(format!("{}{}", arg1, arg2))))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
},
|
||||||
}
|
DefaultFunction::EqualsString => match (&args[0], &args[1]) {
|
||||||
DefaultFunction::EqualsString => {
|
|
||||||
let args = (&args[0], &args[1]);
|
|
||||||
|
|
||||||
match args {
|
|
||||||
(Value::Con(Constant::String(arg1)), Value::Con(Constant::String(arg2))) => {
|
(Value::Con(Constant::String(arg1)), Value::Con(Constant::String(arg2))) => {
|
||||||
Ok(Value::Con(Constant::Bool(arg1 == arg2)))
|
Ok(Value::Con(Constant::Bool(arg1 == arg2)))
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
},
|
||||||
}
|
|
||||||
DefaultFunction::EncodeUtf8 => match &args[0] {
|
DefaultFunction::EncodeUtf8 => match &args[0] {
|
||||||
Value::Con(Constant::String(arg1)) => {
|
Value::Con(Constant::String(arg1)) => {
|
||||||
let bytes = arg1.as_bytes().to_vec();
|
let bytes = arg1.as_bytes().to_vec();
|
||||||
|
|
Loading…
Reference in New Issue