Skip to content

Commit

Permalink
First crack at Dialect.
Browse files Browse the repository at this point in the history
  • Loading branch information
richardkiss committed Aug 21, 2021
1 parent ffaee39 commit ca503f6
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 16 deletions.
90 changes: 90 additions & 0 deletions src/chia_dialect_factory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
use std::collections::HashMap;

use crate::allocator::{Allocator, NodePtr};
use crate::cost::Cost;
use crate::dialect::Dialect;
use crate::err_utils::err;
use crate::f_table::{f_lookup_for_hashmap, FLookup};
use crate::more_ops::op_unknown;
use crate::reduction::Response;
use crate::run_program::OperatorHandler;

const QUOTE_KW: [u8; 1] = [1];
const APPLY_KW: [u8; 1] = [2];

pub fn chia_op_handler(strict: bool) -> Box<dyn OperatorHandler> {
let f_lookup: FLookup = f_lookup_for_hashmap(chia_opcode_mapping());

Box::new(OperatorHandlerWithMode { f_lookup, strict })
}

pub fn chia_dialect(strict: bool) -> Dialect {
Dialect::new(&QUOTE_KW, &APPLY_KW, chia_op_handler(strict))
}

pub struct OperatorHandlerWithMode {
f_lookup: FLookup,
strict: bool,
}

impl OperatorHandler for OperatorHandlerWithMode {
fn op(
&self,
allocator: &mut Allocator,
o: NodePtr,
argument_list: NodePtr,
max_cost: Cost,
) -> Response {
let b = &allocator.atom(o);
if b.len() == 1 {
if let Some(f) = self.f_lookup[b[0] as usize] {
return f(allocator, argument_list, max_cost);
}
}
if self.strict {
err(o, "unimplemented operator")
} else {
op_unknown(allocator, o, argument_list, max_cost)
}
}
}

pub fn chia_opcode_mapping() -> HashMap<String, Vec<u8>> {
let mut h = HashMap::new();
let items = [
(3, "op_if"),
(4, "op_cons"),
(5, "op_first"),
(6, "op_rest"),
(7, "op_list"),
(8, "op_raise"),
(9, "op_eq"),
(10, "op_gr_bytes"),
(11, "op_sha256"),
(12, "op_substr"),
(13, "op_strlen"),
(14, "op_concat"),
(16, "op_add"),
(17, "op_subtract"),
(18, "op_multiply"),
(19, "op_divide"),
(20, "op_divmod"),
(21, "op_greater"),
(22, "op_ash"),
(23, "op_lsh"),
(24, "op_logand"),
(25, "op_logior"),
(26, "op_logxor"),
(27, "op_lognot"),
(29, "op_point_add"),
(30, "op_pubkey_for_exp"),
(32, "op_not"),
(33, "op_any"),
(34, "op_all"),
(36, "op_softfork"),
];
for (k, v) in items {
h.insert(v.to_string(), [k as u8].into());
}
h
}
55 changes: 55 additions & 0 deletions src/dialect.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use crate::allocator::{Allocator, NodePtr};
use crate::cost::Cost;
use crate::reduction::Response;
use crate::run_program::{OperatorHandler, PreEval, RunProgramContext};

pub struct Dialect {
quote_kw: Vec<u8>,
apply_kw: Vec<u8>,
op_handler: Box<dyn OperatorHandler>,
}

impl OperatorHandler for Dialect {
fn op(
&self,
allocator: &mut Allocator,
op: NodePtr,
args: NodePtr,
max_cost: Cost,
) -> Response {
self.op_handler.op(allocator, op, args, max_cost)
}
}

impl Dialect {
pub fn new(quote_kw: &[u8], apply_kw: &[u8], op_handler: Box<dyn OperatorHandler>) -> Self {
Dialect {
quote_kw: quote_kw.to_owned(),
apply_kw: apply_kw.to_owned(),
op_handler,
}
}

pub fn run_program_with_pre_eval(
&self,
allocator: &mut Allocator,
program: NodePtr,
args: NodePtr,
max_cost: Cost,
pre_eval: Option<PreEval>,
) -> Response {
let mut rpc =
RunProgramContext::new(allocator, &self.quote_kw, &self.apply_kw, self, pre_eval);
rpc.run_program(program, args, max_cost)
}

pub fn run_program(
&self,
allocator: &mut Allocator,
program: NodePtr,
args: NodePtr,
max_cost: Cost,
) -> Response {
self.run_program_with_pre_eval(allocator, program, args, max_cost, None)
}
}
28 changes: 15 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
mod allocator;
mod core_ops;
mod cost;
mod err_utils;
mod f_table;
pub mod allocator;
pub mod chia_dialect_factory;
pub mod core_ops;
pub mod cost;
pub mod dialect;
pub mod err_utils;
pub mod f_table;
mod gen;
mod int_to_bytes;
mod more_ops;
mod node;
mod number;
mod op_utils;
pub mod int_to_bytes;
pub mod more_ops;
pub mod node;
pub mod number;
pub mod op_utils;
#[cfg(not(any(test, target_family = "wasm")))]
mod py;
mod reduction;
mod run_program;
mod serialize;
pub mod reduction;
pub mod run_program;
pub mod serialize;
mod sha2;

#[cfg(test)]
Expand Down
4 changes: 1 addition & 3 deletions src/run_program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ fn augment_cost_errors(r: Result<Cost, EvalErr>, max_cost: NodePtr) -> Result<Co
}

impl<'a> RunProgramContext<'a> {
fn new(
pub fn new(
allocator: &'a mut Allocator,
quote_kw: &'a [u8],
apply_kw: &'a [u8],
Expand Down Expand Up @@ -178,9 +178,7 @@ impl<'a> RunProgramContext<'a> {
self.push(p);
Ok(0)
}
}

impl<'a> RunProgramContext<'a> {
fn eval_op_atom(
&mut self,
op_buf: &AtomBuf,
Expand Down

0 comments on commit ca503f6

Please sign in to comment.