main.rs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. use std::{
  2. fs::{read_to_string, File},
  3. io::Write,
  4. process::exit,
  5. };
  6. use clap::Parser as ClapParser;
  7. use darkfi::{
  8. cli_desc,
  9. zkas::{
  10. analyzer::Analyzer, compiler::Compiler, decoder::ZkBinary, lexer::Lexer, parser::Parser,
  11. },
  12. };
  13. #[derive(clap::Parser)]
  14. #[clap(name = "zkas", about = cli_desc!(), version)]
  15. struct Args {
  16. /// Place the output into <FILE>
  17. #[clap(short = 'o', value_name = "FILE")]
  18. output: Option<String>,
  19. /// Strip debug symbols
  20. #[clap(short = 's')]
  21. strip: bool,
  22. /// Preprocess only; do not compile
  23. #[clap(short = 'E')]
  24. evaluate: bool,
  25. /// Interactive semantic analysis
  26. #[clap(short = 'i')]
  27. interactive: bool,
  28. /// Examine decoded bytecode
  29. #[clap(short = 'e')]
  30. examine: bool,
  31. /// ZK script to compile
  32. input: String,
  33. }
  34. fn main() {
  35. let args = Args::parse();
  36. let filename = args.input.as_str();
  37. let source = match read_to_string(filename) {
  38. Ok(v) => v,
  39. Err(e) => {
  40. eprintln!("Error: Failed reading from \"{}\". {}", filename, e);
  41. exit(1);
  42. }
  43. };
  44. let lexer = Lexer::new(filename, source.chars());
  45. let tokens = lexer.lex();
  46. let parser = Parser::new(filename, source.chars(), tokens);
  47. let (constants, witnesses, statements) = parser.parse();
  48. let mut analyzer = Analyzer::new(filename, source.chars(), constants, witnesses, statements);
  49. analyzer.analyze_types();
  50. if args.interactive {
  51. analyzer.analyze_semantic();
  52. }
  53. if args.evaluate {
  54. println!("{:#?}", analyzer.constants);
  55. println!("{:#?}", analyzer.witnesses);
  56. println!("{:#?}", analyzer.statements);
  57. println!("{:#?}", analyzer.stack);
  58. exit(0);
  59. }
  60. let compiler = Compiler::new(
  61. filename,
  62. source.chars(),
  63. analyzer.constants,
  64. analyzer.witnesses,
  65. analyzer.statements,
  66. !args.strip,
  67. );
  68. let bincode = compiler.compile();
  69. let output = match args.output {
  70. Some(o) => o,
  71. None => format!("{}.bin", args.input),
  72. };
  73. let mut file = match File::create(&output) {
  74. Ok(v) => v,
  75. Err(e) => {
  76. eprintln!("Error: Failed to create \"{}\". {}", output, e);
  77. exit(1);
  78. }
  79. };
  80. match file.write_all(&bincode) {
  81. Ok(_) => {}
  82. Err(e) => {
  83. eprintln!("Error: Failed to write bincode to \"{}\". {}", output, e);
  84. exit(1);
  85. }
  86. };
  87. println!("Wrote output to {}", &output);
  88. if args.examine {
  89. let zkbin = ZkBinary::decode(&bincode).unwrap();
  90. println!("{:#?}", zkbin);
  91. }
  92. }