compiler successfully parsing record, registers, state, state_leaf variables with access

This commit is contained in:
collin 2020-07-29 00:18:19 -07:00
parent d5ac5e6709
commit 3d3e8f5e72
26 changed files with 432 additions and 127 deletions

View File

@ -9,7 +9,7 @@ use crate::{
};
use leo_ast::LeoParser;
use leo_inputs::LeoInputsParser;
use leo_types::{InputValue, Inputs, MainInputs, Program};
use leo_types::{Inputs, MainInputs, Program};
use snarkos_errors::gadgets::SynthesisError;
use snarkos_models::{
@ -70,6 +70,34 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
self.program_inputs.set_main_inputs(program_inputs);
}
fn load_program(&mut self) -> Result<String, CompilerError> {
// Load the program syntax tree from the file path
Ok(LeoParser::load_file(&self.main_file_path)?)
}
pub fn parse_program(&mut self, program_string: &str) -> Result<(), CompilerError> {
// Parse the program syntax tree
let syntax_tree = LeoParser::parse_file(&self.main_file_path, program_string)?;
// Build program from syntax tree
let package_name = self.package_name.clone();
self.program = Program::from(syntax_tree, package_name);
self.imported_programs = ImportParser::parse(&self.program)?;
log::debug!("Program parsing complete\n{:#?}", self.program);
Ok(())
}
pub fn parse_inputs(&mut self, inputs_string: &str) -> Result<(), CompilerError> {
let syntax_tree = LeoInputsParser::parse_file(&inputs_string)?;
self.program_inputs.parse(syntax_tree)?;
Ok(())
}
pub fn checksum(&self) -> Result<String, CompilerError> {
// Read in the main file as string
let unparsed_file = fs::read_to_string(&self.main_file_path)
@ -101,41 +129,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> Compiler<F, G> {
generate_test_constraints::<F, G>(cs, self.program, self.program_inputs, &self.imported_programs)
}
fn load_program(&mut self) -> Result<String, CompilerError> {
// Load the program syntax tree from the file path
Ok(LeoParser::load_file(&self.main_file_path)?)
}
pub fn parse_program(&mut self, program_string: &str) -> Result<(), CompilerError> {
// Parse the program syntax tree
let syntax_tree = LeoParser::parse_file(&self.main_file_path, program_string)?;
// Build program from syntax tree
let package_name = self.package_name.clone();
self.program = Program::from(syntax_tree, package_name);
self.imported_programs = ImportParser::parse(&self.program)?;
log::debug!("Program parsing complete\n{:#?}", self.program);
Ok(())
}
pub fn parse_inputs(&mut self, inputs_string: &str) -> Result<(), CompilerError> {
let syntax_tree = LeoInputsParser::parse_file(&inputs_string)?;
self.program_inputs.parse(syntax_tree)?;
Ok(())
}
pub fn to_bytes(&self) -> Result<Vec<u8>, CompilerError> {
Ok(bincode::serialize(&self.program)?)
}
pub fn from_bytes(bytes: &[u8]) -> Result<Self, CompilerError> {
let program: Program = bincode::deserialize(bytes)?;
let mut program_inputs = Inputs::new();
let program_inputs = Inputs::new();
Ok(Self {
package_name: program.name.clone(),

View File

@ -78,4 +78,10 @@ impl FunctionError {
Self::new_from_span(message, span)
}
pub fn input_not_found(expected: String, span: Span) -> Self {
let message = format!("main function input {} not found", expected);
Self::new_from_span(message, span)
}
}

View File

@ -39,28 +39,77 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// Store input values as new variables in resolved program
for (input_model, input_expression) in function.inputs.clone().iter().zip(inputs.into_iter()) {
if let Input::FunctionInput(input_model) = input_model {
// First evaluate input expression
let mut input_value = self.enforce_input(
cs,
scope.clone(),
caller_scope.clone(),
function_name.clone(),
vec![input_model.type_.clone()],
input_expression,
)?;
let (name, value) = match input_model {
Input::FunctionInput(input_model) => {
// First evaluate input expression
let mut input_value = self.enforce_input(
cs,
scope.clone(),
caller_scope.clone(),
function_name.clone(),
vec![input_model.type_.clone()],
input_expression,
)?;
if input_model.mutable {
input_value = ConstrainedValue::Mutable(Box::new(input_value))
if input_model.mutable {
input_value = ConstrainedValue::Mutable(Box::new(input_value))
}
(input_model.identifier.name.clone(), input_value)
}
Input::Registers(identifier) => {
let input_value = self.enforce_input(
cs,
scope.clone(),
caller_scope.clone(),
function_name.clone(),
vec![],
input_expression,
)?;
// Store input as variable with {function_name}_{input_name}
let input_program_identifier = new_scope(function_name.clone(), input_model.identifier.name.clone());
self.store(input_program_identifier, input_value);
} else {
println!("function input model {}", input_model);
println!("function input option {}", input_expression)
}
(identifier.name.clone(), input_value)
}
Input::Record(identifier) => {
let input_value = self.enforce_input(
cs,
scope.clone(),
caller_scope.clone(),
function_name.clone(),
vec![],
input_expression,
)?;
(identifier.name.clone(), input_value)
}
Input::State(identifier) => {
let input_value = self.enforce_input(
cs,
scope.clone(),
caller_scope.clone(),
function_name.clone(),
vec![],
input_expression,
)?;
(identifier.name.clone(), input_value)
}
Input::StateLeaf(identifier) => {
let input_value = self.enforce_input(
cs,
scope.clone(),
caller_scope.clone(),
function_name.clone(),
vec![],
input_expression,
)?;
(identifier.name.clone(), input_value)
}
};
// Store input as variable with {function_name}_{input_name}
let input_program_identifier = new_scope(function_name.clone(), name);
self.store(input_program_identifier, value);
}
// Evaluate every statement in the function and save all potential results

View File

@ -8,3 +8,6 @@ pub use self::input::*;
pub mod main_input;
pub use self::main_input::*;
pub mod section;
pub use self::section::*;

View File

@ -0,0 +1,37 @@
use crate::{errors::FunctionError, ConstrainedCircuitMember, ConstrainedProgram, ConstrainedValue, GroupType};
use leo_types::{Identifier, InputValue, Parameter};
use snarkos_models::{
curves::{Field, PrimeField},
gadgets::r1cs::ConstraintSystem,
};
use std::collections::HashMap;
impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
pub fn allocate_input_section<CS: ConstraintSystem<F>>(
&mut self,
cs: &mut CS,
identifier: Identifier,
section: HashMap<Parameter, Option<InputValue>>,
) -> Result<ConstrainedValue<F, G>, FunctionError> {
let mut members = vec![];
// Store each section definition as a circuit member value
for (parameter, option) in section.into_iter() {
let member_name = parameter.variable.clone();
let member_value = self.allocate_main_function_input(
cs,
parameter.type_,
parameter.variable.name,
option,
parameter.span,
)?;
let member = ConstrainedCircuitMember(member_name, member_value);
members.push(member)
}
// Return section as circuit expression
Ok(ConstrainedValue::CircuitExpression(identifier, members))
}
}

View File

@ -30,12 +30,13 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
// Iterate over main function inputs and allocate new passed-by variable values
let mut input_variables = vec![];
let mut seen = 0;
for (i, input_model) in function.inputs.clone().into_iter().enumerate() {
match input_model {
for input_model in function.inputs.clone().into_iter() {
let (identifier, value) = match input_model {
Input::FunctionInput(input_model) => {
let name = input_model.identifier.name.clone();
let input_option = inputs.get(&name);
let input_option = inputs
.get(&name)
.ok_or(FunctionError::input_not_found(name.clone(), function.span.clone()))?;
let input_value = self.allocate_main_function_input(
cs,
input_model.type_,
@ -44,25 +45,41 @@ impl<F: Field + PrimeField, G: GroupType<F>> ConstrainedProgram<F, G> {
function.span.clone(),
)?;
// Store a new variable for every allocated main function input
let input_name = new_scope(function_name.clone(), input_model.identifier.name.clone());
self.store(input_name.clone(), input_value);
(input_model.identifier, input_value)
}
Input::Registers(identifier) => {
let section = inputs.get_registers();
let value = self.allocate_input_section(cs, identifier.clone(), section)?;
input_variables.push(Expression::Identifier(input_model.identifier));
(identifier, value)
}
Input::Registers => {
seen += 1;
Input::Record(identifier) => {
let section = inputs.get_record();
let value = self.allocate_input_section(cs, identifier.clone(), section)?;
(identifier, value)
}
Input::Record => {
seen += 1;
Input::State(identifier) => {
let section = inputs.get_state();
let value = self.allocate_input_section(cs, identifier.clone(), section)?;
(identifier, value)
}
Input::State => {
seen += 1;
Input::StateLeaf(identifier) => {
let section = inputs.get_state_leaf();
let value = self.allocate_input_section(cs, identifier.clone(), section)?;
(identifier, value)
}
Input::StateLeaf => {
seen += 1;
}
}
};
// Store input as variable with {function_name}_{identifier_name}
let input_name = new_scope(function_name.clone(), identifier.name.clone());
// Store a new variable for every allocated main function input
self.store(input_name, value);
input_variables.push(Expression::Identifier(identifier));
}
self.enforce_function(cs, scope, function_name, function, input_variables)

View File

@ -3,7 +3,7 @@ use crate::{
cli_types::*,
commands::SetupCommand,
errors::CLIError,
files::{InputsFile, Manifest, ProofFile},
files::{Manifest, ProofFile},
};
use snarkos_algorithms::snark::{create_random_proof, PreparedVerifyingKey, Proof};
@ -34,7 +34,7 @@ impl CLI for ProveCommand {
#[cfg_attr(tarpaulin, skip)]
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
let (mut program, parameters, prepared_verifying_key) = SetupCommand::output(options)?;
let (program, parameters, prepared_verifying_key) = SetupCommand::output(options)?;
// Get the package name
let path = current_dir()?;
@ -42,10 +42,6 @@ impl CLI for ProveCommand {
log::info!("Proving...");
// Fetch main program inputs here
// let inputs_string = InputsFile::new(&package_name).read_from(&path)?;
// program.parse_inputs(&inputs_string)?;
// Start the timer
let start = Instant::now();

View File

@ -1,5 +1,6 @@
use crate::Span;
use leo_ast::common::Identifier as AstIdentifier;
use leo_inputs::common::Identifier as InputsAstIdentifier;
use serde::{Deserialize, Serialize};
use std::fmt;
@ -26,6 +27,15 @@ impl<'ast> From<AstIdentifier<'ast>> for Identifier {
}
}
impl<'ast> From<InputsAstIdentifier<'ast>> for Identifier {
fn from(identifier: InputsAstIdentifier<'ast>) -> Self {
Self {
name: identifier.value,
span: Span::from(identifier.span),
}
}
}
impl fmt::Display for Identifier {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)

View File

@ -17,6 +17,7 @@ use leo_ast::{
};
use leo_ast::values::AddressValue;
use leo_inputs::values::NumberValue;
use serde::{Deserialize, Serialize};
use std::fmt;
@ -103,7 +104,7 @@ impl Expression {
}
impl<'ast> Expression {
pub(crate) fn get_count(count: Value<'ast>) -> usize {
pub(crate) fn get_count_from_value(count: Value<'ast>) -> usize {
match count {
Value::Integer(integer) => integer
.number
@ -114,6 +115,10 @@ impl<'ast> Expression {
size => unimplemented!("Array size should be an integer {}", size),
}
}
pub(crate) fn get_count_from_number(number: NumberValue<'ast>) -> usize {
number.value.parse::<usize>().expect("Unable to read array size")
}
}
impl<'ast> fmt::Display for Expression {
@ -398,7 +403,7 @@ impl<'ast> From<ArrayInlineExpression<'ast>> for Expression {
impl<'ast> From<ArrayInitializerExpression<'ast>> for Expression {
fn from(array: ArrayInitializerExpression<'ast>) -> Self {
let count = Expression::get_count(array.count);
let count = Expression::get_count_from_value(array.count);
let expression = Box::new(SpreadOrExpression::from(*array.expression));
Expression::Array(vec![expression; count], Span::from(array.span))

View File

@ -1,26 +1,59 @@
use crate::FunctionInput;
use crate::{FunctionInput, Identifier, Span};
use leo_ast::functions::inputs::Input as AstInput;
use serde::{Deserialize, Serialize};
use std::fmt;
const RECORD_VARIABLE_NAME: &str = "record";
const REGISTERS_VARIABLE_NAME: &str = "registers";
const STATE_VARIABLE_NAME: &str = "state";
const STATE_LEAF_VARIABLE_NAME: &str = "state_leaf";
#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Input {
FunctionInput(FunctionInput),
Record,
Registers,
State,
StateLeaf,
Record(Identifier),
Registers(Identifier),
State(Identifier),
StateLeaf(Identifier),
}
impl<'ast> From<AstInput<'ast>> for Input {
fn from(input: AstInput<'ast>) -> Self {
match input {
AstInput::FunctionInput(function_input) => Input::FunctionInput(FunctionInput::from(function_input)),
AstInput::Record(_) => Input::Record,
AstInput::Registers(_) => Input::Registers,
AstInput::State(_) => Input::State,
AstInput::StateLeaf(_) => Input::StateLeaf,
AstInput::Record(record) => {
let id = Identifier {
name: RECORD_VARIABLE_NAME.to_string(),
span: Span::from(record.span),
};
Input::Record(id)
}
AstInput::Registers(registers) => {
let id = Identifier {
name: REGISTERS_VARIABLE_NAME.to_string(),
span: Span::from(registers.span),
};
Input::Registers(id)
}
AstInput::State(state) => {
let id = Identifier {
name: STATE_VARIABLE_NAME.to_string(),
span: Span::from(state.span),
};
Input::State(id)
}
AstInput::StateLeaf(state_leaf) => {
let id = Identifier {
name: STATE_LEAF_VARIABLE_NAME.to_string(),
span: Span::from(state_leaf.span),
};
Input::StateLeaf(id)
}
}
}
}
@ -29,10 +62,10 @@ impl Input {
fn format(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Input::FunctionInput(function_input) => write!(f, "{}", function_input),
Input::Record => write!(f, "record"),
Input::Registers => write!(f, "registers"),
Input::State => write!(f, "state"),
Input::StateLeaf => write!(f, "state_leaf"),
Input::Record(id) => write!(f, "{}", id),
Input::Registers(id) => write!(f, "{}", id),
Input::State(id) => write!(f, "{}", id),
Input::StateLeaf(id) => write!(f, "{}", id),
}
}
}

View File

@ -1,8 +1,9 @@
use crate::{Input, InputValue, MainInputs, ProgramInputs, ProgramState};
use crate::{InputValue, MainInputs, Parameter, ProgramInputs, ProgramState};
use leo_inputs::{
files::{File, TableOrSection},
InputParserError,
};
use std::collections::HashMap;
#[derive(Clone, PartialEq, Eq)]
pub struct Inputs {
@ -55,7 +56,27 @@ impl Inputs {
}
/// Returns the main function input value with the given `name`
pub fn get(&self, name: &String) -> Option<InputValue> {
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
self.inputs.get(name)
}
/// Returns the runtime register input values
pub fn get_registers(&self) -> HashMap<Parameter, Option<InputValue>> {
self.inputs.get_registers()
}
/// Returns the runtime record input values
pub fn get_record(&self) -> HashMap<Parameter, Option<InputValue>> {
self.state.get_record()
}
/// Returns the runtime state input values
pub fn get_state(&self) -> HashMap<Parameter, Option<InputValue>> {
self.state.get_state()
}
/// Returns the runtime state leaf input values
pub fn get_state_leaf(&self) -> HashMap<Parameter, Option<InputValue>> {
self.state.get_state_leaf()
}
}

View File

@ -6,7 +6,7 @@ macro_rules! input_section_impl {
#[derive(Clone, PartialEq, Eq)]
pub struct $name {
is_present: bool,
values: HashMap<String, Option<InputValue>>,
values: HashMap<Parameter, Option<InputValue>>,
}
impl $name {
@ -23,14 +23,14 @@ macro_rules! input_section_impl {
let is_present = self.is_present;
let mut values = self.values.clone();
values.iter_mut().for_each(|(_name, value)| {
values.iter_mut().for_each(|(_parameter, value)| {
*value = None;
});
Self { is_present, values }
}
/// Returns `true` if the `$name` variable is passed as input to the main function
/// Returns `true` if the main function contains the `$name` variable.
pub fn is_present(&self) -> bool {
self.is_present
}
@ -41,14 +41,19 @@ macro_rules! input_section_impl {
self.is_present = true;
for definition in definitions {
let name = definition.parameter.variable.value;
let value = InputValue::from_expression(definition.parameter.type_, definition.expression)?;
let value = InputValue::from_expression(definition.parameter.type_.clone(), definition.expression)?;
let parameter = Parameter::from(definition.parameter);
self.values.insert(name, Some(value));
self.values.insert(parameter, Some(value));
}
Ok(())
}
/// Returns this section's hashmap of values
pub fn values(&self) -> HashMap<Parameter, Option<InputValue>> {
self.values.clone()
}
}
)*)
}

View File

@ -8,6 +8,9 @@ pub use inputs::*;
pub mod input_value;
pub use input_value::*;
pub mod parameters;
pub use parameters::*;
pub mod program_inputs;
pub use program_inputs::*;

View File

@ -0,0 +1,2 @@
pub mod parameter;
pub use parameter::*;

View File

@ -0,0 +1,19 @@
use crate::{Identifier, Span, Type};
use leo_inputs::parameters::Parameter as AstParameter;
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Parameter {
pub variable: Identifier,
pub type_: Type,
pub span: Span,
}
impl<'ast> From<AstParameter<'ast>> for Parameter {
fn from(parameter: AstParameter<'ast>) -> Self {
Self {
variable: Identifier::from(parameter.variable),
type_: Type::from(parameter.type_),
span: Span::from(parameter.span),
}
}
}

View File

@ -1,4 +1,4 @@
use crate::{Input, InputValue};
use crate::InputValue;
use leo_inputs::{definitions::Definition, InputParserError};
use std::collections::HashMap;
@ -12,10 +12,6 @@ impl MainInputs {
Self { inputs: HashMap::new() }
}
pub fn len(&self) -> usize {
self.inputs.len()
}
/// Returns an empty version of this struct with `None` values.
/// Called during constraint synthesis to provide private inputs.
pub fn empty(&self) -> Self {
@ -28,6 +24,10 @@ impl MainInputs {
Self { inputs }
}
pub fn len(&self) -> usize {
self.inputs.len()
}
/// Parses main input definitions and stores them in `self`.
pub fn parse(&mut self, definitions: Vec<Definition>) -> Result<(), InputParserError> {
for definition in definitions {
@ -40,8 +40,8 @@ impl MainInputs {
Ok(())
}
/// Returns main function input at `index`
pub fn get(&self, name: &String) -> Option<InputValue> {
self.inputs.get(name).unwrap().clone()
/// Returns an `Option` of the main function input at `name`
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
self.inputs.get(name).map(|input| input.clone())
}
}

View File

@ -1,8 +1,9 @@
use crate::{Input, InputValue, MainInputs, Registers};
use crate::{InputValue, MainInputs, Parameter, Registers};
use leo_inputs::{
sections::{Header, Section},
InputParserError,
};
use std::collections::HashMap;
#[derive(Clone, PartialEq, Eq)]
pub struct ProgramInputs {
@ -50,7 +51,13 @@ impl ProgramInputs {
}
}
pub fn get(&self, name: &String) -> Option<InputValue> {
/// Returns the main function input value with the given `name`
pub fn get(&self, name: &String) -> Option<Option<InputValue>> {
self.main.get(name)
}
/// Returns the runtime register input values
pub fn get_registers(&self) -> HashMap<Parameter, Option<InputValue>> {
self.registers.values()
}
}

View File

@ -1,4 +1,4 @@
use crate::{Input, InputValue};
use crate::{InputValue, Parameter};
use leo_inputs::{definitions::Definition, InputParserError};
use std::collections::HashMap;

View File

@ -1,8 +1,9 @@
use crate::{Input, Record, StateLeaf};
use crate::{InputValue, Parameter, Record, StateLeaf};
use leo_inputs::{
sections::{Header, Section},
InputParserError,
};
use std::collections::HashMap;
#[derive(Clone, PartialEq, Eq)]
pub struct PrivateState {
@ -55,4 +56,14 @@ impl PrivateState {
Ok(())
}
/// Returns the runtime record input values
pub fn get_record(&self) -> HashMap<Parameter, Option<InputValue>> {
self.record.values()
}
/// Returns the runtime state leaf input values
pub fn get_state_leaf(&self) -> HashMap<Parameter, Option<InputValue>> {
self.state_leaf.values()
}
}

View File

@ -1,4 +1,4 @@
use crate::{Input, InputValue};
use crate::{InputValue, Parameter};
use leo_inputs::{definitions::Definition, InputParserError};
use std::collections::HashMap;

View File

@ -1,4 +1,4 @@
use crate::{Input, InputValue};
use crate::{InputValue, Parameter};
use leo_inputs::{definitions::Definition, InputParserError};
use std::collections::HashMap;

View File

@ -1,9 +1,11 @@
use crate::{Input, PrivateState, PublicState};
use crate::{InputValue, Parameter, PrivateState, PublicState};
use leo_inputs::{
tables::{Table, Visibility},
InputParserError,
};
use std::collections::HashMap;
#[derive(Clone, PartialEq, Eq)]
pub struct ProgramState {
public: PublicState,
@ -38,4 +40,19 @@ impl ProgramState {
Visibility::Public(_public) => self.public.parse(table.sections),
}
}
/// Returns the runtime record input values
pub fn get_record(&self) -> HashMap<Parameter, Option<InputValue>> {
self.private.get_record()
}
/// Returns the runtime state input values
pub fn get_state(&self) -> HashMap<Parameter, Option<InputValue>> {
self.public.get_state()
}
/// Returns the runtime state leaf input values
pub fn get_state_leaf(&self) -> HashMap<Parameter, Option<InputValue>> {
self.private.get_state_leaf()
}
}

View File

@ -1,9 +1,11 @@
use crate::{Input, State};
use crate::{InputValue, Parameter, State};
use leo_inputs::{
sections::{Header, Section},
InputParserError,
};
use std::collections::HashMap;
#[derive(Clone, PartialEq, Eq)]
pub struct PublicState {
state: State,
@ -14,10 +16,6 @@ impl PublicState {
Self { state: State::new() }
}
pub fn len(&self) -> usize {
if self.state.is_present() { 1usize } else { 0usize }
}
/// Returns an empty version of this struct with `None` values.
/// Called during constraint synthesis to provide private inputs.
pub fn empty(&self) -> Self {
@ -26,6 +24,11 @@ impl PublicState {
Self { state }
}
pub fn len(&self) -> usize {
if self.state.is_present() { 1usize } else { 0usize }
}
/// Parse all inputs included in a file and store them in `self`.
pub fn parse(&mut self, sections: Vec<Section>) -> Result<(), InputParserError> {
for section in sections {
match section.header {
@ -36,4 +39,9 @@ impl PublicState {
Ok(())
}
/// Returns the runtime state input values
pub fn get_state(&self) -> HashMap<Parameter, Option<InputValue>> {
self.state.values()
}
}

View File

@ -1,4 +1,4 @@
use crate::{Input, InputValue};
use crate::{InputValue, Parameter};
use leo_inputs::{definitions::Definition, InputParserError};
use std::collections::HashMap;

View File

@ -1,10 +1,11 @@
use leo_ast::types::IntegerType as AstIntegerType;
use leo_inputs::types::IntegerType as InputsAstIntegerType;
use serde::{Deserialize, Serialize};
use std::fmt;
/// Explicit integer type
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum IntegerType {
U8,
U16,
@ -37,6 +38,24 @@ impl From<AstIntegerType> for IntegerType {
}
}
impl From<InputsAstIntegerType> for IntegerType {
fn from(integer_type: InputsAstIntegerType) -> Self {
match integer_type {
InputsAstIntegerType::U8Type(_type) => IntegerType::U8,
InputsAstIntegerType::U16Type(_type) => IntegerType::U16,
InputsAstIntegerType::U32Type(_type) => IntegerType::U32,
InputsAstIntegerType::U64Type(_type) => IntegerType::U64,
InputsAstIntegerType::U128Type(_type) => IntegerType::U128,
InputsAstIntegerType::I8Type(_type) => IntegerType::I8,
InputsAstIntegerType::I16Type(_type) => IntegerType::I16,
InputsAstIntegerType::I32Type(_type) => IntegerType::I32,
InputsAstIntegerType::I64Type(_type) => IntegerType::I64,
InputsAstIntegerType::I128Type(_type) => IntegerType::I128,
}
}
}
impl fmt::Display for IntegerType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {

View File

@ -1,11 +1,12 @@
use crate::{Expression, Identifier, IntegerType};
use leo_ast::types::{ArrayType, CircuitType, DataType, Type as AstType};
use leo_inputs::types::{ArrayType as InputsArrayType, DataType as InputsDataType, Type as InputsAstType};
use serde::{Deserialize, Serialize};
use std::fmt;
/// Explicit type used for defining a variable or expression type
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Type {
// Data types
Address,
@ -50,13 +51,13 @@ impl From<DataType> for Type {
}
}
impl<'ast> From<ArrayType<'ast>> for Type {
fn from(array_type: ArrayType<'ast>) -> Self {
impl<'ast> From<InputsArrayType<'ast>> for Type {
fn from(array_type: InputsArrayType<'ast>) -> Self {
let element_type = Box::new(Type::from(array_type._type));
let dimensions = array_type
.dimensions
.into_iter()
.map(|row| Expression::get_count(row))
.map(|row| Expression::get_count_from_number(row))
.collect();
Type::Array(element_type, dimensions)
@ -70,16 +71,52 @@ impl<'ast> From<CircuitType<'ast>> for Type {
}
impl<'ast> From<AstType<'ast>> for Type {
fn from(_type: AstType<'ast>) -> Self {
match _type {
AstType::Basic(_type) => Type::from(_type),
AstType::Array(_type) => Type::from(_type),
AstType::Circuit(_type) => Type::from(_type),
fn from(type_: AstType<'ast>) -> Self {
match type_ {
AstType::Basic(type_) => Type::from(type_),
AstType::Array(type_) => Type::from(type_),
AstType::Circuit(type_) => Type::from(type_),
AstType::SelfType(_type) => Type::SelfType,
}
}
}
/// inputs pest ast -> Explicit Type
impl From<InputsDataType> for Type {
fn from(data_type: InputsDataType) -> Self {
match data_type {
InputsDataType::Address(_type) => Type::Address,
InputsDataType::Boolean(_type) => Type::Boolean,
InputsDataType::Field(_type) => Type::Field,
InputsDataType::Group(_type) => Type::Group,
InputsDataType::Integer(type_) => Type::IntegerType(IntegerType::from(type_)),
}
}
}
impl<'ast> From<ArrayType<'ast>> for Type {
fn from(array_type: ArrayType<'ast>) -> Self {
let element_type = Box::new(Type::from(array_type._type));
let dimensions = array_type
.dimensions
.into_iter()
.map(|row| Expression::get_count_from_value(row))
.collect();
Type::Array(element_type, dimensions)
}
}
impl<'ast> From<InputsAstType<'ast>> for Type {
fn from(type_: InputsAstType<'ast>) -> Self {
match type_ {
InputsAstType::Basic(type_) => Type::from(type_),
InputsAstType::Array(type_) => Type::from(type_),
}
}
}
impl Type {
pub fn outer_dimension(&self, dimensions: &Vec<usize>) -> Self {
let type_ = self.clone();