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