Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(experimental): Improve variable not defined error message in comptime interpreter #4889

Merged
merged 34 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
237418f
Add Hir -> Ast conversion
jfecher Apr 10, 2024
88fbae4
Move file
jfecher Apr 11, 2024
d4512ac
Add Hir -> Ast pass
jfecher Apr 11, 2024
dd05c5f
Merge branch 'master' into jf/hir-to-ast
jfecher Apr 12, 2024
064a074
Add weird attributes field even though it was compiling locally witho…
jfecher Apr 12, 2024
99b7839
Start work on interpreter
jfecher Apr 12, 2024
2232793
Evaluate if exprs
jfecher Apr 12, 2024
1c649e5
Update interpreter
jfecher Apr 15, 2024
b5bdb9c
Start evaluating statements
jfecher Apr 15, 2024
65a0da9
Fix compiler errors
jfecher Apr 15, 2024
9d5517b
Implement loops
jfecher Apr 15, 2024
9a31f68
Finish each node; still needs cleanup & testing
jfecher Apr 15, 2024
4247e89
Fix mutation after scopes were added
jfecher Apr 16, 2024
7121ec7
Implement function scopes
jfecher Apr 16, 2024
65fc2e1
clippy
jfecher Apr 16, 2024
20ac4e9
Merge branch 'master' into jf/interpreter
jfecher Apr 16, 2024
2bf6ea7
Add comptime expression & statement
jfecher Apr 17, 2024
a901d8f
Add comptime hir node
jfecher Apr 17, 2024
3443545
Handle comptime node in comptime module
jfecher Apr 18, 2024
55c28b4
Add case to tooling
jfecher Apr 18, 2024
3d08598
Merge branch 'master' into jf/comptime
jfecher Apr 18, 2024
9ebf902
Fix merge
jfecher Apr 18, 2024
4e4f9fd
Add missed case
jfecher Apr 18, 2024
824c4b2
Remove comptime from parse tests
jfecher Apr 18, 2024
63fdb4a
Add scanning pass
jfecher Apr 18, 2024
e376121
Refactor name resolution a bit
jfecher Apr 19, 2024
65f6513
Add into_expression
jfecher Apr 22, 2024
11a6acd
Finish fleshing out into_expression
jfecher Apr 22, 2024
b39f42b
Fix many many merge conflicts
jfecher Apr 22, 2024
a4e596e
fmt
jfecher Apr 22, 2024
7e75b64
Code review
jfecher Apr 23, 2024
522867b
Improve error slightly
jfecher Apr 23, 2024
95b6a19
Merge branch 'master' into jf/comptime-checked
jfecher Apr 23, 2024
47ef177
Finish missed CompTime -> Comptime cases
jfecher Apr 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions compiler/noirc_frontend/src/ast/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub enum ExpressionKind {
Lambda(Box<Lambda>),
Parenthesized(Box<Expression>),
Quote(BlockExpression),
CompTime(BlockExpression),
Error,
}

Expand Down Expand Up @@ -504,6 +505,7 @@ impl Display for ExpressionKind {
Lambda(lambda) => lambda.fmt(f),
Parenthesized(sub_expr) => write!(f, "({sub_expr})"),
Quote(block) => write!(f, "quote {block}"),
CompTime(block) => write!(f, "comptime {block}"),
Error => write!(f, "Error"),
}
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/noirc_frontend/src/ast/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub enum StatementKind {
Break,
Continue,
/// This statement should be executed at compile-time
Comptime(Box<StatementKind>),
CompTime(Box<StatementKind>),
// This is an expression with a trailing semi-colon
Semi(Expression),
// This statement is the result of a recovered parse error.
Expand Down Expand Up @@ -87,10 +87,10 @@ impl StatementKind {
}
self
}
StatementKind::Comptime(mut statement) => {
StatementKind::CompTime(mut statement) => {
*statement =
statement.add_semicolon(semi, span, last_statement_in_block, emit_error);
StatementKind::Comptime(statement)
StatementKind::CompTime(statement)
}
// A semicolon on a for loop is optional and does nothing
StatementKind::For(_) => self,
Expand Down Expand Up @@ -685,7 +685,7 @@ impl Display for StatementKind {
StatementKind::For(for_loop) => for_loop.fmt(f),
StatementKind::Break => write!(f, "break"),
StatementKind::Continue => write!(f, "continue"),
StatementKind::Comptime(statement) => write!(f, "comptime {statement}"),
StatementKind::CompTime(statement) => write!(f, "comptime {statement}"),
StatementKind::Semi(semi) => write!(f, "{semi};"),
StatementKind::Error => write!(f, "Error"),
}
Expand Down
54 changes: 54 additions & 0 deletions compiler/noirc_frontend/src/hir/comptime/errors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::Type;
use acvm::FieldElement;
use noirc_errors::Location;

use super::value::Value;

/// The possible errors that can halt the interpreter.
#[allow(unused)]
#[derive(Debug)]
pub(crate) enum InterpreterError {
ArgumentCountMismatch { expected: usize, actual: usize, call_location: Location },
TypeMismatch { expected: Type, value: Value, location: Location },
NonCompTimeVarReferenced { name: String, location: Location },
IntegerOutOfRangeForType { value: FieldElement, typ: Type, location: Location },
ErrorNodeEncountered { location: Location },
NonFunctionCalled { value: Value, location: Location },
NonBoolUsedInIf { value: Value, location: Location },
NonBoolUsedInConstrain { value: Value, location: Location },
FailingConstraint { message: Option<Value>, location: Location },
NoMethodFound { object: Value, typ: Type, location: Location },
NonIntegerUsedInLoop { value: Value, location: Location },
NonPointerDereferenced { value: Value, location: Location },
NonTupleOrStructInMemberAccess { value: Value, location: Location },
NonArrayIndexed { value: Value, location: Location },
NonIntegerUsedAsIndex { value: Value, location: Location },
NonIntegerIntegerLiteral { typ: Type, location: Location },
NonIntegerArrayLength { typ: Type, location: Location },
NonNumericCasted { value: Value, location: Location },
IndexOutOfBounds { index: usize, length: usize, location: Location },
ExpectedStructToHaveField { value: Value, field_name: String, location: Location },
TypeUnsupported { typ: Type, location: Location },
InvalidValueForUnary { value: Value, operator: &'static str, location: Location },
InvalidValuesForBinary { lhs: Value, rhs: Value, operator: &'static str, location: Location },
CastToNonNumericType { typ: Type, location: Location },
QuoteInRuntimeCode { location: Location },
NonStructInConstructor { typ: Type, location: Location },
CannotInlineMacro { value: Value, location: Location },
UnquoteFoundDuringEvaluation { location: Location },

Unimplemented { item: &'static str, location: Location },

// Perhaps this should be unreachable! due to type checking also preventing this error?
// Currently it and the Continue variant are the only interpreter errors without a Location field
BreakNotInLoop { location: Location },
ContinueNotInLoop { location: Location },

// These cases are not errors, they are just used to prevent us from running more code
// until the loop can be resumed properly. These cases will never be displayed to users.
Break,
Continue,
}

#[allow(unused)]
pub(super) type IResult<T> = std::result::Result<T, InterpreterError>;
26 changes: 17 additions & 9 deletions compiler/noirc_frontend/src/hir/comptime/hir_to_ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::ast::{
UnresolvedTypeData, UnresolvedTypeExpression,
};
use crate::ast::{ConstrainStatement, Expression, Statement, StatementKind};
use crate::hir_def::expr::{HirArrayLiteral, HirExpression, HirIdent};
use crate::hir_def::expr::{HirArrayLiteral, HirBlockExpression, HirExpression, HirIdent};
use crate::hir_def::stmt::{HirLValue, HirPattern, HirStatement};
use crate::hir_def::types::Type;
use crate::macros_api::HirLiteral;
Expand All @@ -26,7 +26,7 @@ impl StmtId {
#[allow(unused)]
fn to_ast(self, interner: &NodeInterner) -> Statement {
let statement = interner.statement(&self);
let span = interner.statement_span(&self);
let span = interner.statement_span(self);

let kind = match statement {
HirStatement::Let(let_stmt) => {
Expand Down Expand Up @@ -66,8 +66,8 @@ impl StmtId {
HirStatement::Expression(expr) => StatementKind::Expression(expr.to_ast(interner)),
HirStatement::Semi(expr) => StatementKind::Semi(expr.to_ast(interner)),
HirStatement::Error => StatementKind::Error,
HirStatement::Comptime(statement) => {
StatementKind::Comptime(Box::new(statement.to_ast(interner).kind))
HirStatement::CompTime(statement) => {
StatementKind::CompTime(Box::new(statement.to_ast(interner).kind))
}
};

Expand Down Expand Up @@ -108,10 +108,7 @@ impl ExprId {
ExpressionKind::Literal(Literal::FmtStr(string))
}
HirExpression::Literal(HirLiteral::Unit) => ExpressionKind::Literal(Literal::Unit),
HirExpression::Block(expr) => {
let statements = vecmap(expr.statements, |statement| statement.to_ast(interner));
ExpressionKind::Block(BlockExpression { statements })
}
HirExpression::Block(expr) => ExpressionKind::Block(expr.into_ast(interner)),
HirExpression::Prefix(prefix) => ExpressionKind::Prefix(Box::new(PrefixExpression {
operator: prefix.operator,
rhs: prefix.rhs.to_ast(interner),
Expand Down Expand Up @@ -172,8 +169,12 @@ impl ExprId {
let body = lambda.body.to_ast(interner);
ExpressionKind::Lambda(Box::new(Lambda { parameters, return_type, body }))
}
HirExpression::Quote(block) => ExpressionKind::Quote(block),
HirExpression::Error => ExpressionKind::Error,
HirExpression::CompTime(block) => ExpressionKind::CompTime(block.into_ast(interner)),
HirExpression::Quote(block) => ExpressionKind::Quote(block),

// A macro was evaluated here!
HirExpression::Unquote(block) => ExpressionKind::Block(block),
};

Expression::new(kind, span)
Expand Down Expand Up @@ -353,3 +354,10 @@ impl HirArrayLiteral {
}
}
}

impl HirBlockExpression {
fn into_ast(self, interner: &NodeInterner) -> BlockExpression {
let statements = vecmap(self.statements, |statement| statement.to_ast(interner));
BlockExpression { statements }
}
}
Loading
Loading