use std::{fmt::Write as _, fs}; use uplc::{ ast::{DeBruijn, FakeNamedDeBruijn, Name, NamedDeBruijn, Program, Term}, machine::cost_model::ExBudget, parser, }; mod args; use args::{Args, UplcCommand}; fn main() -> anyhow::Result<()> { let args = Args::default(); match args { Args::Build => { // 1. load and parse modules // * lib - contains modules, types, and functions // * contracts - contains validators // * scripts - contains native scripts dsl // 2. type check everything // 3. generate uplc and policy/address if relevant todo!() } Args::Dev => { // launch a development server // this should allow people to test // their contracts over http todo!() } Args::New { name } => { if !name.exists() { fs::create_dir_all(name.join("lib"))?; fs::create_dir_all(name.join("policies"))?; fs::create_dir_all(name.join("scripts"))?; } } Args::Uplc(uplc) => match uplc { UplcCommand::Flat { input, print, out } => { let code = std::fs::read_to_string(&input)?; let program = parser::program(&code)?; let program = Program::::try_from(program)?; let bytes = program.to_flat()?; if print { let mut output = String::new(); for (i, byte) in bytes.iter().enumerate() { let _ = write!(output, "{:08b}", byte); if (i + 1) % 4 == 0 { output.push('\n'); } else { output.push(' '); } } println!("{}", output); } else { let out_name = if let Some(out) = out { out } else { format!("{}.flat", input.file_stem().unwrap().to_str().unwrap()) }; fs::write(&out_name, &bytes)?; } } UplcCommand::Fmt { input, print } => { let code = std::fs::read_to_string(&input)?; let program = parser::program(&code)?; let pretty = program.to_pretty(); if print { println!("{}", pretty); } else { fs::write(&input, pretty)?; } } UplcCommand::Unflat { input, print, out } => { let bytes = std::fs::read(&input)?; let program = Program::::from_flat(&bytes)?; let program: Program = program.try_into()?; let pretty = program.to_pretty(); if print { println!("{}", pretty); } else { let out_name = if let Some(out) = out { out } else { format!("{}.uplc", input.file_stem().unwrap().to_str().unwrap()) }; fs::write(&out_name, pretty)?; } } UplcCommand::Eval { input, flat } => { let program = if flat { let bytes = std::fs::read(&input)?; let prog = Program::::from_flat(&bytes)?; prog.into() } else { let code = std::fs::read_to_string(&input)?; let prog = parser::program(&code)?; Program::::try_from(prog)? }; let (term, cost, logs) = program.eval(); match term { Ok(term) => { let term: Term = term.try_into()?; println!("\nResult\n------\n\n{}\n", term.to_pretty()); } Err(err) => { eprintln!("\nError\n-----\n\n{}\n", err); } } 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 ); println!("\nLogs\n----\n{}", logs.join("\n")) } }, } Ok(()) }