Fix unit expression

This commit is contained in:
d0cd 2022-10-13 13:51:44 -05:00
parent 34fa2cb2c6
commit 678f8b02a1
16 changed files with 66 additions and 19 deletions

View File

@ -61,9 +61,7 @@ pub trait ExpressionConsumer {
fn consume_unary(&mut self, _input: UnaryExpression) -> Self::Output; fn consume_unary(&mut self, _input: UnaryExpression) -> Self::Output;
fn consume_unit(&mut self, _input: UnitExpression) -> Self::Output { fn consume_unit(&mut self, _input: UnitExpression) -> Self::Output;
unreachable!("`UnitExpression`s should not be in the AST at this phase of compilation.")
}
} }
/// A Consumer trait for statements in the AST. /// A Consumer trait for statements in the AST.

View File

@ -117,12 +117,10 @@ impl ParserContext<'_> {
fn parse_return_statement(&mut self) -> Result<ReturnStatement> { fn parse_return_statement(&mut self) -> Result<ReturnStatement> {
let start = self.expect(&Token::Return)?; let start = self.expect(&Token::Return)?;
let expression = match self.token.token { let expression = match self.token.token {
Token::Semicolon => { Token::Semicolon => Expression::Unit(UnitExpression { span: self.token.span }),
let span = self.expect(&Token::Semicolon)?;
Expression::Unit(UnitExpression { span })
}
_ => self.parse_expression()?, _ => self.parse_expression()?,
}; };
self.expect(&Token::Semicolon)?;
let span = start + expression.span(); let span = start + expression.span();
Ok(ReturnStatement { span, expression }) Ok(ReturnStatement { span, expression })
} }

View File

@ -44,7 +44,7 @@ impl<'a> CodeGenerator<'a> {
fn visit_return(&mut self, input: &'a ReturnStatement) -> String { fn visit_return(&mut self, input: &'a ReturnStatement) -> String {
match input.expression { match input.expression {
// Skip empty return statements. // Skip empty return statements.
Expression::Tuple(ref tuple) if tuple.elements.is_empty() => String::new(), Expression::Unit(_) => String::new(),
_ => { _ => {
let (operand, mut expression_instructions) = self.visit_expression(&input.expression); let (operand, mut expression_instructions) = self.visit_expression(&input.expression);
// Get the output type of the function. // Get the output type of the function.

View File

@ -19,7 +19,7 @@ use crate::StaticSingleAssigner;
use leo_ast::{ use leo_ast::{
AccessExpression, AssociatedFunction, BinaryExpression, CallExpression, Expression, ExpressionConsumer, Identifier, AccessExpression, AssociatedFunction, BinaryExpression, CallExpression, Expression, ExpressionConsumer, Identifier,
Literal, MemberAccess, Statement, Struct, StructExpression, StructVariableInitializer, TernaryExpression, Literal, MemberAccess, Statement, Struct, StructExpression, StructVariableInitializer, TernaryExpression,
TupleAccess, TupleExpression, UnaryExpression, TupleAccess, TupleExpression, UnaryExpression, UnitExpression,
}; };
use leo_span::{sym, Symbol}; use leo_span::{sym, Symbol};
@ -322,4 +322,8 @@ impl ExpressionConsumer for StaticSingleAssigner<'_> {
(Expression::Identifier(place), statements) (Expression::Identifier(place), statements)
} }
fn consume_unit(&mut self, input: UnitExpression) -> Self::Output {
(Expression::Unit(input), Default::default())
}
} }

View File

@ -627,10 +627,7 @@ impl<'a> ExpressionVisitor<'a> for TypeChecker<'a> {
fn visit_tuple(&mut self, input: &'a TupleExpression, expected: &Self::AdditionalInput) -> Self::Output { fn visit_tuple(&mut self, input: &'a TupleExpression, expected: &Self::AdditionalInput) -> Self::Output {
match input.elements.len() { match input.elements.len() {
0 => { 0 => unreachable!("Tuple expressions must have at least one element."),
self.emit_err(TypeCheckerError::unit_tuple(input.span()));
None
}
1 => { 1 => {
self.emit_err(TypeCheckerError::singleton_tuple(input.span())); self.emit_err(TypeCheckerError::singleton_tuple(input.span()));
None None

View File

@ -1,6 +1,6 @@
/* /*
namespace: Compile namespace: Compile
expectation: Fail expectation: Pass
input_file: input_file:
- inputs/bool_bool.in - inputs/bool_bool.in
*/ */

View File

@ -2,4 +2,4 @@
namespace: Compile namespace: Compile
expectation: Fail expectation: Fail
outputs: outputs:
- "Error [ETYC0372054]: Empty tuple expressions and tuple types are not allowed.\n --> compiler-test:7:9\n |\n 7 | let b: () = ();\n | ^^^^^^^^^^^^^^\nError [ETYC0372054]: Empty tuple expressions and tuple types are not allowed.\n --> compiler-test:7:21\n |\n 7 | let b: () = ();\n | ^^\nError [ETYC0372054]: Empty tuple expressions and tuple types are not allowed.\n --> compiler-test:12:9\n |\n 12 | let b: () = bar();\n | ^^^^^^^^^^^^^^^^^\nError [ETYC0372048]: Cannot call a local transition function from a transition function.\n --> compiler-test:12:21\n |\n 12 | let b: () = bar();\n | ^^^^^\nError [ETYC0372006]: Call expected `1` args, but got `0`\n --> compiler-test:12:21\n |\n 12 | let b: () = bar();\n | ^^^^^\n" - "Error [ETYC0372054]: Empty tuple expressions and tuple types are not allowed.\n --> compiler-test:6:9\n |\n 6 | let b: () = ();\n | ^^^^^^^^^^^^^^\nError [ETYC0372054]: Empty tuple expressions and tuple types are not allowed.\n --> compiler-test:11:9\n |\n 11 | let b: () = bar();\n | ^^^^^^^^^^^^^^^^^\nError [ETYC0372048]: Cannot call a local transition function from a transition function.\n --> compiler-test:11:21\n |\n 11 | let b: () = bar();\n | ^^^^^\nError [ETYC0372006]: Call expected `1` args, but got `0`\n --> compiler-test:11:21\n |\n 11 | let b: () = bar();\n | ^^^^^\n"

View File

@ -0,0 +1,10 @@
---
namespace: Compile
expectation: Pass
outputs:
- output:
- initial_input_ast: 1a81fc79fbd61a51db3d300d5eb64e9108b60f0c83abecf946ab6a43aa05abee
initial_ast: 2b8b08ac0834c20e30e5aac2d39f2a1d60aef024587b62209708638986053de1
unrolled_ast: 2b8b08ac0834c20e30e5aac2d39f2a1d60aef024587b62209708638986053de1
ssa_ast: 2b8b08ac0834c20e30e5aac2d39f2a1d60aef024587b62209708638986053de1
flattened_ast: eaed8b8a1a24eb23ec384fbd27c885db1c2437a398c304bd2f9b6ed9de2e9fa5

View File

@ -1,5 +1,10 @@
--- ---
namespace: Compile namespace: Compile
expectation: Fail expectation: Pass
outputs: outputs:
- "Error [ETYC0372054]: Empty tuple expressions and tuple types are not allowed.\n --> compiler-test:5:16\n |\n 5 | return ();\n | ^^\n" - output:
- initial_input_ast: ba75ac7ea183c8a86596b63c2dcc42bdc2d7a02cfa8f1d2e16f3c2c33bfe4f2e
initial_ast: 2b8b08ac0834c20e30e5aac2d39f2a1d60aef024587b62209708638986053de1
unrolled_ast: 2b8b08ac0834c20e30e5aac2d39f2a1d60aef024587b62209708638986053de1
ssa_ast: 2b8b08ac0834c20e30e5aac2d39f2a1d60aef024587b62209708638986053de1
flattened_ast: eaed8b8a1a24eb23ec384fbd27c885db1c2437a398c304bd2f9b6ed9de2e9fa5

View File

@ -2,4 +2,9 @@
namespace: Compile namespace: Compile
expectation: Pass expectation: Pass
outputs: outputs:
- "Error [ETYC0372058]: A function cannot take in tuples as input.\n --> compiler-test:5:20\n |\n 5 | transition baz(a: (u8, u8)) -> u8 {\n | ^\n" - output:
- initial_input_ast: no input
initial_ast: a81aefbb2dc5b4c4bf25415c244be3c753794f27878087e513caf99a62eb2b6e
unrolled_ast: a81aefbb2dc5b4c4bf25415c244be3c753794f27878087e513caf99a62eb2b6e
ssa_ast: 3ef50f2cfca9dd0d0af10810aa4f7767f3adf8fd4c3f54f6d1c503901510a6b7
flattened_ast: 50f5304628172ecd7e6d19c53f4fc57a4df3f4e76df18152804f34f42ac81e7d

View File

@ -0,0 +1,10 @@
---
namespace: Compile
expectation: Pass
outputs:
- output:
- initial_input_ast: no input
initial_ast: dd0977ae1402bb8fa7c3531c42389adc291dd730f3aacdd567dbdbef321e958a
unrolled_ast: dd0977ae1402bb8fa7c3531c42389adc291dd730f3aacdd567dbdbef321e958a
ssa_ast: f13ee06db150eecf24ef65504fb8b36f055a962c328b1c1fbb7bd15edc6050bd
flattened_ast: 7152760b06956005659ff36441463b342a22cc27ece042f8be4c60b82e933de0

View File

@ -2,4 +2,4 @@
namespace: Compile namespace: Compile
expectation: Fail expectation: Fail
outputs: outputs:
- "Error [ETYC0372058]: A function cannot take in tuples as input.\n --> compiler-test:4:20\n |\n 4 | transition foo(a: (u8, u16)) -> (u8, u16) {\n | ^\nError [ETYC0372058]: A function cannot take in tuples as input.\n --> compiler-test:10:20\n |\n 10 | transition bar(a: (u8, (u8, u8))) -> (u8, (u8, u8)) {\n | ^\nError [ETYC0372055]: A tuple type cannot contain a tuple.\n --> compiler-test:10:47\n |\n 10 | transition bar(a: (u8, (u8, u8))) -> (u8, (u8, u8)) {\n | ^^^^^^^^\n" - "Error [ETYC0372058]: A function cannot take in tuples as input.\n --> compiler-test:4:20\n |\n 4 | transition foo(a: (u8, u16)) -> (u8, u16) {\n | ^\n"

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372057]: A record cannot contain a tuple.\n --> compiler-test:7:9\n |\n 7 | amounts: (u64, u64),\n | ^^^^^^^\n"

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372055]: A tuple type cannot contain a tuple.\n --> compiler-test:4:35\n |\n 4 | transition bar(a: u8) -> (u8, (u8, u8)) {\n | ^^^^^^^^\nError [ETYC0372060]: A tuple expression cannot contain another tuple expression.\n --> compiler-test:5:20\n |\n 5 | return (a, (a + a, a * a));\n | ^^^^^^^^^^^^^^\nError [ETYC0372060]: A tuple expression cannot contain another tuple expression.\n --> compiler-test:5:20\n |\n 5 | return (a, (a + a, a * a));\n | ^^^^^^^^^^^^^^\n"

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372056]: A struct cannot contain a tuple.\n --> compiler-test:5:9\n |\n 5 | mem: (u8, u16)\n | ^^^\nError [ETYC0372056]: A struct cannot contain a tuple.\n --> compiler-test:9:9\n |\n 9 | mems: (A, A)\n | ^^^^\n"

View File

@ -0,0 +1,5 @@
---
namespace: Compile
expectation: Fail
outputs:
- "Error [ETYC0372056]: A struct cannot contain a tuple.\n --> compiler-test:22:9\n |\n 22 | mem: (u8, u16)\n | ^^^\nError [ETYC0372058]: A function cannot take in tuples as input.\n --> compiler-test:8:18\n |\n 8 | function foo(a: (u8, u16)) -> (u8, u16) {\n | ^\nError [ETYC0372055]: A tuple type cannot contain a tuple.\n --> compiler-test:12:28\n |\n 12 | function bar() -> (u8, (u16, u32)) {\n | ^^^^^^^^^^\nError [ETYC0372060]: A tuple expression cannot contain another tuple expression.\n --> compiler-test:13:22\n |\n 13 | return (1u8, (2u16, 3u32));\n | ^^^^^^^^^^^^\nError [ETYC0372060]: A tuple expression cannot contain another tuple expression.\n --> compiler-test:13:22\n |\n 13 | return (1u8, (2u16, 3u32));\n | ^^^^^^^^^^^^\nError [ETYC0372007]: Expected one type from `i8, i16, i32, i64, i128, u8, u16, u32, u64, u128`, but got `(u8,u16)`\n --> compiler-test:17:13\n |\n 17 | for i: (u8, u16) in 0u8..2u8 {}\n | ^\nError [ETYC0372003]: Expected type `(u8,u16)` but type `u8` was found\n --> compiler-test:17:29\n |\n 17 | for i: (u8, u16) in 0u8..2u8 {}\n | ^^^\nError [ETYC0372003]: Expected type `(u8,u16)` but type `u8` was found\n --> compiler-test:17:34\n |\n 17 | for i: (u8, u16) in 0u8..2u8 {}\n | ^^^\n"