From 7d604748bd431616fc16c39d0d0e8fadfe6144c4 Mon Sep 17 00:00:00 2001 From: collin <16715212+collinc97@users.noreply.github.com> Date: Wed, 13 Jul 2022 21:02:33 -0700 Subject: [PATCH] add token transfer example, fix record cast codegen --- compiler/ast/src/expressions/circuit_init.rs | 9 +---- compiler/parser/src/parser/expression.rs | 3 -- .../src/code_generation/visit_expressions.rs | 15 +++++++- examples/transfer/.gitignore | 2 ++ examples/transfer/README.md | 8 +++++ examples/transfer/inputs/transfer.in | 4 +++ examples/transfer/main.aleo | 21 +++++++++++ examples/transfer/program.json | 10 ++++++ examples/transfer/src/main.leo | 35 +++++++++++++++++++ 9 files changed, 95 insertions(+), 12 deletions(-) create mode 100644 examples/transfer/.gitignore create mode 100644 examples/transfer/README.md create mode 100644 examples/transfer/inputs/transfer.in create mode 100644 examples/transfer/main.aleo create mode 100644 examples/transfer/program.json create mode 100644 examples/transfer/src/main.leo diff --git a/compiler/ast/src/expressions/circuit_init.rs b/compiler/ast/src/expressions/circuit_init.rs index 1b3c7e8a3d..a1e59ab4b4 100644 --- a/compiler/ast/src/expressions/circuit_init.rs +++ b/compiler/ast/src/expressions/circuit_init.rs @@ -24,19 +24,12 @@ pub struct CircuitVariableInitializer { /// The expression to initialize the field with. /// When `None`, a binding, in scope, with the name will be used instead. pub expression: Option, - /// `true` if the circuit is a `record` type. - pub is_record: bool, } impl fmt::Display for CircuitVariableInitializer { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if let Some(expr) = &self.expression { - write!(f, "{}: {}", self.identifier, expr)?; - if self.is_record { - write!(f, "private") - } else { - write!(f, "") - } + write!(f, "{}: {}", self.identifier, expr) } else { write!(f, "{}", self.identifier) } diff --git a/compiler/parser/src/parser/expression.rs b/compiler/parser/src/parser/expression.rs index 6a7e51a889..e2c40ac898 100644 --- a/compiler/parser/src/parser/expression.rs +++ b/compiler/parser/src/parser/expression.rs @@ -467,12 +467,9 @@ impl ParserContext<'_> { None }; - let is_record = identifier.to_string().eq("Record"); - Ok(CircuitVariableInitializer { identifier, expression, - is_record, }) } diff --git a/compiler/passes/src/code_generation/visit_expressions.rs b/compiler/passes/src/code_generation/visit_expressions.rs index 95d3ae7674..62e4ce75fd 100644 --- a/compiler/passes/src/code_generation/visit_expressions.rs +++ b/compiler/passes/src/code_generation/visit_expressions.rs @@ -154,6 +154,13 @@ impl<'a> CodeGenerator<'a> { } fn visit_circuit_init(&mut self, input: &'a CircuitExpression) -> (String, String) { + // Lookup circuit or record. + let name = if let Some(type_) = self.composite_mapping.get(&input.name.name) { + format!("{}.{}", input.name.to_string().to_lowercase(), type_) + } else { + unreachable!("All composite types should be known at this phase of compilation") + }; + // Initialize instruction builder strings. let mut instructions = String::new(); let mut circuit_init_instruction = format!(" cast "); @@ -180,7 +187,13 @@ impl<'a> CodeGenerator<'a> { // Push destination register to circuit init instruction. let destination_register = format!("r{}", self.next_register); - writeln!(circuit_init_instruction, "into {} as {};", destination_register, input.name.to_string().to_lowercase()).expect("failed to write to string"); + writeln!( + circuit_init_instruction, + "into {dest} as {name};", + dest = destination_register, + name = name, + ).expect("failed to write to string"); + instructions.push_str(&circuit_init_instruction); // Increment the register counter. diff --git a/examples/transfer/.gitignore b/examples/transfer/.gitignore new file mode 100644 index 0000000000..b28696155d --- /dev/null +++ b/examples/transfer/.gitignore @@ -0,0 +1,2 @@ +outputs/ +build/ diff --git a/examples/transfer/README.md b/examples/transfer/README.md new file mode 100644 index 0000000000..b4da4a59a4 --- /dev/null +++ b/examples/transfer/README.md @@ -0,0 +1,8 @@ +# transfer.aleo + +## Build Guide + +To compile this Aleo program, run: +```bash +aleo build +``` diff --git a/examples/transfer/inputs/transfer.in b/examples/transfer/inputs/transfer.in new file mode 100644 index 0000000000..e7e9565b67 --- /dev/null +++ b/examples/transfer/inputs/transfer.in @@ -0,0 +1,4 @@ +// The program input for transfer/src/main.leo +[main] +owner: address = aleo12aw0kcnzyn5xj46z9u6mzpa67tzuqnvmwe0q2ejfjm8c2ue4pgys3877fr; +amount: u64 = 100u64; diff --git a/examples/transfer/main.aleo b/examples/transfer/main.aleo new file mode 100644 index 0000000000..5714ae58db --- /dev/null +++ b/examples/transfer/main.aleo @@ -0,0 +1,21 @@ +program transfer.aleo; +record token: + owner as address.private; + balance as u64.private; + amount as u64.private; + +function main: + input r0 as address.private; + input r1 as u64.private; + cast r0 0u64 r1 into r2 as token.record; + output r2 as token.record; + +function transfer: + input r0 as token.record; + input r1 as address.private; + input r2 as u64.private; + sub r0.amount r2 into r3; + cast r1 0u64 r2 into r4 as token.record; + cast r0.owner r0.balance r3 into r5 as token.record; + output r4 as token.record; + output r5 as token.record; diff --git a/examples/transfer/program.json b/examples/transfer/program.json new file mode 100644 index 0000000000..9b4dceb80c --- /dev/null +++ b/examples/transfer/program.json @@ -0,0 +1,10 @@ +{ + "program": "transfer.aleo", + "version": "0.0.0", + "description": "", + "development": { + "private_key": "APrivateKey1zkp3FxmbSYjkHsRBzZbCMGXY5u2sGCkgddNKVL7CDwy7KSe", + "address": "aleo12aw0kcnzyn5xj46z9u6mzpa67tzuqnvmwe0q2ejfjm8c2ue4pgys3877fr" + }, + "license": "MIT" +} diff --git a/examples/transfer/src/main.leo b/examples/transfer/src/main.leo new file mode 100644 index 0000000000..d9fd368051 --- /dev/null +++ b/examples/transfer/src/main.leo @@ -0,0 +1,35 @@ +record Token { + owner: address, + balance: u64, + amount: u64, +} + +function main(owner: address, amount: u64) -> Token { + return Token { + owner: owner, + balance: 0u64, + amount: amount, + }; +} + +function transfer( + t: Token, + r: address, + a: u64 +) -> (Token, Token) { + let change: u64 = t.amount - a; + + let t1: Token = Token { + owner: r, + balance: 0u64, + amount: a, + }; + + let t2: Token = Token { + owner: t.owner, + balance: t.balance, + amount: change + }; + + return (t1, t2); +} \ No newline at end of file