mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-22 13:25:30 +03:00
commit
7f37b2f3d8
@ -217,24 +217,14 @@ pub trait StatementReconstructor: ExpressionReconstructor {
|
|||||||
Statement::Console(ConsoleStatement {
|
Statement::Console(ConsoleStatement {
|
||||||
function: match input.function {
|
function: match input.function {
|
||||||
ConsoleFunction::Assert(expr) => ConsoleFunction::Assert(self.reconstruct_expression(expr).0),
|
ConsoleFunction::Assert(expr) => ConsoleFunction::Assert(self.reconstruct_expression(expr).0),
|
||||||
ConsoleFunction::Error(fmt) => ConsoleFunction::Error(ConsoleArgs {
|
ConsoleFunction::AssertEq(left, right) => ConsoleFunction::AssertEq(
|
||||||
string: fmt.string,
|
self.reconstruct_expression(left).0,
|
||||||
parameters: fmt
|
self.reconstruct_expression(right).0,
|
||||||
.parameters
|
),
|
||||||
.into_iter()
|
ConsoleFunction::AssertNeq(left, right) => ConsoleFunction::AssertNeq(
|
||||||
.map(|p| self.reconstruct_expression(p).0)
|
self.reconstruct_expression(left).0,
|
||||||
.collect(),
|
self.reconstruct_expression(right).0,
|
||||||
span: fmt.span,
|
),
|
||||||
}),
|
|
||||||
ConsoleFunction::Log(fmt) => ConsoleFunction::Log(ConsoleArgs {
|
|
||||||
string: fmt.string,
|
|
||||||
parameters: fmt
|
|
||||||
.parameters
|
|
||||||
.into_iter()
|
|
||||||
.map(|p| self.reconstruct_expression(p).0)
|
|
||||||
.collect(),
|
|
||||||
span: fmt.span,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
span: input.span,
|
span: input.span,
|
||||||
})
|
})
|
||||||
|
@ -157,10 +157,13 @@ pub trait StatementVisitor<'a>: ExpressionVisitor<'a> {
|
|||||||
ConsoleFunction::Assert(expr) => {
|
ConsoleFunction::Assert(expr) => {
|
||||||
self.visit_expression(expr, &Default::default());
|
self.visit_expression(expr, &Default::default());
|
||||||
}
|
}
|
||||||
ConsoleFunction::Error(fmt) | ConsoleFunction::Log(fmt) => {
|
ConsoleFunction::AssertEq(left, right) => {
|
||||||
fmt.parameters.iter().for_each(|expr| {
|
self.visit_expression(left, &Default::default());
|
||||||
self.visit_expression(expr, &Default::default());
|
self.visit_expression(right, &Default::default());
|
||||||
});
|
}
|
||||||
|
ConsoleFunction::AssertNeq(left, right) => {
|
||||||
|
self.visit_expression(left, &Default::default());
|
||||||
|
self.visit_expression(right, &Default::default());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,49 +0,0 @@
|
|||||||
// Copyright (C) 2019-2022 Aleo Systems Inc.
|
|
||||||
// This file is part of the Leo library.
|
|
||||||
|
|
||||||
// The Leo library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// The Leo library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
use crate::{Expression, Node, StaticString};
|
|
||||||
use leo_span::Span;
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
/// The arguments `args` passed to `console.log(args)` or `console.error(args)`.
|
|
||||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
|
||||||
pub struct ConsoleArgs {
|
|
||||||
/// The formatting string with `parameters` interpolated into it.
|
|
||||||
pub string: StaticString,
|
|
||||||
/// Parameters to interpolate in `string`.
|
|
||||||
pub parameters: Vec<Expression>,
|
|
||||||
/// The span from `(` to `)`.
|
|
||||||
pub span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for ConsoleArgs {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"\"{}\", {}",
|
|
||||||
self.string,
|
|
||||||
self.parameters
|
|
||||||
.iter()
|
|
||||||
.map(|p| p.to_string())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(",")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
crate::simple_node_impl!(ConsoleArgs);
|
|
@ -14,8 +14,7 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{ConsoleArgs, Expression, Node};
|
use crate::Expression;
|
||||||
use leo_span::Span;
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -23,39 +22,20 @@ use std::fmt;
|
|||||||
/// A console logging function to invoke.
|
/// A console logging function to invoke.
|
||||||
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
|
||||||
pub enum ConsoleFunction {
|
pub enum ConsoleFunction {
|
||||||
/// A `console.assert(expr)` call to invoke,
|
/// A `console.assert(expr)` call to invoke, asserting that the expression evaluates to true.
|
||||||
/// asserting that the expression evaluates to `true`.
|
|
||||||
Assert(Expression),
|
Assert(Expression),
|
||||||
/// A `console.error(args)` call to invoke,
|
/// A `console.assert_eq(expr1, expr2)` call to invoke, asserting that the operands are equal.
|
||||||
/// resulting in an error at runtime.
|
AssertEq(Expression, Expression),
|
||||||
Error(ConsoleArgs),
|
/// A `console.assert_neq(expr1, expr2)` call to invoke, asserting that the operands are not equal.
|
||||||
/// A `console.log(args)` call to invoke,
|
AssertNeq(Expression, Expression),
|
||||||
/// resulting in a log message at runtime.
|
|
||||||
Log(ConsoleArgs),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ConsoleFunction {
|
impl fmt::Display for ConsoleFunction {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ConsoleFunction::Assert(assert) => write!(f, "assert({})", assert),
|
ConsoleFunction::Assert(expr) => write!(f, "assert({})", expr),
|
||||||
ConsoleFunction::Error(error) => write!(f, "error{})", error),
|
ConsoleFunction::AssertEq(expr1, expr2) => write!(f, "assert_eq({}, {})", expr1, expr2),
|
||||||
ConsoleFunction::Log(log) => write!(f, "log({})", log),
|
ConsoleFunction::AssertNeq(expr1, expr2) => write!(f, "assert_neq({}, {})", expr1, expr2),
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Node for ConsoleFunction {
|
|
||||||
fn span(&self) -> Span {
|
|
||||||
match self {
|
|
||||||
ConsoleFunction::Assert(assert) => assert.span(),
|
|
||||||
ConsoleFunction::Error(formatted) | ConsoleFunction::Log(formatted) => formatted.span,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_span(&mut self, span: Span) {
|
|
||||||
match self {
|
|
||||||
ConsoleFunction::Assert(assert) => assert.set_span(span),
|
|
||||||
ConsoleFunction::Error(formatted) | ConsoleFunction::Log(formatted) => formatted.set_span(span),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,5 @@
|
|||||||
pub mod console_function;
|
pub mod console_function;
|
||||||
pub use console_function::*;
|
pub use console_function::*;
|
||||||
|
|
||||||
pub mod console_args;
|
|
||||||
pub use console_args::*;
|
|
||||||
|
|
||||||
pub mod console_statement;
|
pub mod console_statement;
|
||||||
pub use console_statement::*;
|
pub use console_statement::*;
|
||||||
|
@ -78,7 +78,7 @@ impl fmt::Display for Type {
|
|||||||
Type::Boolean => write!(f, "boolean"),
|
Type::Boolean => write!(f, "boolean"),
|
||||||
Type::Field => write!(f, "field"),
|
Type::Field => write!(f, "field"),
|
||||||
Type::Group => write!(f, "group"),
|
Type::Group => write!(f, "group"),
|
||||||
Type::Identifier(ref variable) => write!(f, "circuit {}", variable),
|
Type::Identifier(ref variable) => write!(f, "{}", variable),
|
||||||
Type::Integer(ref integer_type) => write!(f, "{}", integer_type),
|
Type::Integer(ref integer_type) => write!(f, "{}", integer_type),
|
||||||
Type::Scalar => write!(f, "scalar"),
|
Type::Scalar => write!(f, "scalar"),
|
||||||
Type::String => write!(f, "string"),
|
Type::String => write!(f, "string"),
|
||||||
|
@ -172,62 +172,53 @@ impl ParserContext<'_> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a [`ConsoleArgs`] AST node if the next tokens represent a formatted string.
|
|
||||||
fn parse_console_args(&mut self) -> Result<ConsoleArgs> {
|
|
||||||
let mut static_string = None;
|
|
||||||
let (parameters, _, span) = self.parse_paren_comma_list(|p| {
|
|
||||||
if static_string.is_none() {
|
|
||||||
p.bump();
|
|
||||||
let SpannedToken { token, span } = p.prev_token.clone();
|
|
||||||
match token {
|
|
||||||
Token::StaticString(string) => {
|
|
||||||
static_string = Some(StaticString::new(string));
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
p.emit_err(ParserError::unexpected_str(token, "formatted static_string", span));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Ok(None)
|
|
||||||
} else {
|
|
||||||
p.parse_expression().map(Some)
|
|
||||||
}
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(ConsoleArgs {
|
|
||||||
string: static_string.unwrap_or_default(),
|
|
||||||
span,
|
|
||||||
parameters,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a [`ConsoleStatement`] AST node if the next tokens represent a console statement.
|
/// Returns a [`ConsoleStatement`] AST node if the next tokens represent a console statement.
|
||||||
fn parse_console_statement(&mut self) -> Result<ConsoleStatement> {
|
fn parse_console_statement(&mut self) -> Result<ConsoleStatement> {
|
||||||
let keyword = self.expect(&Token::Console)?;
|
let keyword = self.expect(&Token::Console)?;
|
||||||
self.expect(&Token::Dot)?;
|
self.expect(&Token::Dot)?;
|
||||||
let function = self.expect_identifier()?;
|
let identifier = self.expect_identifier()?;
|
||||||
let function = match function.name {
|
let (span, function) = match identifier.name {
|
||||||
sym::assert => {
|
sym::assert => {
|
||||||
self.expect(&Token::LeftParen)?;
|
self.expect(&Token::LeftParen)?;
|
||||||
let expr = self.parse_expression()?;
|
let expr = self.parse_expression()?;
|
||||||
self.expect(&Token::RightParen)?;
|
self.expect(&Token::RightParen)?;
|
||||||
ConsoleFunction::Assert(expr)
|
(keyword + expr.span(), ConsoleFunction::Assert(expr))
|
||||||
}
|
}
|
||||||
sym::error => ConsoleFunction::Error(self.parse_console_args()?),
|
sym::assert_eq => {
|
||||||
sym::log => ConsoleFunction::Log(self.parse_console_args()?),
|
self.expect(&Token::LeftParen)?;
|
||||||
x => {
|
let left = self.parse_expression()?;
|
||||||
|
self.expect(&Token::Comma)?;
|
||||||
|
let right = self.parse_expression()?;
|
||||||
|
self.expect(&Token::RightParen)?;
|
||||||
|
(left.span() + right.span(), ConsoleFunction::AssertEq(left, right))
|
||||||
|
}
|
||||||
|
sym::assert_neq => {
|
||||||
|
self.expect(&Token::LeftParen)?;
|
||||||
|
let left = self.parse_expression()?;
|
||||||
|
self.expect(&Token::Comma)?;
|
||||||
|
let right = self.parse_expression()?;
|
||||||
|
self.expect(&Token::RightParen)?;
|
||||||
|
(left.span() + right.span(), ConsoleFunction::AssertNeq(left, right))
|
||||||
|
}
|
||||||
|
symbol => {
|
||||||
// Not sure what it is, assume it's `log`.
|
// Not sure what it is, assume it's `log`.
|
||||||
self.emit_err(ParserError::unexpected_ident(
|
self.emit_err(ParserError::unexpected_ident(
|
||||||
x,
|
symbol,
|
||||||
&["assert", "error", "log"],
|
&["assert", "assert_eq", "assert_neq"],
|
||||||
function.span,
|
identifier.span,
|
||||||
));
|
));
|
||||||
ConsoleFunction::Log(self.parse_console_args()?)
|
(
|
||||||
|
Default::default(),
|
||||||
|
ConsoleFunction::Assert(Expression::Err(ErrExpression {
|
||||||
|
span: Default::default(),
|
||||||
|
})),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.expect(&Token::Semicolon)?;
|
self.expect(&Token::Semicolon)?;
|
||||||
|
|
||||||
Ok(ConsoleStatement {
|
Ok(ConsoleStatement {
|
||||||
span: keyword + function.span(),
|
span: keyword + span,
|
||||||
function,
|
function,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
use crate::CodeGenerator;
|
use crate::CodeGenerator;
|
||||||
|
|
||||||
use leo_ast::{
|
use leo_ast::{
|
||||||
AssignStatement, Block, ConditionalStatement, ConsoleStatement, DefinitionStatement, Expression,
|
AssignStatement, Block, ConditionalStatement, ConsoleFunction, ConsoleStatement, DefinitionStatement, Expression,
|
||||||
IterationStatement, ParamMode, ReturnStatement, Statement,
|
IterationStatement, ParamMode, ReturnStatement, Statement,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -85,9 +85,30 @@ impl<'a> CodeGenerator<'a> {
|
|||||||
unreachable!("`IterationStatement`s should not be in the AST at this phase of compilation.");
|
unreachable!("`IterationStatement`s should not be in the AST at this phase of compilation.");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_console(&mut self, _input: &'a ConsoleStatement) -> String {
|
fn visit_console(&mut self, input: &'a ConsoleStatement) -> String {
|
||||||
// `ConsoleStatement`s do not need to be included in the bytecode.
|
let mut generate_assert_instruction = |name: &str, left: &'a Expression, right: &'a Expression| {
|
||||||
String::new()
|
let (left_operand, left_instructions) = self.visit_expression(left);
|
||||||
|
let (right_operand, right_instructions) = self.visit_expression(right);
|
||||||
|
let assert_instruction = format!(" {} {} {};", name, left_operand, right_operand);
|
||||||
|
|
||||||
|
// Concatenate the instructions.
|
||||||
|
let mut instructions = left_instructions;
|
||||||
|
instructions.push_str(&right_instructions);
|
||||||
|
instructions.push_str(&assert_instruction);
|
||||||
|
|
||||||
|
instructions
|
||||||
|
};
|
||||||
|
match &input.function {
|
||||||
|
ConsoleFunction::Assert(expr) => {
|
||||||
|
let (operand, mut instructions) = self.visit_expression(expr);
|
||||||
|
let assert_instruction = format!(" assert.eq {} true;", operand);
|
||||||
|
|
||||||
|
instructions.push_str(&assert_instruction);
|
||||||
|
instructions
|
||||||
|
}
|
||||||
|
ConsoleFunction::AssertEq(left, right) => generate_assert_instruction("assert.eq", left, right),
|
||||||
|
ConsoleFunction::AssertNeq(left, right) => generate_assert_instruction("assert.neq", left, right),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn visit_block(&mut self, input: &'a Block) -> String {
|
pub(crate) fn visit_block(&mut self, input: &'a Block) -> String {
|
||||||
|
@ -193,10 +193,15 @@ impl<'a> StatementVisitor<'a> for TypeChecker<'a> {
|
|||||||
fn visit_console(&mut self, input: &'a ConsoleStatement) {
|
fn visit_console(&mut self, input: &'a ConsoleStatement) {
|
||||||
match &input.function {
|
match &input.function {
|
||||||
ConsoleFunction::Assert(expr) => {
|
ConsoleFunction::Assert(expr) => {
|
||||||
self.visit_expression(expr, &Some(Type::Boolean));
|
let type_ = self.visit_expression(expr, &Some(Type::Boolean));
|
||||||
|
self.assert_bool_type(&type_, expr.span());
|
||||||
}
|
}
|
||||||
ConsoleFunction::Error(_) | ConsoleFunction::Log(_) => {
|
ConsoleFunction::AssertEq(left, right) | ConsoleFunction::AssertNeq(left, right) => {
|
||||||
// TODO: undetermined
|
let t1 = self.visit_expression(left, &None);
|
||||||
|
let t2 = self.visit_expression(right, &None);
|
||||||
|
|
||||||
|
// Check that the types are equal.
|
||||||
|
self.check_eq_types(&t1, &t2, input.span());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,9 @@ impl<'a> TypeChecker<'a> {
|
|||||||
/// Emits an error if the two given types are not equal.
|
/// Emits an error if the two given types are not equal.
|
||||||
pub(crate) fn check_eq_types(&self, t1: &Option<Type>, t2: &Option<Type>, span: Span) {
|
pub(crate) fn check_eq_types(&self, t1: &Option<Type>, t2: &Option<Type>, span: Span) {
|
||||||
match (t1, t2) {
|
match (t1, t2) {
|
||||||
(Some(t1), Some(t2)) if t1 != t2 => self.emit_err(TypeCheckerError::type_should_be(t1, t2, span)),
|
(Some(t1), Some(t2)) if !Type::eq_flat(t1, t2) => {
|
||||||
|
self.emit_err(TypeCheckerError::type_should_be(t1, t2, span))
|
||||||
|
}
|
||||||
(Some(type_), None) | (None, Some(type_)) => {
|
(Some(type_), None) | (None, Some(type_)) => {
|
||||||
self.emit_err(TypeCheckerError::type_should_be("no type", type_, span))
|
self.emit_err(TypeCheckerError::type_should_be("no type", type_, span))
|
||||||
}
|
}
|
||||||
|
@ -187,7 +187,6 @@ symbols! {
|
|||||||
CoreFunction,
|
CoreFunction,
|
||||||
console,
|
console,
|
||||||
Else: "else",
|
Else: "else",
|
||||||
error,
|
|
||||||
For: "for",
|
For: "for",
|
||||||
function,
|
function,
|
||||||
If: "if",
|
If: "if",
|
||||||
@ -196,7 +195,8 @@ symbols! {
|
|||||||
input,
|
input,
|
||||||
Let: "let",
|
Let: "let",
|
||||||
leo,
|
leo,
|
||||||
log,
|
assert_eq,
|
||||||
|
assert_neq,
|
||||||
main,
|
main,
|
||||||
Mut: "mut",
|
Mut: "mut",
|
||||||
prelude,
|
prelude,
|
||||||
|
@ -4,8 +4,32 @@ expectation: Pass
|
|||||||
input_file: inputs/true.in
|
input_file: inputs/true.in
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
circuit Foo {
|
||||||
|
a: u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
record Token {
|
||||||
|
// The token owner.
|
||||||
|
owner: address,
|
||||||
|
// The Aleo balance (in gates).
|
||||||
|
gates: u64,
|
||||||
|
// The token amount.
|
||||||
|
amount: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@program
|
@program
|
||||||
function main(a: bool) -> bool {
|
function main(a: bool, foo: Foo, token: Token) -> bool {
|
||||||
console.assert(a == true);
|
console.assert_eq(a, true);
|
||||||
|
console.assert_neq(a, false);
|
||||||
|
console.assert(a);
|
||||||
|
|
||||||
|
console.assert_eq(foo, Foo { a: 0u8 });
|
||||||
|
|
||||||
|
console.assert_neq(token, Token {
|
||||||
|
owner: aleo1lfapwg53y5enqpt0d8cnef4g8lj7l6g9uhkkma23qyv6jm4ppyfq50regr,
|
||||||
|
gates: 0u64,
|
||||||
|
amount: 0u64,
|
||||||
|
});
|
||||||
return a == true;
|
return a == true;
|
||||||
}
|
}
|
||||||
|
14
tests/compiler/console/assert_fail.leo
Normal file
14
tests/compiler/console/assert_fail.leo
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Fail
|
||||||
|
input_file: inputs/true.in
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@program
|
||||||
|
function main(a: bool) -> bool {
|
||||||
|
console.assert_eq(a == 1u8);
|
||||||
|
console.assert(1u8);
|
||||||
|
|
||||||
|
return a == true;
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
namespace: Compile
|
|
||||||
expectation: Pass
|
|
||||||
input_file: inputs/dummy.in
|
|
||||||
*/
|
|
||||||
|
|
||||||
@program
|
|
||||||
function main(y: bool) -> bool {
|
|
||||||
console.error("hello error");
|
|
||||||
return y == true;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
namespace: Compile
|
|
||||||
expectation: Pass
|
|
||||||
input_file: inputs/dummy.in
|
|
||||||
*/
|
|
||||||
|
|
||||||
@program
|
|
||||||
function main(y: bool) -> bool {
|
|
||||||
console.log("hello world");
|
|
||||||
return y == true;
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
/*
|
|
||||||
namespace: Compile
|
|
||||||
expectation: Pass
|
|
||||||
input_file:
|
|
||||||
- inputs/input_unequal.in
|
|
||||||
- inputs/input_equal.in
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Conditionally add two u32 integers and log the result to the console.
|
|
||||||
@program
|
|
||||||
function main(a: u32, b: u32) -> bool {
|
|
||||||
if a == b {
|
|
||||||
console.log("{}=={}", a, b); // This line should not fail.
|
|
||||||
}
|
|
||||||
|
|
||||||
return a == b;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
/*
|
|
||||||
namespace: Compile
|
|
||||||
expectation: Fail
|
|
||||||
*/
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
console.log( hello );
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
namespace: Compile
|
|
||||||
expectation: Pass
|
|
||||||
input_file: inputs/dummy.in
|
|
||||||
*/
|
|
||||||
|
|
||||||
@program
|
|
||||||
function main(y: bool) -> bool {
|
|
||||||
console.log("a = {}", y);
|
|
||||||
return y == true;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
namespace: Compile
|
|
||||||
expectation: Pass
|
|
||||||
input_file: inputs/dummy.in
|
|
||||||
*/
|
|
||||||
|
|
||||||
@program
|
|
||||||
function main(y: bool) -> bool {
|
|
||||||
console.log("{}", 1u32);
|
|
||||||
return y == true;
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
namespace: Compile
|
|
||||||
expectation: Pass
|
|
||||||
input_file: inputs/dummy.in
|
|
||||||
*/
|
|
||||||
|
|
||||||
@program
|
|
||||||
function main(y: bool) -> bool {
|
|
||||||
console.log("{} {}", 1u32, true);
|
|
||||||
return y == true;
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
/*
|
|
||||||
namespace: Compile
|
|
||||||
expectation: Fail
|
|
||||||
*/
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
console.log("{}", a);
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
namespace: Compile
|
|
||||||
expectation: Fail
|
|
||||||
input_file: inputs/dummy.in
|
|
||||||
*/
|
|
||||||
|
|
||||||
function main(y: bool) -> bool {
|
|
||||||
let hello: string = "hello world";
|
|
||||||
console.log(hello);
|
|
||||||
return y == true;
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
namespace: Compile
|
namespace: Compile
|
||||||
expectation: Fail
|
expectation: Pass
|
||||||
*/
|
*/
|
||||||
|
|
||||||
circuit Amount {
|
circuit Amount {
|
||||||
@ -32,4 +32,4 @@ function main(x: address) -> u64 {
|
|||||||
let t: Token = Token { owner: x, gates: 0u64, amount: Amount { amount: c, amt: c } };
|
let t: Token = Token { owner: x, gates: 0u64, amount: Amount { amount: c, amt: c } };
|
||||||
|
|
||||||
return t.gates;
|
return t.gates;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ namespace: Compile
|
|||||||
expectation: Pass
|
expectation: Pass
|
||||||
outputs:
|
outputs:
|
||||||
- output:
|
- output:
|
||||||
- initial_input_ast: 222defe193f82972f049ae44ae527ea3c1404b7eb75fca2d1eea23b28e792a8d
|
- initial_input_ast: 00ae278f2e47685455a873498a580f06abfcb7bae93cc5844c2616a7da7d03db
|
||||||
initial_ast: 6c65fcbd8d4c78b14b44e6c5a8a5aa207ddaaec906b6dbe4f3767bb268fcd244
|
initial_ast: c9e573f04eefae7c4769e23ef75e1b330fc728126ddfa82458f96e4677ee50a1
|
||||||
unrolled_ast: 6c65fcbd8d4c78b14b44e6c5a8a5aa207ddaaec906b6dbe4f3767bb268fcd244
|
unrolled_ast: c9e573f04eefae7c4769e23ef75e1b330fc728126ddfa82458f96e4677ee50a1
|
||||||
ssa_ast: c346c03c0dbd339428c528740ed1e8b9ed8592e9abe59c995c83089fffb9c707
|
ssa_ast: 4ee779d08beb04336cddb64d1b0e4a662d90b178754f6ffece96bd94e751686d
|
||||||
|
5
tests/expectations/compiler/console/assert_fail.out
Normal file
5
tests/expectations/compiler/console/assert_fail.out
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
namespace: Compile
|
||||||
|
expectation: Fail
|
||||||
|
outputs:
|
||||||
|
- "Error [EPAR0370005]: expected , -- found ')'\n --> compiler-test:6:31\n |\n 6 | console.assert_eq(a == 1u8);\n | ^"
|
@ -2,4 +2,4 @@
|
|||||||
namespace: Compile
|
namespace: Compile
|
||||||
expectation: Fail
|
expectation: Fail
|
||||||
outputs:
|
outputs:
|
||||||
- "Error [EAST0372008]: function `main` shadowed by\n --> compiler-test:8:1\n |\n 8 | function main(y: bool) -> bool {\n 9 | console.log(\"{}\", 2u8);\n 10 | return y; \n 11 | }\n | ^\n"
|
- "Error [EPAR0370007]: unexpected identifier: expected 'assert', 'assert_eq', 'assert_neq' -- found 'log'\n --> compiler-test:4:13\n |\n 4 | console.log(\"{}\", 1u8);\n | ^^^\nError [EPAR0370005]: expected ; -- found '('\n --> compiler-test:4:16\n |\n 4 | console.log(\"{}\", 1u8);\n | ^"
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
namespace: Compile
|
namespace: Compile
|
||||||
expectation: Fail
|
expectation: Fail
|
||||||
outputs:
|
outputs:
|
||||||
- "Error [EAST0372011]: variable `a` shadowed by\n --> compiler-test:3:23\n |\n 3 | function main(a: u32, a: u32) -> u32 {\n | ^\n"
|
- "Error [EPAR0370007]: unexpected identifier: expected 'assert', 'assert_eq', 'assert_neq' -- found 'log'\n --> compiler-test:4:13\n |\n 4 | console.log(\"{}\", 1u8);\n | ^^^\nError [EPAR0370005]: expected ; -- found '('\n --> compiler-test:4:16\n |\n 4 | console.log(\"{}\", 1u8);\n | ^"
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
namespace: Compile
|
namespace: Compile
|
||||||
expectation: Fail
|
expectation: Fail
|
||||||
outputs:
|
outputs:
|
||||||
- "Error [ETYC0372017]: The type `Foo` is not found in the current scope.\n --> compiler-test:4:22\n |\n 4 | function main(a: u8, foo: Foo) -> u8 {\n | ^^^\nError [ETYC0372003]: Expected type `circuit Foo` but type `u8` was found\n --> compiler-test:9:22\n |\n 9 | function returns_foo(a: u8) -> Foo {\n | ^\nError [ETYC0372017]: The type `Foo` is not found in the current scope.\n --> compiler-test:9:1\n |\n 9 | function returns_foo(a: u8) -> Foo {\n 10 | return a;\n 11 | }\n | ^\n"
|
- "Error [ETYC0372017]: The type `Foo` is not found in the current scope.\n --> compiler-test:4:22\n |\n 4 | function main(a: u8, foo: Foo) -> u8 {\n | ^^^\nError [ETYC0372003]: Expected type `Foo` but type `u8` was found\n --> compiler-test:9:22\n |\n 9 | function returns_foo(a: u8) -> Foo {\n | ^\nError [ETYC0372017]: The type `Foo` is not found in the current scope.\n --> compiler-test:9:1\n |\n 9 | function returns_foo(a: u8) -> Foo {\n 10 | return a;\n 11 | }\n | ^\n"
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
---
|
---
|
||||||
namespace: Compile
|
namespace: Compile
|
||||||
expectation: Fail
|
expectation: Pass
|
||||||
outputs:
|
outputs:
|
||||||
- "Failed to parse string. Remaining invalid string is: \"amount as circuit amount.private;\n\n\nfunction mint:\n input r0 as address.private;\n input r1 as u64.private;\n cast r1 r1 into r2 as amount;\n cast r0 0u64 r2 into r3 as token.record;\n output r3 as token.record;\n\nfunction main:\n input r0 as address.private;\n cast 1u64 1u64 into r1 as amount;\n cast r0 0u64 r1 into r2 as token.record;\n output r2.gates as u64.private;\n\n\""
|
- output:
|
||||||
|
- initial_input_ast: no input
|
||||||
|
initial_ast: 4c9190de88fefd0cd576a5567f42bc1ac4b4db466cbf26703d0226928ba3b593
|
||||||
|
unrolled_ast: 4c9190de88fefd0cd576a5567f42bc1ac4b4db466cbf26703d0226928ba3b593
|
||||||
|
ssa_ast: bbf5abf43a38845ceaf00571964f6313382ba7af97a42a272720003e8ed8430d
|
||||||
|
@ -2,4 +2,4 @@
|
|||||||
namespace: Compile
|
namespace: Compile
|
||||||
expectation: Fail
|
expectation: Fail
|
||||||
outputs:
|
outputs:
|
||||||
- "Error [ETYC0372017]: The type `Foo` is not found in the current scope.\n --> compiler-test:5:2\n |\n 5 | \tlet b: Foo = 1u8;\n | ^^^^^^^^^^^^^^^^\nError [ETYC0372003]: Expected type `circuit Foo` but type `u8` was found\n --> compiler-test:5:15\n |\n 5 | \tlet b: Foo = 1u8;\n | ^^^\n"
|
- "Error [ETYC0372017]: The type `Foo` is not found in the current scope.\n --> compiler-test:5:2\n |\n 5 | \tlet b: Foo = 1u8;\n | ^^^^^^^^^^^^^^^^\nError [ETYC0372003]: Expected type `Foo` but type `u8` was found\n --> compiler-test:5:15\n |\n 5 | \tlet b: Foo = 1u8;\n | ^^^\n"
|
||||||
|
@ -4,80 +4,53 @@ expectation: Pass
|
|||||||
outputs:
|
outputs:
|
||||||
- Console:
|
- Console:
|
||||||
function:
|
function:
|
||||||
Assert:
|
AssertEq:
|
||||||
Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":15,\\\"hi\\\":16}\"}"
|
- Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":18,\\\"hi\\\":19}\"}"
|
||||||
span:
|
- Identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":21,\\\"hi\\\":22}\"}"
|
||||||
lo: 0
|
|
||||||
hi: 16
|
|
||||||
- Console:
|
|
||||||
function:
|
|
||||||
Error:
|
|
||||||
string: "{}"
|
|
||||||
parameters:
|
|
||||||
- Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":20,\\\"hi\\\":21}\"}"
|
|
||||||
span:
|
|
||||||
lo: 13
|
|
||||||
hi: 22
|
|
||||||
span:
|
span:
|
||||||
lo: 0
|
lo: 0
|
||||||
hi: 22
|
hi: 22
|
||||||
- Console:
|
- Console:
|
||||||
function:
|
function:
|
||||||
Error:
|
AssertEq:
|
||||||
string: "{}{}"
|
- Circuit:
|
||||||
parameters:
|
name: "{\"name\":\"Foo\",\"span\":\"{\\\"lo\\\":18,\\\"hi\\\":21}\"}"
|
||||||
- Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":22,\\\"hi\\\":23}\"}"
|
members:
|
||||||
- Identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":25,\\\"hi\\\":26}\"}"
|
- identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":24,\\\"hi\\\":25}\"}"
|
||||||
span:
|
expression:
|
||||||
lo: 13
|
Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":27,\\\"hi\\\":28}\"}"
|
||||||
hi: 27
|
span:
|
||||||
|
lo: 18
|
||||||
|
hi: 30
|
||||||
|
- Circuit:
|
||||||
|
name: "{\"name\":\"Foo\",\"span\":\"{\\\"lo\\\":32,\\\"hi\\\":35}\"}"
|
||||||
|
members:
|
||||||
|
- identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":38,\\\"hi\\\":39}\"}"
|
||||||
|
expression:
|
||||||
|
Identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":41,\\\"hi\\\":42}\"}"
|
||||||
|
span:
|
||||||
|
lo: 32
|
||||||
|
hi: 44
|
||||||
span:
|
span:
|
||||||
lo: 0
|
lo: 0
|
||||||
hi: 27
|
hi: 44
|
||||||
- Console:
|
- Console:
|
||||||
function:
|
function:
|
||||||
Error:
|
AssertNeq:
|
||||||
string: x
|
- Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":19,\\\"hi\\\":20}\"}"
|
||||||
parameters: []
|
- Identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":22,\\\"hi\\\":23}\"}"
|
||||||
span:
|
|
||||||
lo: 13
|
|
||||||
hi: 18
|
|
||||||
span:
|
span:
|
||||||
lo: 0
|
lo: 0
|
||||||
hi: 18
|
hi: 23
|
||||||
- Console:
|
- Console:
|
||||||
function:
|
function:
|
||||||
Log:
|
Assert:
|
||||||
string: "{}"
|
Literal:
|
||||||
parameters:
|
Boolean:
|
||||||
- Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":18,\\\"hi\\\":19}\"}"
|
- false
|
||||||
span:
|
- span:
|
||||||
lo: 11
|
lo: 15
|
||||||
hi: 20
|
hi: 20
|
||||||
span:
|
span:
|
||||||
lo: 0
|
lo: 0
|
||||||
hi: 20
|
hi: 20
|
||||||
- Console:
|
|
||||||
function:
|
|
||||||
Log:
|
|
||||||
string: "{}{}"
|
|
||||||
parameters:
|
|
||||||
- Identifier: "{\"name\":\"x\",\"span\":\"{\\\"lo\\\":20,\\\"hi\\\":21}\"}"
|
|
||||||
- Identifier: "{\"name\":\"y\",\"span\":\"{\\\"lo\\\":23,\\\"hi\\\":24}\"}"
|
|
||||||
span:
|
|
||||||
lo: 11
|
|
||||||
hi: 25
|
|
||||||
span:
|
|
||||||
lo: 0
|
|
||||||
hi: 25
|
|
||||||
- Console:
|
|
||||||
function:
|
|
||||||
Log:
|
|
||||||
string: x
|
|
||||||
parameters: []
|
|
||||||
span:
|
|
||||||
lo: 11
|
|
||||||
hi: 16
|
|
||||||
span:
|
|
||||||
lo: 0
|
|
||||||
hi: 16
|
|
||||||
|
@ -3,5 +3,11 @@ namespace: ParseStatement
|
|||||||
expectation: Fail
|
expectation: Fail
|
||||||
outputs:
|
outputs:
|
||||||
- "Error [EPAR0370021]: Unicode bidi override code point encountered."
|
- "Error [EPAR0370021]: Unicode bidi override code point encountered."
|
||||||
- "Error [EPAR0370009]: unexpected string: expected 'formatted static_string', found '1'\n --> test:1:13\n |\n 1 | console.log(1);\n | ^"
|
- "Error [EPAR0370007]: unexpected identifier: expected 'assert', 'assert_eq', 'assert_neq' -- found 'log'\n --> test:1:9\n |\n 1 | console.log(1);\n | ^^^\nError [EPAR0370005]: expected ; -- found '('\n --> test:1:12\n |\n 1 | console.log(1);\n | ^"
|
||||||
- "Error [EPAR0370007]: unexpected identifier: expected 'assert', 'error', 'log' -- found 'test'\n --> test:1:9\n |\n 1 | console.test();\n | ^^^^"
|
- "Error [EPAR0370007]: unexpected identifier: expected 'assert', 'assert_eq', 'assert_neq' -- found 'test'\n --> test:1:9\n |\n 1 | console.test();\n | ^^^^\nError [EPAR0370005]: expected ; -- found '('\n --> test:1:13\n |\n 1 | console.test();\n | ^"
|
||||||
|
- "Error [EPAR0370007]: unexpected identifier: expected 'assert', 'assert_eq', 'assert_neq' -- found 'error'\n --> test:1:9\n |\n 1 | console.error(\"{}\", x);\n | ^^^^^\nError [EPAR0370005]: expected ; -- found '('\n --> test:1:14\n |\n 1 | console.error(\"{}\", x);\n | ^"
|
||||||
|
- "Error [EPAR0370007]: unexpected identifier: expected 'assert', 'assert_eq', 'assert_neq' -- found 'error'\n --> test:1:9\n |\n 1 | console.error(\"{}{}\", x, y);\n | ^^^^^\nError [EPAR0370005]: expected ; -- found '('\n --> test:1:14\n |\n 1 | console.error(\"{}{}\", x, y);\n | ^"
|
||||||
|
- "Error [EPAR0370007]: unexpected identifier: expected 'assert', 'assert_eq', 'assert_neq' -- found 'error'\n --> test:1:9\n |\n 1 | console.error(\"x\");\n | ^^^^^\nError [EPAR0370005]: expected ; -- found '('\n --> test:1:14\n |\n 1 | console.error(\"x\");\n | ^"
|
||||||
|
- "Error [EPAR0370007]: unexpected identifier: expected 'assert', 'assert_eq', 'assert_neq' -- found 'log'\n --> test:1:9\n |\n 1 | console.log(\"{}\", x);\n | ^^^\nError [EPAR0370005]: expected ; -- found '('\n --> test:1:12\n |\n 1 | console.log(\"{}\", x);\n | ^"
|
||||||
|
- "Error [EPAR0370007]: unexpected identifier: expected 'assert', 'assert_eq', 'assert_neq' -- found 'log'\n --> test:1:9\n |\n 1 | console.log(\"{}{}\", x, y);\n | ^^^\nError [EPAR0370005]: expected ; -- found '('\n --> test:1:12\n |\n 1 | console.log(\"{}{}\", x, y);\n | ^"
|
||||||
|
- "Error [EPAR0370007]: unexpected identifier: expected 'assert', 'assert_eq', 'assert_neq' -- found 'log'\n --> test:1:9\n |\n 1 | console.log(\"x\");\n | ^^^\nError [EPAR0370005]: expected ; -- found '('\n --> test:1:12\n |\n 1 | console.log(\"x\");\n | ^"
|
||||||
|
@ -3,18 +3,10 @@ namespace: ParseStatement
|
|||||||
expectation: Pass
|
expectation: Pass
|
||||||
*/
|
*/
|
||||||
|
|
||||||
console.assert(x);
|
console.assert_eq(x, y);
|
||||||
|
|
||||||
|
console.assert_eq(Foo { x: x }, Foo { x: y });
|
||||||
|
|
||||||
console.error("{}", x);
|
console.assert_neq(x, y);
|
||||||
|
|
||||||
console.error("{}{}", x, y);
|
console.assert(false);
|
||||||
|
|
||||||
console.error("x");
|
|
||||||
|
|
||||||
|
|
||||||
console.log("{}", x);
|
|
||||||
|
|
||||||
console.log("{}{}", x, y);
|
|
||||||
|
|
||||||
console.log("x");
|
|
||||||
|
@ -8,3 +8,16 @@ console.error(""); // bidi override
|
|||||||
console.log(1);
|
console.log(1);
|
||||||
|
|
||||||
console.test();
|
console.test();
|
||||||
|
|
||||||
|
console.error("{}", x);
|
||||||
|
|
||||||
|
console.error("{}{}", x, y);
|
||||||
|
|
||||||
|
console.error("x");
|
||||||
|
|
||||||
|
|
||||||
|
console.log("{}", x);
|
||||||
|
|
||||||
|
console.log("{}{}", x, y);
|
||||||
|
|
||||||
|
console.log("x");
|
||||||
|
Loading…
Reference in New Issue
Block a user