add dynamic check errors for circuits 3

This commit is contained in:
collin 2020-10-24 19:27:30 -07:00
parent 6e124e52ff
commit 17a65fe54a
5 changed files with 48 additions and 15 deletions

View File

@ -161,17 +161,17 @@ fn test_mutate_self_variable_fail() {
#[test]
fn test_mutate_self_function_fail() {
let bytes = include_bytes!("mut_self_function_fail.leo");
let program = parse_program(bytes).unwrap();
let error = parse_program(bytes).err().unwrap();
expect_compiler_error(program);
expect_dynamic_check_error(error);
}
#[test]
fn test_mutate_self_static_function_fail() {
let bytes = include_bytes!("mut_self_static_function_fail.leo");
let program = parse_program(bytes).unwrap();
let error = parse_program(bytes).err().unwrap();
expect_compiler_error(program);
expect_dynamic_check_error(error);
}
#[test]
@ -227,9 +227,9 @@ fn test_self_member_invalid() {
#[test]
fn test_self_member_undefined() {
let bytes = include_bytes!("self_member_undefined.leo");
let program = parse_program(bytes).unwrap();
let error = parse_program(bytes).err().unwrap();
let _err = expect_compiler_error(program);
expect_dynamic_check_error(error);
}
// All

View File

@ -57,8 +57,6 @@ pub struct DynamicCheck {
frames: Vec<Frame>,
}
pub struct VariableEnvironment {}
impl DynamicCheck {
///
/// Creates a new `DynamicCheck` from a given program and symbol table.
@ -89,20 +87,27 @@ impl DynamicCheck {
/// Collects a vector of `TypeAssertion` predicates from a program.
///
fn parse_program(&mut self, program: &Program) -> Result<(), DynamicCheckError> {
// Parse program input keyword as a circuit type.
// let input_type = CircuitType::from_input()
// Iterate over circuit types.
let circuits = program
.circuits
.iter()
.map(|(_identifier, circuit)| circuit)
.collect::<Vec<_>>();
// Parse circuit types in program context.
self.parse_circuits(circuits)?;
// Iterate over functions.
let functions = program
.functions
.iter()
.map(|(_identifier, function)| function)
.collect::<Vec<_>>();
// Parse functions in program context.
self.parse_functions(functions)
}
@ -334,8 +339,6 @@ impl Frame {
fn assert_equal(&mut self, left: Type, right: Type, span: &Span) {
let type_assertion = TypeAssertion::new_equality(left, right, span);
println!("equality: {:?}", type_assertion);
self.type_assertions.push(type_assertion);
}
@ -502,7 +505,17 @@ impl Frame {
///
fn parse_assignee(&mut self, assignee: &Assignee, span: &Span) -> Result<Type, FrameError> {
// Get the type of the assignee variable.
let mut type_ = self.get_variable(&assignee.identifier.name).unwrap().to_owned();
let mut type_ = if assignee.identifier.is_self() {
// If the variable is the self keyword, then return the self.circuit_type
let self_type = self.self_type_or_error(span)?;
Type::Circuit(self_type.identifier)
} else {
// Otherwise, lookup the variable by name in the symbol table.
self.get_variable(&assignee.identifier.name)
.map(|type_| type_.to_owned())
.ok_or_else(|| FrameError::undefined_variable(&assignee.identifier))?
};
// Iteratively evaluate assignee access types.
for access in &assignee.accesses {
@ -697,7 +710,7 @@ impl Frame {
///
fn parse_identifier(&self, identifier: &Identifier) -> Result<Type, FrameError> {
// Check Self type.
if identifier.is_self_type() {
if identifier.is_self() {
// Check for frame circuit self type.
let circuit_type = self.self_type_or_error(&identifier.span)?;
@ -1037,6 +1050,8 @@ impl Frame {
.ok_or_else(|| FrameError::undefined_circuit(identifier))?
};
println!("circuit_type: {:?}", circuit_type);
// Check the length of the circuit members.
if circuit_type.variables.len() != members.len() {
return Err(FrameError::num_variables(
@ -1055,7 +1070,7 @@ impl Frame {
self.assert_equal(expected_variable.type_.clone(), actual_type, span)
}
Ok(Type::Circuit(identifier.to_owned()))
Ok(Type::Circuit(circuit_type.identifier))
}
///

View File

@ -130,4 +130,13 @@ impl FrameError {
Self::new_from_span(message, identifier.span.to_owned())
}
///
/// Attempted to call a variable that is not defined in the current context.
///
pub fn undefined_variable(identifier: &Identifier) -> Self {
let message = format!("The variable `{}` is not defined.", identifier);
Self::new_from_span(message, identifier.span.to_owned())
}
}

View File

@ -22,7 +22,7 @@ use crate::{
Type,
TypeError,
};
use leo_typed::{Circuit, CircuitMember, Identifier};
use leo_typed::{Circuit, CircuitMember, Identifier, Input};
use serde::{Deserialize, Serialize};
@ -141,4 +141,13 @@ impl CircuitType {
}
}
}
// ///
// /// Returns a new `CircuitType` from a given `Input` struct.
// ///
// pub fn from_input(input: &Input) -> Self {
// // Get definitions for each input variable.
//
// // Create a new `CircuitType` for each
// }
}

View File

@ -73,7 +73,7 @@ impl Input {
Ok(())
}
/// Parse all input variables included in a file and store them in `self`.
/// Parse all state variables included in a file and store them in `self`.
pub fn parse_state(&mut self, file: File) -> Result<(), InputParserError> {
for entry in file.entries.into_iter() {
match entry {