1use crate::{Bytecode, CompiledPrograms, Pass};
18
19use itertools::Itertools;
20use leo_ast::{Ast, Mode, ProgramId};
21use leo_errors::Result;
22
23use std::fmt::Display;
24
25mod expression;
26
27mod program;
28
29mod statement;
30
31mod type_;
32
33mod visitor;
34use snarkvm::{
35 prelude::{ArrayType, LiteralType, Network, PlaintextType},
36 synthesizer::program::{
37 CommitVariant,
38 DeserializeVariant,
39 ECDSAVerifyVariant,
40 HashVariant,
41 SerializeVariant,
42 SnarkVerifyVariant,
43 },
44};
45use visitor::*;
46
47#[derive(Default)]
49pub struct GeneratedPrograms {
50 pub primary: Option<AleoProgram>,
51 pub imports: Vec<(String, AleoProgram)>,
52}
53
54impl GeneratedPrograms {
55 pub fn into_compiled(self) -> CompiledPrograms {
57 let primary_bytecode = self.primary.map(|p| p.to_string()).unwrap_or_default();
58 let import_bytecodes = self
59 .imports
60 .into_iter()
61 .map(|(name, program)| Bytecode { program_name: name, bytecode: program.to_string() })
62 .collect();
63 CompiledPrograms { primary_bytecode, import_bytecodes }
64 }
65
66 pub fn for_each_statement_list(&mut self, mut f: impl FnMut(&mut Vec<AleoStmt>, usize)) {
68 for (_, program) in &mut self.imports {
69 program.for_each_statement_list(&mut f);
70 }
71 if let Some(primary) = &mut self.primary {
72 primary.for_each_statement_list(&mut f);
73 }
74 }
75}
76
77pub struct CodeGenerating;
78
79impl Pass for CodeGenerating {
80 type Input = ();
81 type Output = GeneratedPrograms;
82
83 const NAME: &str = "CodeGenerating";
84
85 fn do_pass(_input: Self::Input, state: &mut crate::CompilerState) -> Result<Self::Output> {
86 let mut visitor = CodeGeneratingVisitor {
87 state,
88 next_register: 0,
89 current_function: None,
90 variable_mapping: Default::default(),
91 composite_mapping: Default::default(),
92 global_mapping: Default::default(),
93 variant: None,
94 program: match &state.ast {
95 Ast::Program(p) => p,
96 Ast::Library(_) => {
97 return Ok(Default::default()); }
99 },
100 program_id: None,
101 finalize_caller: None,
102 next_label: 0,
103 conditional_depth: 0,
104 internal_record_inputs: Default::default(),
105 };
106
107 Ok(visitor.visit_package())
108 }
109}
110
111#[derive(Debug)]
112pub struct AleoProgram {
113 imports: Vec<String>,
114 program_id: ProgramId,
115 data_types: Vec<AleoDatatype>, mappings: Vec<AleoMapping>,
117 functions: Vec<AleoFunctional>,
118 constructor: Option<AleoConstructor>,
119}
120
121impl AleoProgram {
122 pub fn for_each_statement_list(&mut self, f: &mut impl FnMut(&mut Vec<AleoStmt>, usize)) {
125 for functional in &mut self.functions {
126 match functional {
127 AleoFunctional::Closure(c) => {
128 f(&mut c.statements, c.inputs.len());
129 }
130 AleoFunctional::Function(fun) => {
131 f(&mut fun.statements, fun.inputs.len());
132 if let Some(fin) = &mut fun.finalize {
133 f(&mut fin.statements, fin.inputs.len());
134 }
135 }
136 AleoFunctional::Finalize(fin) => {
137 f(&mut fin.statements, fin.inputs.len());
138 }
139 AleoFunctional::View(v) => {
140 f(&mut v.statements, v.inputs.len());
141 }
142 }
143 }
144 if let Some(constructor) = &mut self.constructor {
145 f(&mut constructor.statements, 0);
146 }
147 }
148}
149
150impl Display for AleoProgram {
151 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
152 self.imports
153 .iter()
154 .map(|program_name| format!("import {program_name};"))
155 .chain(std::iter::once(format!("program {};\n", self.program_id)))
156 .chain(self.data_types.iter().map(ToString::to_string))
157 .chain(self.mappings.iter().map(ToString::to_string))
158 .chain(self.functions.iter().map(ToString::to_string))
159 .chain(self.constructor.iter().map(ToString::to_string))
160 .join("\n")
161 .fmt(f)
162 }
163}
164
165#[derive(Debug)]
166pub enum AleoDatatype {
167 Struct(AleoStruct),
168 Record(AleoRecord),
169}
170
171impl Display for AleoDatatype {
172 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
173 match self {
174 Self::Struct(s) => s.fmt(f),
175 Self::Record(r) => r.fmt(f),
176 }
177 }
178}
179
180#[derive(Debug)]
181pub struct AleoStruct {
182 name: String,
183 fields: Vec<(String, AleoType)>,
184}
185impl Display for AleoStruct {
186 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
187 writeln!(f, "struct {}:", self.name)?;
188 for (id, ty) in self.fields.iter() {
189 writeln!(f, " {id} as {ty};")?;
190 }
191 Ok(())
192 }
193}
194
195#[derive(Debug)]
196pub struct AleoRecord {
197 name: String,
198 fields: Vec<(String, AleoType, AleoVisibility)>,
199}
200impl Display for AleoRecord {
201 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
202 writeln!(f, "record {}:", self.name)?;
203 for (id, ty, mode) in self.fields.iter() {
204 writeln!(f, " {id} as {ty}.{mode};")?;
205 }
206 Ok(())
207 }
208}
209
210#[derive(Clone, Debug, PartialEq)]
211pub enum AleoVisibility {
212 Constant,
213 Public,
214 Private,
215}
216impl AleoVisibility {
217 fn maybe_from(mode: Mode) -> Option<Self> {
218 match mode {
219 Mode::None => None,
220 Mode::Constant => Some(Self::Constant),
221 Mode::Private => Some(Self::Private),
222 Mode::Public => Some(Self::Public),
223 }
224 }
225}
226
227impl Display for AleoVisibility {
228 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
229 write!(f, "{}", match self {
230 Self::Constant => "constant",
231 Self::Public => "public",
232 Self::Private => "private",
233 })
234 }
235}
236
237#[derive(Debug)]
238pub struct AleoMapping {
239 name: String,
240 key_type: AleoType,
241 key_visibility: Option<AleoVisibility>,
242 value_type: AleoType,
243 value_visibility: Option<AleoVisibility>,
244}
245impl Display for AleoMapping {
246 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
247 writeln!(f, "mapping {}:", self.name)?;
248 if let Some(key_viz) = &self.key_visibility {
249 writeln!(f, " key as {}.{};", self.key_type, key_viz)?;
250 } else {
251 writeln!(f, " key as {};", self.key_type)?;
252 }
253 if let Some(value_viz) = &self.value_visibility {
254 writeln!(f, " value as {}.{};", self.value_type, value_viz)?;
255 } else {
256 writeln!(f, " value as {};", self.value_type)?;
257 }
258 Ok(())
259 }
260}
261
262#[derive(Debug)]
263pub struct AleoClosure {
264 name: String,
265 inputs: Vec<AleoInput>,
266 statements: Vec<AleoStmt>,
267}
268impl Display for AleoClosure {
269 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
270 writeln!(f, "closure {}:", self.name)?;
271 for input in &self.inputs {
272 write!(f, "{}", input)?;
273 }
274 for stm in &self.statements {
275 write!(f, "{}", stm)?;
276 }
277 Ok(())
278 }
279}
280
281#[derive(Debug)]
282pub enum AleoFunctional {
283 Closure(AleoClosure),
284 Function(AleoFunction),
285 Finalize(AleoFinalize),
286 View(AleoView),
287}
288impl AleoFunctional {
289 pub fn as_closure(self) -> AleoClosure {
290 if let Self::Closure(c) = self { c } else { panic!("this is not a closure") }
291 }
292
293 pub fn as_function(self) -> AleoFunction {
294 if let Self::Function(c) = self { c } else { panic!("this is not a function") }
295 }
296
297 pub fn as_function_ref_mut(&mut self) -> &mut AleoFunction {
298 if let Self::Function(c) = self { c } else { panic!("this is not a function") }
299 }
300
301 pub fn as_finalize(self) -> AleoFinalize {
302 if let Self::Finalize(c) = self { c } else { panic!("this is not a finalize") }
303 }
304}
305impl Display for AleoFunctional {
306 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
307 match self {
308 Self::Closure(c) => c.fmt(f),
309 Self::Function(fun) => fun.fmt(f),
310 Self::Finalize(fin) => fin.fmt(f),
311 Self::View(v) => v.fmt(f),
312 }
313 }
314}
315
316#[derive(Debug)]
326pub struct AleoView {
327 name: String,
328 inputs: Vec<AleoInput>,
329 statements: Vec<AleoStmt>,
330}
331impl Display for AleoView {
332 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
333 writeln!(f, "view {}:", self.name)?;
334 for input in &self.inputs {
335 write!(f, "{}", input)?;
336 }
337 for stm in &self.statements {
338 write!(f, "{}", stm)?;
339 }
340 Ok(())
341 }
342}
343
344#[derive(Debug)]
345pub struct AleoFunction {
346 name: String,
347 inputs: Vec<AleoInput>,
348 statements: Vec<AleoStmt>,
349 finalize: Option<AleoFinalize>,
350}
351impl Display for AleoFunction {
352 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
353 writeln!(f, "function {}:", self.name)?;
354 for input in &self.inputs {
355 write!(f, "{}", input)?;
356 }
357 for stm in &self.statements {
358 write!(f, "{}", stm)?;
359 }
360 if let Some(finalize) = &self.finalize {
361 write!(f, "\n{}", finalize)?;
362 }
363 Ok(())
364 }
365}
366
367#[derive(Debug)]
368pub struct AleoFinalize {
369 caller_name: String,
370 inputs: Vec<AleoInput>,
371 statements: Vec<AleoStmt>,
372}
373impl Display for AleoFinalize {
374 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
375 writeln!(f, "finalize {}:", self.caller_name)?;
376 for input in &self.inputs {
377 write!(f, "{}", input)?;
378 }
379 for stm in &self.statements {
380 write!(f, "{}", stm)?;
381 }
382 Ok(())
383 }
384}
385
386#[derive(Debug)]
387pub struct AleoInput {
388 register: AleoReg,
389 type_: AleoType,
390 visibility: Option<AleoVisibility>,
391}
392impl Display for AleoInput {
393 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
394 if let Some(visibility) = &self.visibility {
395 writeln!(f, " input {} as {}.{};", self.register, self.type_, visibility)
396 } else {
397 writeln!(f, " input {} as {};", self.register, self.type_)
398 }
399 }
400}
401
402#[derive(Debug)]
403pub struct AleoConstructor {
404 statements: Vec<AleoStmt>,
405}
406impl Display for AleoConstructor {
407 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
408 writeln!(f, "constructor:")?;
409 for stm in &self.statements {
410 write!(f, "{}", stm)?;
411 }
412 Ok(())
413 }
414}
415
416#[derive(Hash, Eq, PartialEq, Clone, Debug)]
417pub enum AleoExpr {
418 Reg(AleoReg),
419 Tuple(Vec<AleoExpr>),
420 ArrayAccess(Box<AleoExpr>, Box<AleoExpr>),
421 MemberAccess(Box<AleoExpr>, String),
422 RawName(String),
423 Address(String),
425 Identifier(String),
426 Bool(bool),
427 Field(String),
428 Group(String),
429 Signature(String),
430 Scalar(String),
431 String(String),
432 U8(u8),
433 U16(u16),
434 U32(u32),
435 U64(u64),
436 U128(u128),
437 I8(i8),
438 I16(i16),
439 I32(i32),
440 I64(i64),
441 I128(i128),
442}
443impl Display for AleoExpr {
444 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
445 match self {
446 Self::Reg(reg) => write!(f, "{reg}"),
447 Self::Tuple(regs) => write!(f, "{}", regs.iter().map(|reg| reg.to_string()).join(" ")),
448 Self::ArrayAccess(array, index) => write!(f, "{array}[{index}]"),
449 Self::MemberAccess(comp, member) => write!(f, "{comp}.{member}"),
450 Self::RawName(n) => write!(f, "{n}"),
451 Self::Identifier(val) => write!(f, "'{val}'"),
453 Self::Address(val) => write!(f, "{val}"),
454 Self::Bool(val) => write!(f, "{val}"),
455 Self::Field(val) => write!(f, "{val}field"),
456 Self::Group(val) => write!(f, "{val}group"),
457 Self::U8(val) => write!(f, "{val}u8"),
458 Self::U16(val) => write!(f, "{val}u16"),
459 Self::U32(val) => write!(f, "{val}u32"),
460 Self::U64(val) => write!(f, "{val}u64"),
461 Self::U128(val) => write!(f, "{val}u128"),
462 Self::I8(val) => write!(f, "{val}i8"),
463 Self::I16(val) => write!(f, "{val}i16"),
464 Self::I32(val) => write!(f, "{val}i32"),
465 Self::I64(val) => write!(f, "{val}i64"),
466 Self::I128(val) => write!(f, "{val}i128"),
467 Self::Scalar(val) => write!(f, "{val}scalar"),
468 Self::Signature(val) => write!(f, "{val}"),
469 Self::String(val) => write!(f, "\"{val}\""),
470 }
471 }
472}
473
474#[derive(Clone, Debug, PartialEq)]
475pub enum AleoStmt {
476 Output(AleoExpr, AleoType, Option<AleoVisibility>),
477 AssertEq(AleoExpr, AleoExpr),
478 AssertNeq(AleoExpr, AleoExpr),
479 Cast(AleoExpr, AleoReg, AleoType),
480 Abs(AleoExpr, AleoReg),
481 AbsW(AleoExpr, AleoReg),
482 Double(AleoExpr, AleoReg),
483 Inv(AleoExpr, AleoReg),
484 Not(AleoExpr, AleoReg),
485 Neg(AleoExpr, AleoReg),
486 Square(AleoExpr, AleoReg),
487 Sqrt(AleoExpr, AleoReg),
488 Ternary(AleoExpr, AleoExpr, AleoExpr, AleoReg),
489 Commit(CommitVariant, AleoExpr, AleoExpr, AleoReg, AleoType),
490 Hash(HashVariant, AleoExpr, AleoReg, AleoType),
491 Get(AleoExpr, AleoExpr, AleoReg),
492 GetOrUse(AleoExpr, AleoExpr, AleoExpr, AleoReg),
493 Set(AleoExpr, AleoExpr, AleoExpr),
494 Remove(AleoExpr, AleoExpr),
495 Contains(AleoExpr, AleoExpr, AleoReg),
496 RandChacha(AleoReg, AleoType),
497 SignVerify(AleoExpr, AleoExpr, AleoExpr, AleoReg),
498 EcdsaVerify(ECDSAVerifyVariant, AleoExpr, AleoExpr, AleoExpr, AleoReg),
499 SnarkVerify(SnarkVerifyVariant, AleoExpr, AleoExpr, AleoExpr, AleoExpr, AleoReg),
500 Await(AleoExpr),
501 Serialize(SerializeVariant, AleoExpr, AleoType, AleoReg, AleoType),
502 Deserialize(DeserializeVariant, AleoExpr, AleoType, AleoReg, AleoType),
503 Call(String, Vec<AleoExpr>, Vec<AleoReg>),
504 CallDynamic(
505 AleoExpr,
506 AleoExpr,
507 AleoExpr,
508 Vec<AleoExpr>,
509 Vec<(AleoType, Option<AleoVisibility>)>,
510 Vec<AleoReg>,
511 Vec<(AleoType, Option<AleoVisibility>)>,
512 ),
513 GetRecordDynamic(AleoExpr, String, AleoReg, AleoType),
514 ContainsDynamic(AleoExpr, AleoExpr, AleoExpr, AleoExpr, AleoReg),
516 GetDynamic(AleoExpr, AleoExpr, AleoExpr, AleoExpr, AleoReg, AleoType),
518 GetOrUseDynamic(AleoExpr, AleoExpr, AleoExpr, AleoExpr, AleoExpr, AleoReg, AleoType),
520 Async(String, Vec<AleoExpr>, Vec<AleoReg>),
521 BranchEq(AleoExpr, AleoExpr, String),
522 Position(String),
523 Add(AleoExpr, AleoExpr, AleoReg),
524 AddWrapped(AleoExpr, AleoExpr, AleoReg),
525 And(AleoExpr, AleoExpr, AleoReg),
526 Div(AleoExpr, AleoExpr, AleoReg),
527 DivWrapped(AleoExpr, AleoExpr, AleoReg),
528 Eq(AleoExpr, AleoExpr, AleoReg),
529 Gte(AleoExpr, AleoExpr, AleoReg),
530 Gt(AleoExpr, AleoExpr, AleoReg),
531 Lte(AleoExpr, AleoExpr, AleoReg),
532 Lt(AleoExpr, AleoExpr, AleoReg),
533 Mod(AleoExpr, AleoExpr, AleoReg),
534 Mul(AleoExpr, AleoExpr, AleoReg),
535 MulWrapped(AleoExpr, AleoExpr, AleoReg),
536 Nand(AleoExpr, AleoExpr, AleoReg),
537 Neq(AleoExpr, AleoExpr, AleoReg),
538 Nor(AleoExpr, AleoExpr, AleoReg),
539 Or(AleoExpr, AleoExpr, AleoReg),
540 Pow(AleoExpr, AleoExpr, AleoReg),
541 PowWrapped(AleoExpr, AleoExpr, AleoReg),
542 Rem(AleoExpr, AleoExpr, AleoReg),
543 RemWrapped(AleoExpr, AleoExpr, AleoReg),
544 Shl(AleoExpr, AleoExpr, AleoReg),
545 ShlWrapped(AleoExpr, AleoExpr, AleoReg),
546 Shr(AleoExpr, AleoExpr, AleoReg),
547 ShrWrapped(AleoExpr, AleoExpr, AleoReg),
548 Sub(AleoExpr, AleoExpr, AleoReg),
549 SubWrapped(AleoExpr, AleoExpr, AleoReg),
550 Xor(AleoExpr, AleoExpr, AleoReg),
551}
552impl Display for AleoStmt {
553 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
554 match self {
555 Self::Output(arg, type_, viz) => {
556 if let Some(viz) = &viz {
557 writeln!(f, " output {} as {}.{};", arg, type_, viz)
558 } else {
559 writeln!(f, " output {} as {};", arg, type_)
560 }
561 }
562 Self::AssertEq(left, right) => writeln!(f, " assert.eq {left} {right};"),
563 Self::AssertNeq(left, right) => writeln!(f, " assert.neq {left} {right};"),
564 Self::Cast(operands, dest, type_) => {
565 writeln!(f, " cast {operands} into {dest} as {type_};")
566 }
567 Self::GetRecordDynamic(src, field, dest, type_) => {
568 writeln!(f, " get.record.dynamic {src}.{field} into {dest} as {type_};")
569 }
570 Self::Abs(op, dest) => writeln!(f, " abs {op} into {dest};"),
571 Self::AbsW(op, dest) => writeln!(f, " abs.w {op} into {dest};"),
572 Self::Double(op, dest) => writeln!(f, " double {op} into {dest};"),
573 Self::Inv(op, dest) => writeln!(f, " inv {op} into {dest};"),
574 Self::Not(op, dest) => writeln!(f, " not {op} into {dest};"),
575 Self::Neg(op, dest) => writeln!(f, " neg {op} into {dest};"),
576 Self::Square(op, dest) => writeln!(f, " square {op} into {dest};"),
577 Self::Sqrt(op, dest) => writeln!(f, " sqrt {op} into {dest};"),
578 Self::Ternary(cond, if_true, if_false, dest) => {
579 writeln!(f, " ternary {cond} {if_true} {if_false} into {dest};")
580 }
581 Self::Commit(variant, arg0, arg1, dest, type_) => {
582 writeln!(f, " {} {arg0} {arg1} into {dest} as {type_};", CommitVariant::opcode(*variant as u8))
583 }
584 Self::Hash(variant, arg0, dest, type_) => {
585 writeln!(f, " {} {arg0} into {dest} as {type_};", variant.opcode())
586 }
587 Self::Get(mapping, key, dest) => writeln!(f, " get {mapping}[{key}] into {dest};"),
588 Self::GetOrUse(mapping, key, default, dest) => {
589 writeln!(f, " get.or_use {mapping}[{key}] {default} into {dest};")
590 }
591 Self::Set(value, mapping, key) => writeln!(f, " set {value} into {mapping}[{key}];"),
592 Self::Remove(mapping, key) => writeln!(f, " remove {mapping}[{key}];"),
593 Self::Contains(mapping, key, dest) => writeln!(f, " contains {mapping}[{key}] into {dest};"),
594 Self::RandChacha(dest, type_) => writeln!(f, " rand.chacha into {dest} as {type_};"),
595 Self::SignVerify(arg0, arg1, arg2, dest) => {
596 writeln!(f, " sign.verify {arg0} {arg1} {arg2} into {dest};")
597 }
598 Self::EcdsaVerify(variant, arg0, arg1, arg2, dest) => {
599 writeln!(f, " {} {arg0} {arg1} {arg2} into {dest};", variant.opcode())
600 }
601 Self::SnarkVerify(variant, arg0, arg1, arg2, arg3, dest) => {
602 writeln!(f, " {} {arg0} {arg1} {arg2} {arg3} into {dest};", variant.opcode())
603 }
604 Self::Await(exp) => writeln!(f, " await {exp};"),
605 Self::Serialize(variant, input, input_ty, dest, dest_ty) => {
606 writeln!(
607 f,
608 " {} {input} ({input_ty}) into {dest} ({dest_ty});",
609 SerializeVariant::opcode(variant.clone() as u8),
610 )
611 }
612 Self::Deserialize(variant, input, input_ty, dest, dest_ty) => {
613 writeln!(
614 f,
615 " {} {input} ({input_ty}) into {dest} ({dest_ty});",
616 DeserializeVariant::opcode(variant.clone() as u8),
617 )
618 }
619 Self::Call(id, inputs, dests) => {
620 write!(f, " call {id}")?;
621 if !inputs.is_empty() {
622 write!(f, " {}", inputs.iter().map(|input| input.to_string()).join(" "))?;
623 }
624 if !dests.is_empty() {
625 write!(f, " into {}", dests.iter().map(|input| input.to_string()).join(" "))?;
626 }
627 writeln!(f, ";")
628 }
629 Self::CallDynamic(prog, net, fun, inputs, input_types, outputs, output_types) => {
630 write!(f, " call.dynamic {prog} {net} {fun}")?;
631 if !inputs.is_empty() {
632 write!(f, " with {}", inputs.iter().map(|i| i.to_string()).join(" "))?;
633 }
634 if !input_types.is_empty() {
635 write!(
636 f,
637 " (as {})",
638 input_types
639 .iter()
640 .map(|(ty, viz)| { if let Some(v) = viz { format!("{ty}.{v}") } else { format!("{ty}") } })
641 .join(" ")
642 )?;
643 }
644 if !outputs.is_empty() {
645 write!(f, " into {}", outputs.iter().map(|o| o.to_string()).join(" "))?;
646 }
647 if !output_types.is_empty() {
648 write!(
649 f,
650 " (as {})",
651 output_types
652 .iter()
653 .map(|(ty, viz)| { if let Some(v) = viz { format!("{ty}.{v}") } else { format!("{ty}") } })
654 .join(" ")
655 )?;
656 }
657 writeln!(f, ";")
658 }
659 Self::ContainsDynamic(prog, net, mapping, key, dest) => {
660 writeln!(f, " contains.dynamic {prog} {net} {mapping}[{key}] into {dest};")
661 }
662 Self::GetDynamic(prog, net, mapping, key, dest, ty) => {
663 writeln!(f, " get.dynamic {prog} {net} {mapping}[{key}] into {dest} as {ty};")
664 }
665 Self::GetOrUseDynamic(prog, net, mapping, key, default, dest, ty) => {
666 writeln!(f, " get.or_use.dynamic {prog} {net} {mapping}[{key}] {default} into {dest} as {ty};")
667 }
668 Self::Async(id, inputs, dests) => {
669 write!(f, " async {id}")?;
670 if !inputs.is_empty() {
671 write!(f, " {}", inputs.iter().map(|input| input.to_string()).join(" "))?;
672 }
673 if !dests.is_empty() {
674 write!(f, " into {}", dests.iter().map(|input| input.to_string()).join(" "))?;
675 }
676 writeln!(f, ";")
677 }
678 Self::BranchEq(arg0, arg1, label) => {
679 writeln!(f, " branch.eq {arg0} {arg1} to {label};")
680 }
681 Self::Position(label) => writeln!(f, " position {label};"),
682 Self::Add(arg0, arg1, dest) => writeln!(f, " add {arg0} {arg1} into {dest};"),
683 Self::AddWrapped(arg0, arg1, dest) => writeln!(f, " add.w {arg0} {arg1} into {dest};"),
684 Self::And(arg0, arg1, dest) => writeln!(f, " and {arg0} {arg1} into {dest};"),
685 Self::Div(arg0, arg1, dest) => writeln!(f, " div {arg0} {arg1} into {dest};"),
686 Self::DivWrapped(arg0, arg1, dest) => writeln!(f, " div.w {arg0} {arg1} into {dest};"),
687 Self::Eq(arg0, arg1, dest) => writeln!(f, " is.eq {arg0} {arg1} into {dest};"),
688 Self::Gte(arg0, arg1, dest) => writeln!(f, " gte {arg0} {arg1} into {dest};"),
689 Self::Gt(arg0, arg1, dest) => writeln!(f, " gt {arg0} {arg1} into {dest};"),
690 Self::Lte(arg0, arg1, dest) => writeln!(f, " lte {arg0} {arg1} into {dest};"),
691 Self::Lt(arg0, arg1, dest) => writeln!(f, " lt {arg0} {arg1} into {dest};"),
692 Self::Mod(arg0, arg1, dest) => writeln!(f, " mod {arg0} {arg1} into {dest};"),
693 Self::Mul(arg0, arg1, dest) => writeln!(f, " mul {arg0} {arg1} into {dest};"),
694 Self::MulWrapped(arg0, arg1, dest) => writeln!(f, " mul.w {arg0} {arg1} into {dest};"),
695 Self::Nand(arg0, arg1, dest) => writeln!(f, " nand {arg0} {arg1} into {dest};"),
696 Self::Neq(arg0, arg1, dest) => writeln!(f, " is.neq {arg0} {arg1} into {dest};"),
697 Self::Nor(arg0, arg1, dest) => writeln!(f, " nor {arg0} {arg1} into {dest};"),
698 Self::Or(arg0, arg1, dest) => writeln!(f, " or {arg0} {arg1} into {dest};"),
699 Self::Pow(arg0, arg1, dest) => writeln!(f, " pow {arg0} {arg1} into {dest};"),
700 Self::PowWrapped(arg0, arg1, dest) => writeln!(f, " pow.w {arg0} {arg1} into {dest};"),
701 Self::Rem(arg0, arg1, dest) => writeln!(f, " rem {arg0} {arg1} into {dest};"),
702 Self::RemWrapped(arg0, arg1, dest) => writeln!(f, " rem.w {arg0} {arg1} into {dest};"),
703 Self::Shl(arg0, arg1, dest) => writeln!(f, " shl {arg0} {arg1} into {dest};"),
704 Self::ShlWrapped(arg0, arg1, dest) => writeln!(f, " shl.w {arg0} {arg1} into {dest};"),
705 Self::Shr(arg0, arg1, dest) => writeln!(f, " shr {arg0} {arg1} into {dest};"),
706 Self::ShrWrapped(arg0, arg1, dest) => writeln!(f, " shr.w {arg0} {arg1} into {dest};"),
707 Self::Sub(arg0, arg1, dest) => writeln!(f, " sub {arg0} {arg1} into {dest};"),
708 Self::SubWrapped(arg0, arg1, dest) => writeln!(f, " sub.w {arg0} {arg1} into {dest};"),
709 Self::Xor(arg0, arg1, dest) => writeln!(f, " xor {arg0} {arg1} into {dest};"),
710 }
711 }
712}
713
714#[derive(Clone, Debug, PartialEq)]
715pub enum AleoType {
716 Future { name: String, program: String },
717 Record { name: String, program: Option<String> },
718 Ident { name: String },
719 Location { program: String, name: String },
720 Array { inner: Box<AleoType>, len: u32 },
721 GroupX,
722 GroupY,
723 Address,
724 Identifier,
725 DynamicRecord,
726 DynamicFuture,
727 Boolean,
728 Field,
729 Group,
730 I8,
731 I16,
732 I32,
733 I64,
734 I128,
735 U8,
736 U16,
737 U32,
738 U64,
739 U128,
740 Scalar,
741 Signature,
742 String,
743}
744impl Display for AleoType {
745 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
746 match self {
747 Self::Future { name, program } => write!(f, "{program}/{name}.future"),
748 Self::Record { name, program: Some(program_name) } => write!(f, "{program_name}/{name}.record"),
749 Self::Record { name, program: None } => write!(f, "{name}.record"),
750 Self::GroupX => write!(f, "group.x"),
751 Self::GroupY => write!(f, "group.y"),
752 Self::Ident { name } => write!(f, "{name}"),
753 Self::Location { program, name } => write!(f, "{program}/{name}"),
754 Self::Identifier => write!(f, "identifier"),
755 Self::DynamicRecord => write!(f, "dynamic.record"),
756 Self::DynamicFuture => write!(f, "dynamic.future"),
757 Self::Address => write!(f, "address"),
758 Self::Boolean => write!(f, "boolean"),
759 Self::Field => write!(f, "field"),
760 Self::Group => write!(f, "group"),
761 Self::I8 => write!(f, "i8"),
762 Self::I16 => write!(f, "i16"),
763 Self::I32 => write!(f, "i32"),
764 Self::I64 => write!(f, "i64"),
765 Self::I128 => write!(f, "i128"),
766 Self::U8 => write!(f, "u8"),
767 Self::U16 => write!(f, "u16"),
768 Self::U32 => write!(f, "u32"),
769 Self::U64 => write!(f, "u64"),
770 Self::U128 => write!(f, "u128"),
771 Self::Scalar => write!(f, "scalar"),
772 Self::Signature => write!(f, "signature"),
773 Self::String => write!(f, "string"),
774 Self::Array { inner, len } => write!(f, "[{inner}; {len}u32]"),
775 }
776 }
777}
778impl<N: Network> From<PlaintextType<N>> for AleoType {
779 fn from(value: PlaintextType<N>) -> Self {
780 match value {
781 PlaintextType::Literal(lit) => lit.into(),
782 PlaintextType::Struct(id) => Self::Ident { name: id.to_string() },
783 PlaintextType::ExternalStruct(loc) => {
784 Self::Location { program: loc.program_id().to_string(), name: loc.name().to_string() }
785 }
786 PlaintextType::Array(arr) => arr.into(),
787 }
788 }
789}
790impl From<LiteralType> for AleoType {
791 fn from(value: LiteralType) -> Self {
792 match value {
793 LiteralType::Identifier => Self::Identifier,
794 LiteralType::Address => Self::Address,
795 LiteralType::Boolean => Self::Boolean,
796 LiteralType::Field => Self::Field,
797 LiteralType::Group => Self::Group,
798 LiteralType::I8 => Self::I8,
799 LiteralType::I16 => Self::I16,
800 LiteralType::I32 => Self::I32,
801 LiteralType::I64 => Self::I64,
802 LiteralType::I128 => Self::I128,
803 LiteralType::U8 => Self::U8,
804 LiteralType::U16 => Self::U16,
805 LiteralType::U32 => Self::U32,
806 LiteralType::U64 => Self::U64,
807 LiteralType::U128 => Self::U128,
808 LiteralType::Scalar => Self::Scalar,
809 LiteralType::Signature => Self::Signature,
810 LiteralType::String => Self::String,
811 }
812 }
813}
814impl<N: Network> From<ArrayType<N>> for AleoType {
815 fn from(value: ArrayType<N>) -> Self {
816 Self::Array { len: **value.length(), inner: Box::new(AleoType::from(value.next_element_type().clone())) }
817 }
818}
819
820#[derive(Hash, Eq, PartialEq, Clone, Debug)]
821pub enum AleoReg {
822 Self_,
823 Block,
824 Network,
825 R(u64),
826}
827impl Display for AleoReg {
828 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
829 match self {
830 Self::Self_ => write!(f, "self"),
831 Self::Block => write!(f, "block"),
832 Self::Network => write!(f, "network"),
833 Self::R(n) => write!(f, "r{n}"),
834 }
835 }
836}