|
|
@@ -95,9 +95,11 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- x => {
|
|
|
- self.error.emit(format!("Unknown `{}` proof section", x), t.line, t.column)
|
|
|
- }
|
|
|
+ x => self.error.abort(
|
|
|
+ &format!("Unknown `{}` proof section", x),
|
|
|
+ t.line,
|
|
|
+ t.column,
|
|
|
+ ),
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -118,8 +120,8 @@ impl Parser {
|
|
|
|
|
|
// TODO: Do we need this?
|
|
|
if namespace_found && namespace != constant_tokens[0].token {
|
|
|
- self.error.emit(
|
|
|
- format!(
|
|
|
+ self.error.abort(
|
|
|
+ &format!(
|
|
|
"Found `{}` namespace. Expected `{}`.",
|
|
|
constant_tokens[0].token, namespace
|
|
|
),
|
|
|
@@ -138,16 +140,12 @@ impl Parser {
|
|
|
|
|
|
while let Some((typ, name, comma)) = constants_inner.next_tuple() {
|
|
|
if comma.token_type != TokenType::Comma {
|
|
|
- self.error.emit(
|
|
|
- "Separator is not a comma".to_string(),
|
|
|
- comma.line,
|
|
|
- comma.column,
|
|
|
- );
|
|
|
+ self.error.abort("Separator is not a comma", comma.line, comma.column);
|
|
|
}
|
|
|
|
|
|
if constants_map.contains_key(name.token.as_str()) {
|
|
|
- self.error.emit(
|
|
|
- format!(
|
|
|
+ self.error.abort(
|
|
|
+ &format!(
|
|
|
"Section `constant` already contains the token `{}`.",
|
|
|
&name.token
|
|
|
),
|
|
|
@@ -168,8 +166,8 @@ impl Parser {
|
|
|
|
|
|
// TODO: Do we need this?
|
|
|
if namespace_found && namespace != contract_tokens[0].token {
|
|
|
- self.error.emit(
|
|
|
- format!(
|
|
|
+ self.error.abort(
|
|
|
+ &format!(
|
|
|
"Found `{}` namespace. Expected `{}`.",
|
|
|
contract_tokens[0].token, namespace
|
|
|
),
|
|
|
@@ -188,16 +186,12 @@ impl Parser {
|
|
|
|
|
|
while let Some((typ, name, comma)) = contract_inner.next_tuple() {
|
|
|
if comma.token_type != TokenType::Comma {
|
|
|
- self.error.emit(
|
|
|
- "Separator is not a comma".to_string(),
|
|
|
- comma.line,
|
|
|
- comma.column,
|
|
|
- );
|
|
|
+ self.error.abort("Separator is not a comma", comma.line, comma.column);
|
|
|
}
|
|
|
|
|
|
if contract_map.contains_key(name.token.as_str()) {
|
|
|
- self.error.emit(
|
|
|
- format!(
|
|
|
+ self.error.abort(
|
|
|
+ &format!(
|
|
|
"Section `contract` already contains the token `{}`.",
|
|
|
&name.token
|
|
|
),
|
|
|
@@ -217,8 +211,8 @@ impl Parser {
|
|
|
self.check_section_structure("circuit", contract_tokens.clone());
|
|
|
|
|
|
if circuit_tokens[circuit_tokens.len() - 2].token_type != TokenType::Semicolon {
|
|
|
- self.error.emit(
|
|
|
- "Circuit section does not end with a semicolon. Would never finish parsing.".to_string(),
|
|
|
+ self.error.abort(
|
|
|
+ "Circuit section does not end with a semicolon. Would never finish parsing.",
|
|
|
circuit_tokens[circuit_tokens.len()-2].line,
|
|
|
circuit_tokens[circuit_tokens.len()-2].column
|
|
|
);
|
|
|
@@ -226,8 +220,8 @@ impl Parser {
|
|
|
|
|
|
// TODO: Do we need this?
|
|
|
if namespace_found && namespace != circuit_tokens[0].token {
|
|
|
- self.error.emit(
|
|
|
- format!(
|
|
|
+ self.error.abort(
|
|
|
+ &format!(
|
|
|
"Found `{}` namespace. Expected `{}`.",
|
|
|
circuit_tokens[0].token, namespace
|
|
|
),
|
|
|
@@ -254,37 +248,56 @@ impl Parser {
|
|
|
}
|
|
|
|
|
|
ast.insert(namespace.clone(), ast_inner);
|
|
|
- // TODO: Verify there are both constant/contract sections
|
|
|
- // TODO: Verify there is a circuit section
|
|
|
// TODO: Check that there are no duplicate names in constants, contract
|
|
|
// and circuit assignments
|
|
|
|
|
|
// Clean up the `constant` section
|
|
|
- let c = ast.get(&namespace).unwrap().get("constant").unwrap();
|
|
|
+ let c = match ast.get(&namespace).unwrap().get("constant") {
|
|
|
+ Some(c) => c,
|
|
|
+ None => {
|
|
|
+ self.error.abort("Missing `constant` section in .zk source", 0, 0);
|
|
|
+ unreachable!()
|
|
|
+ }
|
|
|
+ };
|
|
|
let constants = self.parse_ast_constants(c);
|
|
|
+ if constants.is_empty() {
|
|
|
+ self.error.warn("Constant section is empty", 0, 0);
|
|
|
+ }
|
|
|
|
|
|
// Clean up the `contract` section
|
|
|
- let c = ast.get(&namespace).unwrap().get("contract").unwrap();
|
|
|
+ let c = match ast.get(&namespace).unwrap().get("contract") {
|
|
|
+ Some(c) => c,
|
|
|
+ None => {
|
|
|
+ self.error.abort("Missing `contract` section in .zk source", 0, 0);
|
|
|
+ unreachable!()
|
|
|
+ }
|
|
|
+ };
|
|
|
let witnesses = self.parse_ast_contract(c);
|
|
|
+ if witnesses.is_empty() {
|
|
|
+ self.error.abort("Contract section is empty", 0, 0);
|
|
|
+ }
|
|
|
|
|
|
// Clean up the `circuit` section
|
|
|
let stmt = self.parse_ast_circuit(circuit_statements);
|
|
|
+ if stmt.is_empty() {
|
|
|
+ self.error.abort("Circuit section is empty", 0, 0);
|
|
|
+ }
|
|
|
|
|
|
(constants, witnesses, stmt)
|
|
|
}
|
|
|
|
|
|
fn check_section_structure(&self, section: &str, tokens: Vec<Token>) {
|
|
|
if tokens[0].token_type != TokenType::String {
|
|
|
- self.error.emit(
|
|
|
- format!("{} section declaration must start with a naming string.", section),
|
|
|
+ self.error.abort(
|
|
|
+ &format!("{} section declaration must start with a naming string.", section),
|
|
|
tokens[0].line,
|
|
|
tokens[0].column,
|
|
|
);
|
|
|
}
|
|
|
|
|
|
if tokens[1].token_type != TokenType::LeftBrace {
|
|
|
- self.error.emit(
|
|
|
- format!(
|
|
|
+ self.error.abort(
|
|
|
+ &format!(
|
|
|
"{} section opening is not correct. Must be opened with a left brace `{{`",
|
|
|
section
|
|
|
),
|
|
|
@@ -294,8 +307,8 @@ impl Parser {
|
|
|
}
|
|
|
|
|
|
if tokens[tokens.len() - 1].token_type != TokenType::RightBrace {
|
|
|
- self.error.emit(
|
|
|
- format!(
|
|
|
+ self.error.abort(
|
|
|
+ &format!(
|
|
|
"{} section closing is not correct. Must be closed with a right brace `}}`",
|
|
|
section
|
|
|
),
|
|
|
@@ -307,8 +320,8 @@ impl Parser {
|
|
|
if (section == "constant" || section == "contract") &&
|
|
|
tokens[2..tokens.len() - 1].len() % 3 != 0
|
|
|
{
|
|
|
- self.error.emit(
|
|
|
- format!(
|
|
|
+ self.error.abort(
|
|
|
+ &format!(
|
|
|
"Invalid number of elements in `{}` section. Must be pairs of `type:name` separated with a comma `,`",
|
|
|
section
|
|
|
),
|
|
|
@@ -323,24 +336,24 @@ impl Parser {
|
|
|
|
|
|
for (k, v) in ast {
|
|
|
if &v.0.token != k {
|
|
|
- self.error.emit(
|
|
|
- format!("Constant name `{}` doesn't match token `{}`.", v.0.token, k),
|
|
|
+ self.error.abort(
|
|
|
+ &format!("Constant name `{}` doesn't match token `{}`.", v.0.token, k),
|
|
|
v.0.line,
|
|
|
v.0.column,
|
|
|
);
|
|
|
}
|
|
|
|
|
|
if v.0.token_type != TokenType::Symbol {
|
|
|
- self.error.emit(
|
|
|
- format!("Constant name `{}` is not a symbol.", v.0.token),
|
|
|
+ self.error.abort(
|
|
|
+ &format!("Constant name `{}` is not a symbol.", v.0.token),
|
|
|
v.0.line,
|
|
|
v.0.column,
|
|
|
);
|
|
|
}
|
|
|
|
|
|
if v.1.token_type != TokenType::Symbol {
|
|
|
- self.error.emit(
|
|
|
- format!("Constant type `{}` is not a symbol.", v.1.token),
|
|
|
+ self.error.abort(
|
|
|
+ &format!("Constant type `{}` is not a symbol.", v.1.token),
|
|
|
v.1.line,
|
|
|
v.1.column,
|
|
|
);
|
|
|
@@ -375,8 +388,8 @@ impl Parser {
|
|
|
}
|
|
|
|
|
|
x => {
|
|
|
- self.error.emit(
|
|
|
- format!("`{}` is an illegal constant type", x),
|
|
|
+ self.error.abort(
|
|
|
+ &format!("`{}` is an illegal constant type", x),
|
|
|
v.1.line,
|
|
|
v.1.column,
|
|
|
);
|
|
|
@@ -392,24 +405,24 @@ impl Parser {
|
|
|
|
|
|
for (k, v) in ast {
|
|
|
if &v.0.token != k {
|
|
|
- self.error.emit(
|
|
|
- format!("Witness name `{}` doesn't match token `{}`.", v.0.token, k),
|
|
|
+ self.error.abort(
|
|
|
+ &format!("Witness name `{}` doesn't match token `{}`.", v.0.token, k),
|
|
|
v.0.line,
|
|
|
v.0.column,
|
|
|
);
|
|
|
}
|
|
|
|
|
|
if v.0.token_type != TokenType::Symbol {
|
|
|
- self.error.emit(
|
|
|
- format!("Witness name `{}` is not a symbol.", v.0.token),
|
|
|
+ self.error.abort(
|
|
|
+ &format!("Witness name `{}` is not a symbol.", v.0.token),
|
|
|
v.0.line,
|
|
|
v.0.column,
|
|
|
);
|
|
|
}
|
|
|
|
|
|
if v.1.token_type != TokenType::Symbol {
|
|
|
- self.error.emit(
|
|
|
- format!("Witness type `{}` is not a symbol.", v.1.token),
|
|
|
+ self.error.abort(
|
|
|
+ &format!("Witness type `{}` is not a symbol.", v.1.token),
|
|
|
v.1.line,
|
|
|
v.1.column,
|
|
|
);
|
|
|
@@ -462,8 +475,8 @@ impl Parser {
|
|
|
}
|
|
|
|
|
|
x => {
|
|
|
- self.error.emit(
|
|
|
- format!("`{}` is an illegal witness type", x),
|
|
|
+ self.error.abort(
|
|
|
+ &format!("`{}` is an illegal witness type", x),
|
|
|
v.1.line,
|
|
|
v.1.column,
|
|
|
);
|
|
|
@@ -487,8 +500,8 @@ impl Parser {
|
|
|
}
|
|
|
}
|
|
|
if left_paren != right_paren {
|
|
|
- self.error.emit(
|
|
|
- "Incorrect number of left and right parenthesis for statement.".to_string(),
|
|
|
+ self.error.abort(
|
|
|
+ "Incorrect number of left and right parenthesis for statement.",
|
|
|
statement[0].line,
|
|
|
statement[0].column,
|
|
|
);
|
|
|
@@ -534,8 +547,8 @@ impl Parser {
|
|
|
}
|
|
|
|
|
|
if !parsing {
|
|
|
- self.error.emit(
|
|
|
- format!("Illegal token `{}`", next_token.token),
|
|
|
+ self.error.abort(
|
|
|
+ &format!("Illegal token `{}`", next_token.token),
|
|
|
next_token.line,
|
|
|
next_token.column,
|
|
|
);
|
|
|
@@ -616,8 +629,8 @@ impl Parser {
|
|
|
}
|
|
|
|
|
|
x => {
|
|
|
- self.error.emit(
|
|
|
- format!("Unimplemented function call `{}`", x),
|
|
|
+ self.error.abort(
|
|
|
+ &format!("Unimplemented function call `{}`", x),
|
|
|
token.line,
|
|
|
token.column,
|
|
|
);
|
|
|
@@ -637,8 +650,8 @@ impl Parser {
|
|
|
) -> Vec<Variable> {
|
|
|
if let Some(next_token) = iter.peek() {
|
|
|
if next_token.token_type != TokenType::LeftParen {
|
|
|
- self.error.emit(
|
|
|
- "Invalid function call opening. Must start with a `(`".to_string(),
|
|
|
+ self.error.abort(
|
|
|
+ "Invalid function call opening. Must start with a `(`",
|
|
|
next_token.line,
|
|
|
next_token.column,
|
|
|
);
|
|
|
@@ -646,7 +659,7 @@ impl Parser {
|
|
|
// Skip the opening parenthesis
|
|
|
iter.next();
|
|
|
} else {
|
|
|
- self.error.emit("Premature ending of statement".to_string(), token.line, token.column);
|
|
|
+ self.error.abort("Premature ending of statement", token.line, token.column);
|
|
|
}
|
|
|
|
|
|
// Eat up function arguments
|
|
|
@@ -665,11 +678,7 @@ impl Parser {
|
|
|
}
|
|
|
|
|
|
if sep.token_type != TokenType::Comma {
|
|
|
- self.error.emit(
|
|
|
- "Argument separator is not a comma (`,`)".to_string(),
|
|
|
- sep.line,
|
|
|
- sep.column,
|
|
|
- );
|
|
|
+ self.error.abort("Argument separator is not a comma (`,`)", sep.line, sep.column);
|
|
|
}
|
|
|
}
|
|
|
|